WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 03 of 30] tools: vnet: Remove

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 03 of 30] tools: vnet: Remove
From: Ian Campbell <ian.campbell@xxxxxxxxxx>
Date: Mon, 21 Mar 2011 14:44:26 +0000
Cc: Ian Campbell <ian.campbell@xxxxxxxxxx>
Delivery-date: Thu, 24 Mar 2011 16:54:27 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1300718663@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1300718506 0
# Node ID 28f04a6595064dca0062b972aa7ef69db8065c90
# Parent  223f61702bda3a85e2b62ef9fdfffacf371aa7d9
tools: vnet: Remove

Build has been broken since at least 18969:d6889b3b6423 (early 2009)
and it has been unhooked from the top level build since forever
AFAICT. The last actual development (as opposed to tree wide cleanups
and build fixes) appears to have been 11594:6d7bba6443ef in 2006. The
functionality of vnet has apparently been superceded by VLANs,
ebtables, Ethernet-over-IP etc all of which are well integrated with
upstream kernels and distros.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

diff -r 223f61702bda -r 28f04a659506 tools/python/xen/xend/XendVnet.py
--- a/tools/python/xen/xend/XendVnet.py Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-#============================================================================
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of version 2.1 of the GNU Lesser General Public
-# License as published by the Free Software Foundation.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#============================================================================
-# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
-# Copyright (C) 2005 XenSource Ltd
-#============================================================================
-
-"""Handler for vnet operations.
-"""
-
-from xen.util import Brctl
-from xen.xend import sxp
-from xen.xend.XendError import XendError
-from xen.xend.XendLogging import log
-from xen.xend.xenstore.xstransact import xstransact
-
-
-def vnet_cmd(cmd):
-    out = None
-    try:
-        try:
-            out = file("/proc/vnet/policy", "wb")
-            sxp.show(cmd, out)
-        except IOError, ex:
-            raise XendError(str(ex))
-    finally:
-        if out: out.close()
-
-class XendVnetInfo:
-    
-    vifctl_ops = {'up': 'vif.add', 'down': 'vif.del'}
-
-    def __init__(self, dbpath, config=None):
-        if config:
-            self.id = str(sxp.child_value(config, 'id'))
-            self.dbid = self.id.replace(':', '-')
-            self.dbpath = dbpath + '/' + self.dbid
-            self.config = config
-        else:
-            self.dbpath = dbpath
-            self.importFromDB()
-            
-        self.bridge = sxp.child_value(self.config, 'bridge')
-        if not self.bridge:
-            self.bridge = "vnet%s" % self.id
-        self.vnetif = sxp.child_value(self.config, 'vnetif')
-        if not self.vnetif:
-            self.vnetif = "vnif%s" % self.id
-
-
-    def exportToDB(self, save=False, sync=False):
-        to_store = {
-            'id' : self.id,
-            'dbid' : self.dbid,
-            'config' : sxp.to_string(self.config)
-            }
-        xstransact.Write(self.dbpath, to_store)
-
-
-    def importFromDB(self):
-        (self.id, self.dbid, c) = xstransact.Gather(self.dbpath,
-                                                    ('id', str),
-                                                    ('dbid', str),
-                                                    ('config', str))
-        self.config = sxp.from_string(c)
-
-
-    def sxpr(self):
-        return self.config
-
-    def configure(self):
-        log.info("Configuring vnet %s", self.id)
-        val = vnet_cmd(['vnet.add'] + sxp.children(self.config))
-        Brctl.bridge_create(self.bridge)
-        Brctl.vif_bridge_add({'bridge': self.bridge, 'vif': self.vnetif})
-        return val
-        
-    def delete(self):
-        log.info("Deleting vnet %s", self.id)
-        Brctl.vif_bridge_rem({'bridge': self.bridge, 'vif': self.vnetif})
-        Brctl.bridge_del(self.bridge)
-        val = vnet_cmd(['vnet.del', self.id])
-        xstransact.Remove(self.dbpath)
-        return val
-
-    def vifctl(self, op, vif, vmac):
-        try:
-            fn = self.vifctl_ops[op]
-            return vnet_cmd([fn, ['vnet', self.id], ['vif', vif], ['vmac', 
vmac]])
-        except XendError:
-            log.warning("vifctl failed: op=%s vif=%s mac=%s", op, vif, vmac)
-
-class XendVnet:
-    """Index of all vnets. Singleton.
-    """
-
-    dbpath = "/vnet"
-
-    def __init__(self):
-        # Table of vnet info indexed by vnet id.
-        self.vnet = {}
-        listing = xstransact.List(self.dbpath)
-        for entry in listing:
-            try:
-                info = XendVnetInfo(self.dbpath + '/' + entry)
-                self.vnet[info.id] = info
-                info.configure()
-            except XendError, ex:
-                log.warning("Failed to configure vnet %s: %s", str(info.id), 
str(ex))
-            except Exception, ex:
-                log.exception("Vnet error")
-                xstransact.Remove(self.dbpath + '/' + entry)
-
-    def vnet_of_bridge(self, bridge):
-        """Get the vnet for a bridge (if any).
-
-        @param bridge: bridge name
-        @return vnet or None
-        """
-        for v in self.vnet.values():
-            if v.bridge == bridge:
-                return v
-        else:
-            return None
-
-    def vnet_ls(self):
-        """List all vnet ids.
-        """
-        return self.vnet.keys()
-
-    def vnets(self):
-        """List all vnets.
-        """
-        return self.vnet.values()
-
-    def vnet_get(self, id):
-        """Get a vnet.
-
-        @param id vnet id
-        """
-        id = str(id)
-        return self.vnet.get(id)
-
-    def vnet_create(self, config):
-        """Create a vnet.
-
-        @param config: config
-        """
-        info = XendVnetInfo(self.dbpath, config=config)
-        self.vnet[info.id] = info
-        info.exportToDB()
-        info.configure()
-
-    def vnet_delete(self, id):
-        """Delete a vnet.
-
-        @param id: vnet id
-        """
-        info = self.vnet_get(id)
-        if info:
-            del self.vnet[id]
-            info.delete()
-
-def instance():
-    global inst
-    try:
-        inst
-    except:
-        inst = XendVnet()
-    return inst
diff -r 223f61702bda -r 28f04a659506 tools/python/xen/xend/server/SrvRoot.py
--- a/tools/python/xen/xend/server/SrvRoot.py   Mon Mar 21 14:41:45 2011 +0000
+++ b/tools/python/xen/xend/server/SrvRoot.py   Mon Mar 21 14:41:46 2011 +0000
@@ -29,7 +29,6 @@ class SrvRoot(SrvDir):
     subdirs = [
         ('node',    'SrvNode'       ),
         ('domain',  'SrvDomainDir'  ),
-        ('vnet',    'SrvVnetDir'    ),
         ]
 
     def __init__(self):
diff -r 223f61702bda -r 28f04a659506 tools/python/xen/xend/server/SrvVnetDir.py
--- a/tools/python/xen/xend/server/SrvVnetDir.py        Mon Mar 21 14:41:45 
2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-#============================================================================
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of version 2.1 of the GNU Lesser General Public
-# License as published by the Free Software Foundation.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#============================================================================
-# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
-#============================================================================
-
-from xen.xend import sxp
-from xen.xend.Args import FormFn
-from xen.xend import PrettyPrint
-from xen.xend import XendVnet
-from xen.xend.XendError import XendError
-
-from xen.web.SrvDir import SrvDir
-
-class SrvVnet(SrvDir):
-
-    def __init__(self, vnetinfo):
-        SrvDir.__init__(self)
-        self.vnetinfo = vnetinfo
-        self.xvnet = XendVnet.instance()
-
-    def op_delete(self, op, req):
-        val = self.xvnet.vnet_delete(self.vnetinfo.id)
-        return val
-
-    def render_POST(self, req):
-        return self.perform(req)
-        
-    def render_GET(self, req):
-        if self.use_sxp(req):
-            req.setHeader("Content-Type", sxp.mime_type)
-            sxp.show(self.vnetinfo.sxpr(), out=req)
-        else:
-            req.write('<html><head></head><body>')
-            self.print_path(req)
-            req.write('<p>Vnet %s</p>' % self.vnetinfo.id)
-            req.write("<code><pre>")
-            PrettyPrint.prettyprint(self.vnetinfo.sxpr(), out=req)
-            req.write("</pre></code>")
-            self.form(req)
-            req.write('</body></html>')
-        return ''
-
-    def form(self, req):
-        url = req.prePathURL()
-        req.write('<form method="post" action="%s">' % url)
-        req.write('<input type="submit" name="op" value="delete">')
-        req.write('</form>')
-        
-class SrvVnetDir(SrvDir):
-    """Vnet directory.
-    """
-
-    def __init__(self):
-        SrvDir.__init__(self)
-        self.xvnet = XendVnet.instance()
-
-    def vnet(self, x):
-        val = None
-        vnetinfo = self.xvnet.vnet_get(x)
-        if not vnetinfo:
-            raise XendError('No such vnet ' + str(x))
-        val = SrvVnet(vnetinfo)
-        return val
-
-    def get(self, x):
-        v = SrvDir.get(self, x)
-        if v is not None:
-            return v
-        v = self.vnet(x)
-        return v
-
-    def op_create(self, op, req):
-        fn = FormFn(self.xvnet.vnet_create,
-                    [['config', 'sxpr']])
-        val = fn(req.args, {})
-        return val
-        
-    def render_POST(self, req):
-        return self.perform(req)
-
-    def render_GET(self, req):
-        if self.use_sxp(req):
-            req.setHeader("Content-Type", sxp.mime_type)
-            self.ls_vnet(req, 1)
-        else:
-            req.write("<html><head></head><body>")
-            self.print_path(req)
-            self.ls(req)
-            self.ls_vnet(req)
-            self.form(req)
-            req.write("</body></html>")
-
-    def ls_vnet(self, req, use_sxp=0):
-        url = req.prePathURL()
-        if not url.endswith('/'):
-            url += '/'
-        if use_sxp:
-            vnets = self.xvnet.vnet_ls()
-            sxp.show(vnets, out=req)
-        else:
-            vnets = self.xvnet.vnets()
-            vnets.sort(lambda x, y: cmp(x.id, y.id))
-            req.write('<ul>')
-            for v in vnets:
-               req.write('<li><a href="%s%s"> Vnet %s</a>' % (url, v.id, v.id))
-               req.write('</li>')
-            req.write('</ul>')
-
-    def form(self, req):
-        """Generate the form(s) for vnet dir operations.
-        """
-        req.write('<form method="post" action="%s" 
enctype="multipart/form-data">'
-                  % req.prePathURL())
-        req.write('<button type="submit" name="op" value="create">Create 
Vnet</button>')
-        req.write('Config <input type="file" name="config"><br>')
-        req.write('</form>')
diff -r 223f61702bda -r 28f04a659506 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Mon Mar 21 14:41:45 2011 +0000
+++ b/tools/python/xen/xm/main.py       Mon Mar 21 14:41:46 2011 +0000
@@ -201,9 +201,6 @@ SUBCOMMAND_HELP = {
                          'Destroy a domain\'s version 2 virtual network 
device.'),
     'network2-list'  : ('<Domain> [--long]',
                         'List version 2 virtual network interfaces for a 
domain.'),
-    'vnet-create'   :  ('<ConfigFile>','Create a vnet from ConfigFile.'),
-    'vnet-delete'   :  ('<VnetId>', 'Delete a Vnet.'),
-    'vnet-list'     :  ('[-l|--long]', 'List Vnets.'),
     'vtpm-list'     :  ('<Domain> [--long]', 'List virtual TPM devices.'),
     'pci-attach'    :  ('[-o|--options=<opt>] <Domain> <domain:bus:slot.func> 
[virtual slot]',
                         'Insert a new pass-through pci device.'),
@@ -319,9 +316,6 @@ SUBCOMMAND_OPTIONS = {
     ),
     'dmesg': (
        ('-c', '--clear', 'Clear dmesg buffer as well as printing it'),
-    ),
-    'vnet-list': (
-       ('-l', '--long', 'List Vnets as SXP'),
     ),
     'network-list': (
        ('-l', '--long', 'List resources as SXP'),
@@ -485,12 +479,6 @@ device_commands = [
     "usb-hc-destroy",
     ]
 
-vnet_commands = [
-    "vnet-list",
-    "vnet-create",
-    "vnet-delete",
-    ]
-
 security_commands = [
     "setpolicy",
     ]
@@ -534,7 +522,7 @@ cpupool_commands = [
     ]
 
 all_commands = (domain_commands + host_commands + scheduler_commands +
-                device_commands + vnet_commands + security_commands +
+                device_commands + security_commands +
                 acm_commands + flask_commands + tmem_commands + 
cpupool_commands +
                 ['shell', 'event-monitor'])
 
@@ -3270,51 +3258,6 @@ def xm_usb_hc_destroy(args):
     dom = args[0]
     dev = args[1]
     server.xend.domain.destroyDevice(dom, 'vusb', dev)
-
-def xm_vnet_list(args):
-    xenapi_unsupported()
-    try:
-        (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
-    except getopt.GetoptError, opterr:
-        err(opterr)
-        usage('vnet-list')
-    
-    use_long = 0
-    for (k, v) in options:
-        if k in ['-l', '--long']:
-            use_long = 1
-            
-    if params:
-        use_long = 1
-        vnets = params
-    else:
-        vnets = server.xend_vnets()
-    
-    for vnet in vnets:
-        try:
-            if use_long:
-                info = server.xend_vnet(vnet)
-                PrettyPrint.prettyprint(info)
-            else:
-                print vnet
-        except Exception, ex:
-            print vnet, ex
-
-def xm_vnet_create(args):
-    xenapi_unsupported()
-    arg_check(args, "vnet-create", 1)
-    conf = args[0]
-    if not os.access(conf, os.R_OK):
-        print "File not found: %s" % conf
-        sys.exit(1)
-
-    server.xend_vnet_create(conf)
-
-def xm_vnet_delete(args):
-    xenapi_unsupported()
-    arg_check(args, "vnet-delete", 1)
-    vnet = args[0]
-    server.xend_vnet_delete(vnet)
 
 def xm_network_new(args):
     xenapi_only()
@@ -3850,10 +3793,6 @@ commands = {
     "network-new": xm_network_new,
     "network-del": xm_network_del,
     "network-show": xm_network_show,
-    # vnet
-    "vnet-list": xm_vnet_list,
-    "vnet-create": xm_vnet_create,
-    "vnet-delete": xm_vnet_delete,
     # vtpm
     "vtpm-list": xm_vtpm_list,
     #pci
diff -r 223f61702bda -r 28f04a659506 tools/vnet/00INSTALL
--- a/tools/vnet/00INSTALL      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-This directory contains the implementation of vnets:
-virtual private networks for virtual machines.
-
-make
-        - compile in local dirs. The module is in vnet-module/vnet_module.ko.
-
-make dist
-        - compile and install into $(XEN_ROOT)/dist/install,
-        - where XEN_ROOT is the root of the xen tree.
-
-make install
-        - compile and install into system.
-
-By default the makefiles expect this code to have been installed
-in tools/vnet in a xen source tree. If compiling outside the xen
-source tree, set XEN_ROOT to the location of the xen source.
-You can do this in the environment or in a Make.local file
-in the current directory (see Make.env for details).
-
-The xen0 kernel must have been compiled before building the vnet module.
-The vnet module installs to
- /lib/modules/<kernel version>-xen0/kernel/xen/vnet_module.ko
-
-The vnet module should be loaded before starting xend, or
-xend will fail to create any persistent vnets it has in its configuration.
-The script network-vnet is a modified version of the xen network script
-that loads the module if it's not already loaded.
-
-The module uses kernel crypto functions, and these need to be
-enabled in the xen0 kernel config. They should be on by default -
-if they're not you will get compile or insmod errors (see below).
-
-Kernel config options:
-
-1)     You will need to have your xen0 kernel compiled with HMAC_SUPPORT 
-       2.6.x = (MAIN MENU: Cryptographic Options -> HMAC Support)
-       BEFORE running "make install".
-
-2)     You will want at least some of the other algorithms listed under
-       "Cryptographic Options" for the kernel compiled as modules.
-
-3)     You will want the networking IPsec/VLAN options compiled in as modules
-       2.6.x = (MAIN MENU: Device Drivers -> Networking Support -> 
-                               Networking Options ->
-                                       IP: AH transformation
-                                       IP: ESP transformation
-                                       IP: IPComp transformation 
-                                       IP: tunnel transformation
-
-                                       IPsec user configuration interface
-       
-                                       802.1Q VLAN Support
-
-Please refer to the additional documentation found in tools/vnet/doc for
-proper syntax and config file parameters.
diff -r 223f61702bda -r 28f04a659506 tools/vnet/00README
--- a/tools/vnet/00README       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-This directory contains the implementation of vnets:
-virtual private networks for virtual machines.
-
-See 00INSTALL for build instructions, doc/ for more information
-and examples/ for example configurations.
-
-The vnet implementation can be run using a kernel module
-or a user-space daemon. The kernel module is in vnet-module/ and the
-user-space daemon (varpd) is in vnetd/. The user-space daemon
-needs the tun/tap kernel module. Vnets use multicast to find
-virtual interfaces and support broadcast. Either implementation can
-tunnel multicast packets to other implementations if wide-area
-multicast routing is not available.
-
-Mike Wray <mike.wray@xxxxxx>
\ No newline at end of file
diff -r 223f61702bda -r 28f04a659506 tools/vnet/Make.env
--- a/tools/vnet/Make.env       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-# -*- mode: Makefile; -*-
-
-# Include any local overrides.
--include $(VNET_ROOT)/Make.local
-
-# If building vnets outside the xen source tree, set XEN_ROOT to the
-# absolute path of the root of the xen source tree. Edit this file
-# or set XEN_ROOT in Make.local, the make command line or
-# the environment. For example put this in Make.local:
-# export XEN_ROOT = $(shell cd ~/xen-unstable.hg && pwd)
-
-export XEN_ROOT ?= $(shell cd $(VNET_ROOT)/../.. && pwd)
-
-export LINUX_SERIES   ?= 2.6
-
-DISTDIR               ?= $(XEN_ROOT)/dist
-export DESTDIR        ?= $(DISTDIR)/install
-
-export VNET_MODULE_DIR = $(VNET_ROOT)/vnet-module
-export VNETD_DIR       = $(VNET_ROOT)/vnetd
-export LIBXUTIL_DIR    = $(VNET_ROOT)/libxutil
-
-
-export GC_DIR          = $(VNET_ROOT)/build/gc
-export GC_INCLUDE      = $(GC_DIR)/include
-export GC_LIB_DIR      = $(GC_DIR)/lib
-export GC_LIB_A        = $(GC_LIB_DIR)/libgc.a
-export GC_LIB_SO       = $(GC_LIB_DIR)/libgc.so
diff -r 223f61702bda -r 28f04a659506 tools/vnet/Makefile
--- a/tools/vnet/Makefile       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-# -*- mode: Makefile; -*-
-
-ifndef VNET_ROOT
-export VNET_ROOT = $(shell pwd)
-include $(VNET_ROOT)/Make.env
-endif
-
-SUBDIRS:=
-SUBDIRS+= examples
-SUBDIRS+= scripts
-SUBDIRS+= gc
-SUBDIRS+= libxutil
-SUBDIRS+= vnetd
-SUBDIRS+= vnet-module
-
-.PHONY: all
-all: compile
-
-gc.tar.gz:
-       #wget http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/$@
-       wget $(XEN_EXTFILES_URL)/$@
-
-.PHONY: gc
-gc: gc.tar.gz
-       tar xfz gc.tar.gz
-       ln -sf gc?.? gc
-
-$(GC_LIB_A): gc
-       (cd gc && ./configure --prefix=$(GC_DIR) )
-       make -C gc
-       DESTDIR="" make -C gc install
-
-.PHONY: gc-all
-gc-all: $(GC_LIB_A)
-
-.PHONY: gc-install
-gc-install:
-
-.PHONY: gc-clean
-gc-clean:
-       -@$(RM) -r gc?.? gc
-
-submak = $(MAKE) -C $(patsubst %-$(1),%,$(@)) $(1)
-subtgt = $(patsubst %,%-$(1),$(SUBDIRS))
-
-%-all:
-       $(call submak,all)
-
-%-clean:
-       -$(call submak,clean)
-
-%-install:
-       $(call submak,install)
-
-.PHONY: compile
-compile: $(call subtgt,all)
-
-.PHONY: install
-install: DESTDIR=
-install: dist
-
-.PHONY: dist
-dist: compile $(call subtgt,install)
-
-.PHONY: clean
-clean: $(call subtgt,clean)
-       -@$(RM) -r build
-
-.PHONY: pristine
-pristine: clean
-       -@$(RM) gc.tar.gz
-
-.PHONY: help
-help:
-       @echo 'Cleaning targets:'
-       @echo '  clean     - clean subdirs and remove the build dir'
-       @echo '  pristine  - clean, then remove the gc tarball'
-       @echo ''
-       @echo 'Installation targets:'
-       @echo '  install   - build and install relative to /'
-       @echo '  dist      - build and install relative to DESTDIR (default 
XEN_ROOT/dist/install)'
-       @echo ''
-       @echo 'Compilation targets:'
-       @echo '  all       - same as compile'
-       @echo '  compile   - build everything'
-       @echo ''
-       @echo 'To build everything locally use "make" or "make all"'.
-       @echo 'To build and install into XEN_ROOT/dist/install use "make dist".'
-       @echo 'To build and install into the system use "make dist".'
-       @echo 'See ./00README and ./00INSTALL for more information.'
diff -r 223f61702bda -r 28f04a659506 tools/vnet/doc/Makefile
--- a/tools/vnet/doc/Makefile   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-#!/usr/bin/make -f
-# -*- mode: Makefile; -*-
-XEN_ROOT        = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-VERSION = 1.0
-HEADER  = Vnet
-
-PS2PDF         := ps2pdf
-DVIPS          := dvips
-LATEX          := latex
-LATEX2HTML     := latex2html
-DOXYGEN                := doxygen
-POD2MAN                := pod2man
-
-DOC_MAN5SRC    := $(wildcard man/*.pod.5)
-DOC_MAN1SRC    := $(wildcard man/*.pod.1)
-DOC_MAN1       := $(patsubst man/%.pod.1,man1/%.1,$(DOC_MAN1SRC))
-DOC_MAN5       := $(patsubst man/%.pod.5,man5/%.5,$(DOC_MAN5SRC))
-
-.PHONY: all man clean install
-
-.PHONY: all
-all: man
-
-.PHONY: man
-man:
-       @if which $(POD2MAN) 1>/dev/null 2>/dev/null; then \
-       $(MAKE) $(DOC_MAN1) $(DOC_MAN5); fi
-
-man1/%.1: man/%.pod.1 Makefile
-       $(INSTALL_DIR) $(@D)
-       $(POD2MAN) --release=$(VERSION) --name=`echo $@ | sed 's/^man1.//'| \
-               sed 's/.1//'` -s 1 -c $(HEADER) $< $@
-
-man5/%.5: man/%.pod.5 Makefile
-       $(INSTALL_DIR) $(@D)
-       $(POD2MAN) --release=$(VERSION) --name=`echo $@ | sed 's/^man5.//'| \
-               sed 's/.5//'` -s 5 -c $(HEADER) $< $@
-
-.PHONY: clean
-clean:
-       @$(RM) -rf man5
-       @$(RM) -rf man1
-
-.PHONY:  install
- install: all
-       $(INSTALL_DIR) $(DESTDIR)$(MANDIR)
-       $(CP) -dR man1 $(DESTDIR)$(MANDIR)
-       $(CP) -dR man5 $(DESTDIR)$(MANDIR)
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/doc/man/vn.pod.1
--- a/tools/vnet/doc/man/vn.pod.1       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-=head1 NAME
-
-vn - Vnet (virtual networking) management utility.
-
-=head1 SYNOPSIS
-
-vn <command> [args]
-
-=head1 DESCRIPTION
-
-The B<vn> utility manages vnets, virtual networks for virtual machines.
-Before using vnets, the vnet kernel module must be installed or
-the user-space daemon vnetd must be running. Using the kernel module is 
recommended,
-see the B<insmod> command below.
-
-A vnet is a virtual network that behaves like a private LAN, transporting
-Ethernet frames. Each vnet is identified by a 128-bit vnet id and
-has a network device that interfaces to it. Ethernet packets written
-to the device are encapsulated and sent to the network.
-Received vnet packets are decapsulated and delivered from the device
-corresponding to their vnet id. The default encapsulation uses UDP on port 
1798.
-
-Usually each vnet device is enslaved to a corresponding bridge, and virtual
-machine interfaces are attached to vnets by enslaving them to the bridge.
-Each vnet behaves like a private LAN: traffic on one vnet is not visible
-on other vnets, and interfaces on a vnet cannot see traffic on the
-physical network. 
-
-Vnets can be connected together into larger networks
-by direct bridging or packet forwarding, or by using multihomed vms
-with interfaces on several vnets, or vnets and the physical network.
-As vnet interfaces are discovered dynamically, vnet connectivity is maintained
-if a vm using a vnet is migrated from one physical machine to another.
-
-In the commands vnet ids can be given in two forms. Long form, as 8 4-digit 
hex fields
-separated by colons, for example 0000:0000:0000:0000:0000:0000:0000:0004, and
-short form as a hex field, for example 0004 or 4. The short form is the same 
as the
-long form with the first 7 fields zero. Vnet id 
0000:0000:0000:0000:0000:0000:0000:0001
-is reserved for the physical network and has no vnet device.
-
-Vnets use multicast to discover the location of virtual interfaces, by default
-using multicast group 224.10.0.1. If all the machines hosting vnets are on
-the same subnet, or reachable by multicast, vnets will span all the machines
-automatically. If some machines are not reachable by multicast you can 
configure
-vnets to perform multicast forwarding using UDP. 
-
-The vnet devices are fully-functional network devices, so you can add IP 
addresses
-to them and test connectivity without any vms running.
-For example, using vnif0004 on machines A and B:
-
-        A> ifconfig vnif0004 192.0.2.11
-        B> ifconfig vnif0004 192.0.2.12
-        B> ping 192.0.2.11
-
-If the vnet device is enslaved to a bridge you will have to add the IP address
-to the bridge instead. Use C<brctl show> or C<vn vnets> to see if a vnet
-device is on a bridge.
-
-=over 4
-
-=item B<insmod> I<[varp_mcaddr=ADDR]>
-
-Insert the vnet kernel module, optionally supplying the multicast
-address to use, default 224.10.0.1.
-
-=item B<varp>
-
-Print varp infrormation and varp cache.
-
-=item B<vnets> [options]
-
-Print the list of vnets (virtual networks). If a vnet device is on a bridge,
-also shows the bridge and its bridged interfaces.
-
-=over 4
-
-=item B<-a | --all>
-
-Also print the vifs on each vnet and varp information.
-
-=item B<-l | --long>
-
-Also print the ifconfig for the vnet devices.
-
-=back
-
-=item B<vnet-create> I<[options]> I<vnetid>
-
-Create a vnet with the given id. The options are:
-
-=over 4
-
-=item B<-s | --security> I<level>
-
-Security level, which can be one of I<none> for no security,
-I<auth> for message authentication, and I<conf> for message
-authentication and confidentiality. The default is no security.
-Security is provided using IPSEC, but uses hard-wired keys.
-
-=item B<-b | --bridge> I<bridgename>
-
-Create a bridge for the vnet called I<bridgename> and enslave
-the vnet device to it.
-
-=item B<-v | --vnetif> I<vnetifname>
-
-Use I<vnetifname> as the name for the vnet device. If this option
-is not specified the default is to name the device vnifN where N
-is the last field of the vnet id as 4 hex characters.
-For example vnif0004. Network device names can be at
-most 14 characters.
-
-=back
-
-=item B<vnet-delete> I<[options]> I<vnetid>
-
-Delete the vnet with the given id. The vnet device goes away too.
-
-=over 4
-
-=item B<-b | --bridge>
-
-If this option is specified, delete the bridge associated with the vnet.
-
-=back
-
-=item B<vifs>
-
-Print the list of vifs (virtual interfaces).
-
-=item B<vif-add> I<[-i|-interface]> I<vnet> I<vmac>
-
-Add a vif to a vnet. Here I<vnet> is the vnet id and I<vmac>
-is the vif's MAC address. Alternatively, I<vmac> can be the name of
-a network device if the I<-i> or -I<--interface> flag is given.
-
-It is not usually necessary to use B<vif-add> as vnets automatically
-add vifs for the MAC addresses they see.
-
-=item B<vif-delete> I<[-i|-interface]> I<vnet> I<vmac>
-
-Delete a vif from a vnet. Here I<vnet> is the vnet id and I<vmac>
-is the vif's MAC address. Alternatively, I<vmac> can be the name of
-a network device if the I<-i> of -I<--interface> flag is given.
-
-It is not usually necessary to use B<vif-delete> as vnets periodically
-delete unused vifs.
-
-=item B<peers>
-
-Print the list of peer vnet machines to forward multicasts to, and accept
-forwarded multicasts from.
-
-=item B<peer-add> I<addr>
-
-Add the peer with the given IP address or hostname.
-
-=item B<peer-delete> I<addr>
-
-Delete the peer with the given IP address or hostname.
-
-=back
-
-=head1 AUTHOR
-
-The author of vn and vnets is Mike Wray of HP Labs. Please send problems, bugs,
-enhancements requests etc. to mike.wray@xxxxxxx
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) 2006 Mike Wray <mike.wray@xxxxxx>.
-
-This library is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
diff -r 223f61702bda -r 28f04a659506 tools/vnet/doc/vnet-module.txt
--- a/tools/vnet/doc/vnet-module.txt    Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-Vnet Low-level Command Interface
-Mike Wray <mike.wray@xxxxxx>
-2006/10/12
-
-The vnet kernel module and user-space daemon vnetd support a low-level
-command interface to control vnets. The kernel module creates 
/proc/vnet/policy,
-which is used by writing commands into it. Vnetd listens on the unix-domain
-socket /tmp/vnetd.
-
-The vn utility in ../scripts provides a higher-level interface to
-the vnet commands (using the kernel module or vnetd).
-
-The commands are:
-
-(vnet.add (id <id>) [(vnetif <ifname>)] [(security { none | auth | conf } )] )
-
-Create the vnet with id <id> and the given security level (default none).
-Vnet ids are 128-bit and can be specified as 8 fields of 1 to 4 hex digits
-separated by colons. A vnet id with no colons is treated as one with the first
-7 fields zero. Examples:
-
-1500 - equivalent to 0:0:0:0:0:0:0:1500
-aaff:0:0:0:0:0:77:88
-
-Security levels:
-- none: no security
-- auth: message authentication (IPSEC hmac)
-- conf: message confidentiality (IPSEC hmac and encryption)
-
-The <ifname> is the name of the network device created for the vnet.
-If not given it defaults to vnif<N>, where <N> is the hex for the
-8-th field in the id. Note that network device names can have a
-maximum of 14 characters.
-
-(vnet.del (id <id>))
-
-Delete the vnet with id <id>.
-
-(vif.add (vnet <vnetid>) (vmac <macaddr>))
-
-Add the vif with MAC address <macaddr> to the vnet with id <vnetid>.
-This makes the vnet module respond to VARP requests for <macaddr>
-on vnet <vnetid>. The vnet implementation learns MAC addresses
-so doing this should not be necessary.
-
-(vif.del (vnet <vnetid>) (vmac <macaddr>))
-
-Remove the vif with MAC address <macaddr> from the vnet with id <vnetid>.
-The vnet module will stop responding to VARP for the vif.
-
-(peer.add (addr <addr>))
-
-Add a peer at IP address <addr> to forward multicasts to,
-and accept forwarded multicasts from.
-
-(peer.del (addr <addr>))
-
-Delete a peer.
-
-(vif.list)  - get list of vifs.
-(vnet.list) - get list of vnets.
-(varp.list) - get vnet/varp info.
-(peer.list) - get list of peers.
-
-The kernel module produces output on the console, and vnetd
-returns output on the unix socket. The kernel module also provides
-the following files which can be read to get information:
-
-/proc/vnet/vifs  - get list of vifs.
-/proc/vnet/vnets - get list of vnets.
-/proc/vnet/varp  - get vnet/varp info.
-/proc/vnet/peers - get list of peers.
diff -r 223f61702bda -r 28f04a659506 tools/vnet/doc/vnet-xend.txt
--- a/tools/vnet/doc/vnet-xend.txt      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-
-Vnets: Virtual Networks for Virtual Machines
-
-Mike Wray <mike.wray@xxxxxx>
-
-2005/12/13
-
-0) Introduction
----------------
-
-Vnets provide virtual private LANs for virtual machines.
-This is done using bridging and multipoint tunneling. A virtual interface
-on a vnet can only see other interfaces on the same vnet - it cannot
-see the real network, and the real network cannot see it either.
-
-Virtual interfaces on the same vnet can be on the same machine
-or on different machines, they can still talk. The hosting machines
-can even be on different subnets if you configure vnet forwarding,
-or have multicast routing enabled.
-
-
-1) Installing vnet support
---------------------------
-
-Assuming the code has been installed (make install in the parent directory),
-configure xend to use 'network-vnet' instead of the default 'network' to
-start up networking. This just loads the vnet module when networking starts.
-
-In /etc/xend/xend-config.sxp:
-
-Configure the network script:
-
-(network-script        network-vnet)
-
-Restart xend.
-
-Alternatively insert the vnet module using 'vn insmod',
-preferably before xend starts.
-
-2) Creating vnets
------------------
-
-Xend already implements commands to add/remove vnets and
-bridge to them. To add a vnet use
-
-xm vnet-create <vnet config file>
-
-For example, if vnet97.sxp contains:
-
-(vnet (id 97) (bridge vnet97) (vnetif vnif97) (security none))
-
-do
-
-xm vnet-create vnet97.sxp
-
-This will define a vnet with id 97 and no security. The bridge for the
-vnet is called vnet97 and the virtual interface for it is vnif97.
-To add an interface on a vm to this vnet simply set its bridge to vnet97
-in its configuration.
-
-In Python:
-
-vif="bridge=vnet97"
-
-In sxp:
-
-(dev (vif (mac aa:00:00:01:02:03) (bridge vnet97)))
-
-By default vnets use udp encapsulation, but if you use etherip encapsulation
-you will also have to reduce the MTU of the corresponding
-device in the domain (because of the tunneling). Reducing the MTU may improve
-performance for udp encapsulation, but is not necessary.
-
-For example, for eth0 (in the domain, not dom0) use
-
-ifconfig eth0 mtu 1400
-
-or, better, put
-
-MTU=1400
-
-in /etc/sysconfig/network-scripts/ifcfg-eth0. You may also have to change or 
remove
-cached config files for eth0 under /etc/sysconfig/networking.
-
-Once configured, vnets are persistent in the xend database.
-To remove a vnet use
-
-xm vnet-delete <vnet id>
-
-To list vnets use
-
-xm vnet-list
-
-To get information on one or more vnet ids use
-
-xm vnet-list <vnet id>...
-
-You can also manage vnets using the vn utility which talks
-directly to the vnet implementation. The source is in ../scripts/vn
-and is installed in /usr/sbin/vn.
-
-3) Troubleshooting
-------------------
-
-The vnet module should appear in 'lsmod'.
-If a vnet has been configured it should appear in the output of 'xm vnet-list'.
-Its bridge and interface should appear in 'ifconfig'.
-It should also show in 'brctl show', with its attached interfaces.
-
-You can 'see into' a vnet from dom0 if you put an IP address on the bridge.
-For example, if you have vnet97 and a vm with ip addr 192.0.2.12 connected to 
it,
-then
-
-ifconfig vnet97 192.0.2.20 up
-
-should let you ping 192.0.2.12 via the vnet97 bridge.
-
-4) Examples
------------
-
-These assume a vnet with a bridge 'vnet97' has been created.
-
-Here's the full config for a vm on vnet 97, using ip addr 192.0.2.12:
-
-(vm
- (name dom12)
- (memory '64')
- (cpu '1')
- (console '8502')
- (image
-  (linux
-   (kernel /boot/vmlinuz-2.6-xenU)
-   (ip 192.0.2.12:192.0.2.4::::eth0:off)
-   (root /dev/sda1)
-   (args 'rw fastboot 4')
-  )
- )
- (device (vbd (uname phy:hda2) (dev sda1) (mode w)))
- (device (vif (mac aa:00:00:11:00:12) (bridge vnet97)))
-)
-
-If you run another vm on the same vnet:
-
-(vm
- (name dom11)
- (memory '64')
- (cpu '1')
- (console '8501')
- (image
-  (linux
-   (kernel /boot/vmlinuz-2.6-xenU)
-   (ip 192.0.2.11:192.0.2.4::::eth0:off)
-   (root /dev/sda1)
-   (args 'rw fastboot 4')
-  )
- )
- (device (vbd (uname phy:hda3) (dev sda1) (mode w)))
- (device (vif (mac aa:00:00:11:00:11) (bridge vnet97)))
-)
-
-the vms should be able to talk over the vnet. Check with ping.
-If they are both on the same machine the connection will simply
-be the vnet97 bridge, if they are on separate machines their
-packets will be tunneled in udp (or etherip). They should be able to
-see each other, but not the real network.
-
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/examples/Makefile
--- a/tools/vnet/examples/Makefile      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-# -*- mode: Makefile; -*-
-#============================================================================
-XEN_ROOT        = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-.PHONY: all
-all:
-
-.PHONY: install
-install:
-       $(INSTALL_DIR) $(XEN_SCRIPT_DIR)
-       $(INSTALL_PROG) network-vnet $(XEN_SCRIPT_DIR)
-       $(INSTALL_PROG) vnet-insert $(XEN_SCRIPT_DIR)
-
-.PHONY: clean
-clean:
diff -r 223f61702bda -r 28f04a659506 tools/vnet/examples/network-vnet
--- a/tools/vnet/examples/network-vnet  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-#!/bin/sh
-scriptdir=/etc/xen/scripts/
-
-case ${1} in
-    start)
-        ${scriptdir}/vnet-insert
-        ;;
-esac
-
-${scriptdir}/network-bridge "$@"
diff -r 223f61702bda -r 28f04a659506 tools/vnet/examples/vnet-insert
--- a/tools/vnet/examples/vnet-insert   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-# Insert the vnet module if it can be found and
-# it's not already there.
-vnet_insert () {
-    local module="vnet_module"
-    local mod_dir=/lib/modules/$(uname -r)
-    local mod_obj=""
-
-    if lsmod | grep -q ${module} ; then
-        echo "VNET: ${module} loaded"
-        return
-    fi
-    local mods=$(find ${mod_dir} -name "${module}.*o")
-    if [[ ${mods} ]] ; then
-        for mod_obj in ${mods} ; do
-            break
-        done
-    fi
-    if [ -z "${mod_obj}" ] ; then
-        echo "VNET: ${module} not found"
-        exit 1
-    fi
-    echo "VNET: Loading ${module} from ${mod_obj}"
-    insmod ${mod_obj} "$@"
-}
-
-vnet_insert "$@"
diff -r 223f61702bda -r 28f04a659506 tools/vnet/examples/vnet97.sxp
--- a/tools/vnet/examples/vnet97.sxp    Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-# Vnet configuration for a vnet with id 97 and no security.
-(vnet (id 97) (bridge vnet97) (vnetif vnif97) (security none))
diff -r 223f61702bda -r 28f04a659506 tools/vnet/examples/vnet98.sxp
--- a/tools/vnet/examples/vnet98.sxp    Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-# Vnet configuration for a vnet with id 98 and message authentication.
-(vnet (id 98) (bridge vnet98) (vnetif vnif98) (security auth))
diff -r 223f61702bda -r 28f04a659506 tools/vnet/examples/vnet99.sxp
--- a/tools/vnet/examples/vnet99.sxp    Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-# Vnet configuration for a vnet with id 99 and message confidentiality.
-(vnet (id 99) (bridge vnet99) (vnif vnetif99) (security conf))
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/Makefile
--- a/tools/vnet/libxutil/Makefile      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-ifndef VNET_ROOT
-export VNET_ROOT = $(shell cd .. && pwd)
-include $(VNET_ROOT)/Make.env
-endif
-
-include $(XEN_ROOT)/tools/Rules.mk
-
-LIB_SRCS :=
-LIB_SRCS += allocate.c
-LIB_SRCS += enum.c
-LIB_SRCS += file_stream.c
-#LIB_SRCS += gzip_stream.c
-LIB_SRCS += hash_table.c
-LIB_SRCS += iostream.c
-LIB_SRCS += lexis.c
-LIB_SRCS += mem_stream.c
-LIB_SRCS += string_stream.c
-LIB_SRCS += sxpr.c
-LIB_SRCS += sxpr_parser.c
-LIB_SRCS += sys_net.c
-LIB_SRCS += sys_string.c
-LIB_SRCS += util.c
-
-LIB_OBJS := $(LIB_SRCS:.c=.o)
-PIC_OBJS := $(LIB_SRCS:.c=.opic)
-
-$(call cc-option-add,CFLAGS,CC,-fgnu89-inline)
-CFLAGS   += -Werror -fno-strict-aliasing
-CFLAGS   += -O3
-#CFLAGS   += -g
-
-MAJOR    := 3.0
-MINOR    := 0
-LIB      := libxutil.so 
-LIB      += libxutil.so.$(MAJOR)
-LIB      += libxutil.so.$(MAJOR).$(MINOR)
-LIB      += libxutil.a
-
-.PHONY: all
-all: build
-
-.PHONY: build
-build: #check-for-zlib
-       $(MAKE) $(LIB)
-
-gzip_stream.o: check-for-zlib
-
-libxutil.so: libxutil.so.$(MAJOR)
-       ln -sf $^ $@
-
-libxutil.so.$(MAJOR): libxutil.so.$(MAJOR).$(MINOR)
-       ln -sf $^ $@
-
-libxutil.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
-       $(CC) $(CFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxutil.so.$(MAJOR) 
$(SHLIB_LDFLAGS) -o $@ $^
-
-libxutil.a: $(LIB_OBJS)
-       $(AR) rc $@ $^
-
-.PHONY: check-for-zlib
-check-for-zlib:
-       @if [ ! -e /usr/include/zlib.h ]; then \
-       echo "***********************************************************"; \
-       echo "ERROR: install zlib header files (http://www.gzip.org/zlib)"; \
-       echo "***********************************************************"; \
-       false; \
-       fi
-
-.PHONY: install
-install: build
-       $(INSTALL_DIR) $(DESTDIR)$(LIBDIR)
-       $(INSTALL_PROG) libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)
-       $(INSTALL_DATA) libxutil.a $(DESTDIR)$(LIBDIR)
-       ln -sf libxutil.so.$(MAJOR).$(MINOR) 
$(DESTDIR)$(LIBDIR)/libxutil.so.$(MAJOR)
-       ln -sf libxutil.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libxutil.so
-
-.PHONY: clean
-clean:
-       -@$(RM) *.a *.so* *.o *.opic *.rpm 
-       -@$(RM) *~
-       -@$(RM) $(DEPS)
-
--include $(DEPS)
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/allocate.c
--- a/tools/vnet/libxutil/allocate.c    Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "allocate.h"
-
-/** @file
- * Support for allocating memory.
- * Usable from user code or kernel code (with __KERNEL__ defined).
- * In user code will use GC if USE_GC is defined.
- */
-
-#ifdef __KERNEL__
-/*----------------------------------------------------------------------------*/
-#  include <linux/config.h>
-#  include <linux/slab.h>
-#  include <linux/string.h>
-#  include <linux/types.h>
-
-#  define DEFAULT_TYPE    0
-#  define MALLOC(n, type) kmalloc(n, type)
-#  define FREE(ptr)       kfree(ptr)
-
-/*----------------------------------------------------------------------------*/
-#else /* ! __KERNEL__ */
-
-#  include <stdlib.h>
-#  include <string.h>
-
-#  define DEFAULT_TYPE    0
-
-#ifdef USE_GC
-#  include "gc.h"
-#  define MALLOC(n, typ)  GC_malloc(n)
-#  define FREE(ptr)       (ptr=NULL)
-//typedef void *GC_PTR;
-//GC_PTR (*GC_oom_fn)(size_t n);
-#else
-#  define MALLOC(n, type) malloc(n)
-#  define FREE(ptr)       free(ptr)
-#endif
-
-/*----------------------------------------------------------------------------*/
-#endif
-
-/** Function to call when memory cannot be allocated. */
-AllocateFailedFn *allocate_failed_fn = NULL;
-
-/** Allocate memory and zero it.
- * The type is only relevant when calling from kernel code,
- * from user code it is ignored.
- * In kernel code the values accepted by kmalloc can be used:
- * GFP_USER, GFP_ATOMIC, GFP_KERNEL.
- *
- * @param size number of bytes to allocate
- * @param type memory type to allocate (kernel only)
- * @return pointer to the allocated memory or zero
- * if malloc failed
- */
-void *allocate_type(int size, int type){
-    void *p = MALLOC(size, type);
-    if(p){
-        memzero(p, size);
-    } else if(allocate_failed_fn){
-        allocate_failed_fn(size, type);
-    }
-    return p;
-}
-
-/** Allocate memory and zero it.
- *
- * @param size number of bytes to allocate
- * @return pointer to the allocated memory or zero
- * if malloc failed
- */
-void *allocate(int size){
-    return allocate_type(size, DEFAULT_TYPE);
-}
-
-/** Free memory allocated by allocate().
- * No-op if 'p' is null.
- *
- * @param p memory to free
- */
-void deallocate(void *p){
-    if(p){
-        FREE(p);
-    }
-}
-
-/** Set bytes to zero.
- * No-op if 'p' is null.
- *
- * @param p memory to zero
- * @param size number of bytes to zero
- */
-void memzero(void *p, int size){
-    if(p){
-        memset(p, 0, (size_t)size);
-    }
-}
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/allocate.h
--- a/tools/vnet/libxutil/allocate.h    Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_ALLOCATE_H_
-#define _XUTIL_ALLOCATE_H_
-
-/** Allocate memory for a given type, and cast. */
-#define ALLOCATE(ctype) (ctype *)allocate(sizeof(ctype))
-
-/** Allocate memory for a given type, and cast. */
-#define ALLOCATE_TYPE(ctype, type) (ctype *)allocate(sizeof(ctype))
-
-extern void *allocate_type(int size, int type);
-extern void *allocate(int size);
-extern void deallocate(void *);
-extern void memzero(void *p, int size);
-
-typedef void AllocateFailedFn(int size, int type);
-extern AllocateFailedFn *allocate_failed_fn;
-
-#endif /* _XUTIL_ALLOCATE_H_ */
-
-
-
-
-
-
-
-
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/debug.h
--- a/tools/vnet/libxutil/debug.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef _XUTIL_DEBUG_H_
-#define _XUTIL_DEBUG_H_
-
-#ifndef MODULE_NAME
-#define MODULE_NAME ""
-#endif
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/kernel.h>
-
-#ifdef DEBUG
-
-#define dprintf(fmt, args...) printk(KERN_DEBUG   "[DBG] " MODULE_NAME ">%s" 
fmt, __FUNCTION__, ##args)
-#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME ">%s" 
fmt, __FUNCTION__, ##args)
-#define iprintf(fmt, args...) printk(KERN_INFO    "[INF] " MODULE_NAME ">%s" 
fmt, __FUNCTION__, ##args)
-#define eprintf(fmt, args...) printk(KERN_ERR     "[ERR] " MODULE_NAME ">%s" 
fmt, __FUNCTION__, ##args)
-
-#else
-
-#define dprintf(fmt, args...) do {} while(0)
-#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME fmt, 
##args)
-#define iprintf(fmt, args...) printk(KERN_INFO    "[INF] " MODULE_NAME fmt, 
##args)
-#define eprintf(fmt, args...) printk(KERN_ERR     "[ERR] " MODULE_NAME fmt, 
##args)
-
-#endif
-
-#else
-
-#include <stdio.h>
-
-#ifdef DEBUG
-
-#define dprintf(fmt, args...) fprintf(stdout, "%d [DBG] " MODULE_NAME ">%s" 
fmt, getpid(), __FUNCTION__, ##args)
-#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME ">%s" 
fmt, getpid(), __FUNCTION__, ##args)
-#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME ">%s" 
fmt, getpid(), __FUNCTION__, ##args)
-#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME ">%s" 
fmt, getpid(), __FUNCTION__, ##args)
-
-#else
-
-#define dprintf(fmt, args...) do {} while(0)
-#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME fmt, 
getpid(), ##args)
-#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME fmt, 
getpid(), ##args)
-#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME fmt, 
getpid(), ##args)
-
-#endif
-
-#endif
-
-/** Print format for an IP address.
- * See NIPQUAD(), HIPQUAD()
- */
-#define IPFMT "%u.%u.%u.%u"
-
-#endif /* ! _XUTIL_DEBUG_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/enum.c
--- a/tools/vnet/libxutil/enum.c        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2002, 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifdef __KERNEL__
-#include <linux/errno.h>
-#else
-#include <errno.h>
-#endif
-
-#include "sys_string.h"
-#include "enum.h"
-
-/** Map an enum name to its value using a table.
- *
- * @param name enum name
- * @param defs enum definitions
- * @return enum value or -1 if not known
- */
-int enum_name_to_val(char *name, EnumDef *defs){
-    int val = -1;
-    for(; defs->name; defs++){
-       if(!strcmp(defs->name, name)){
-           val = defs->val;
-           break;
-       }
-    }
-    return val;
-}
-
-/** Map an enum value to its name using a table.
- *
- * @param val enum value
- * @param defs enum definitions
- * @param defs_n number of definitions
- * @return enum name or NULL if not known
- */
-char *enum_val_to_name(int val, EnumDef *defs){
-    char *name = NULL;
-    for(; defs->name; defs++){
-       if(val == defs->val){
-           name = defs->name;
-           break;
-       }
-    }
-    return name;
-}
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/enum.h
--- a/tools/vnet/libxutil/enum.h        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2002, 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _XUTIL_ENUM_H_
-#define _XUTIL_ENUM_H_
-
-/** Mapping of an enum value to a name. */
-typedef struct EnumDef {
-    int val;
-    char *name;
-} EnumDef;
-
-extern int enum_name_to_val(char *name, EnumDef *defs);
-extern char *enum_val_to_name(int val, EnumDef *defs);
-
-#endif /* _XUTIL_ENUM_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/fd_stream.c
--- a/tools/vnet/libxutil/fd_stream.c   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * An IOStream implementation using fds.
- */
-#ifndef __KERNEL__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include "allocate.h"
-#include "fd_stream.h"
-
-#define MODULE_NAME "fd_stream"
-#define DEBUG 1
-//#undef DEBUG
-#include "debug.h"
-
-static int fd_read(IOStream *s, void *buf, size_t n);
-static int fd_write(IOStream *s, const void *buf, size_t n);
-static int fd_error(IOStream *s);
-static int fd_close(IOStream *s);
-static void fd_free(IOStream *s);
-static int fd_flush(IOStream *s);
-
-/** Methods used by a fd IOStream. */
-static const IOMethods fd_methods = {
-    read:  fd_read,
-    write: fd_write,
-    error: fd_error,
-    close: fd_close,
-    free:  fd_free,
-    flush: fd_flush,
-};
-
-/** Get the fd data.
- * 
- * @param io fd stream
- * @return data
- */
-static inline FDData * fd_data(IOStream *io){
-    return (FDData *)io->data;
-}
-
-/** Test if a stream is a fd stream.
- *
- * @param io stream
- * @return 0 if a fd stream, -EINVAL if not
- */
-int fd_stream_check(IOStream *io){
-    return (io && io->methods == &fd_methods ? 0 : -EINVAL);
-}
-
-/** Get the data for a fd stream.
- *
- * @param io stream
- * @param data return value for the data
- * @return 0 if a fd stream, -EINVAL if not
- */
-int fd_stream_data(IOStream *io, FDData **data){
-    int err = fd_stream_check(io);
-    if(err){
-        *data = NULL;
-    } else {
-        *data = fd_data(io);
-    }
-    return err;
-}
-
-
-/** Write to the underlying fd.
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to write
- * @return number of bytes written
- */
-static int fd_write(IOStream *s, const void *buf, size_t n){
-    FDData *data = fd_data(s);
-    int k;
-    k = write(data->fd, buf, n);
-    return k;
-}
-
-/** Read from the underlying stream;
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to read
- * @return number of bytes read
- */
-static int fd_read(IOStream *s, void *buf, size_t n){
-    FDData *data = fd_data(s);
-    int k;
-    k = read(data->fd, buf, n);
-    //printf("> fd_read> buf=%p n=%d --> k=%d\n", buf, n, k);
-    return k;
-}
-
-/** Flush the fd (no-op).
- *
- * @param s fd stream
- * @return 0 on success, error code otherwise
- */
-static int fd_flush(IOStream *s){
-    return 0;
-}
-
-/** Check if a fd stream has an error (no-op).
- *
- * @param s fd stream
- * @return 1 if has an error, 0 otherwise
- */
-static int fd_error(IOStream *s){
-    return 0;
-}
-
-/** Close a fd stream.
- *
- * @param s fd stream to close
- * @return result of the close
- */
-static int fd_close(IOStream *s){
-    FDData *data = fd_data(s);
-    return close(data->fd);
-}
-
-/** Free a fd stream.
- *
- * @param s fd stream
- */
-static void fd_free(IOStream *s){
-    FDData *data = fd_data(s);
-    deallocate(data);
-}
-
-/** Create an IOStream for a fd.
- *
- * @param fd fd to wtap
- * @return new IOStream using fd for i/o
- */
-IOStream *fd_stream_new(int fd){
-    int err = -ENOMEM;
-    IOStream *io = NULL;
-    FDData *data = NULL;
-
-    io = ALLOCATE(IOStream);
-    if(!io) goto exit;
-    io->methods = &fd_methods;
-    data = ALLOCATE(FDData);
-    if(!data) goto exit;
-    io->data = data;
-    data->fd = fd;
-    err = 0;
-  exit:
-    if(err){
-        if(io){
-            if(data) deallocate(data);
-            deallocate(io);
-            io = NULL;
-        }
-    }
-    return io;
-}
-
-#endif
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/fd_stream.h
--- a/tools/vnet/libxutil/fd_stream.h   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XMC_FD_STREAM_H_
-#define _XMC_FD_STREAM_H_
-
-#ifndef __KERNEL__
-#include "iostream.h"
-
-/** Data associated with a fd stream. */
-typedef struct FDData {
-    /** The socket file descriptor. */
-    int fd;
-} FDData;
-
-extern IOStream *fd_stream_new(int fd);
-extern int fd_stream_data(IOStream *io, FDData **data);
-extern int fd_stream_check(IOStream *io);
-
-#endif
-#endif /* !_XMC_FD_STREAM_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/file_stream.c
--- a/tools/vnet/libxutil/file_stream.c Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * An IOStream implementation using FILE*.
- */
-#ifndef __KERNEL__
-#include <stdio.h>
-#include <stdlib.h>
-#include "allocate.h"
-#include "file_stream.h"
-
-static int file_read(IOStream *s, void *buf, size_t n);
-static int file_write(IOStream *s, const void *buf, size_t n);
-static int file_error(IOStream *s);
-static int file_close(IOStream *s);
-static void file_free(IOStream *s);
-static int file_flush(IOStream *s);
-
-/** Methods used by a FILE* IOStream. */
-static const IOMethods file_methods = {
-    read:  file_read,
-    write: file_write,
-    error: file_error,
-    close: file_close,
-    free:  file_free,
-    flush: file_flush,
-};
-
-/** IOStream for stdin. */
-static IOStream _iostdin = {
-    methods: &file_methods,
-    data: (void*)1,
-    nofree: 1,
-};
-
-/** IOStream for stdout. */
-static IOStream _iostdout = {
-    methods: &file_methods,
-    data: (void*)2,
-    nofree: 1,
-};
-
-/** IOStream for stderr. */
-static IOStream _iostderr = {
-    methods: &file_methods,
-    data: (void*)3,
-    nofree: 1,
-};
-
-/** IOStream for stdin. */
-IOStream *iostdin = &_iostdin;
-
-/** IOStream for stdout. */
-IOStream *iostdout = &_iostdout;
-
-/** IOStream for stderr. */
-IOStream *iostderr = &_iostderr;
-
-/* Get the underlying FILE*.
- *
- * @param s file stream
- * @return the stream s wraps
- */
-static inline FILE *get_file(IOStream *s){
-     FILE *data = NULL;
-     switch((long)s->data){
-     case 1:
-         data = stdin;
-         break;
-     case 2:
-         data = stdout;
-         break;
-     case 3:
-         data = stderr;
-         break;
-     default:
-         data = (FILE*)s->data;
-         break;
-     }
-     return data;
-}
-
-/** Control buffering on the underlying stream, like setvbuf().
- *
- * @param io file stream
- * @param buf buffer
- * @param mode buffering mode (see man setvbuf())
- * @param size buffer size
- * @return 0 on success, non-zero otherwise
- */
-int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size){
-    return setvbuf(get_file(io), buf, mode, size);
-}
-
-/** Write to the underlying stream using fwrite();
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to write
- * @return number of bytes written
- */
-static int file_write(IOStream *s, const void *buf, size_t n){
-    return fwrite(buf, 1, n, get_file(s));
-}
-
-/** Read from the underlying stream using fread();
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to read
- * @return number of bytes read
- */
-static int file_read(IOStream *s, void *buf, size_t n){
-    return fread(buf, 1, n, get_file(s));
-}
-
-/** Fush the underlying stream using fflush().
- *
- * @param s file stream
- * @return 0 on success, error code otherwise
- */
-static int file_flush(IOStream *s){
-    return fflush(get_file(s));
-}
-
-/** Check if a stream has an error.
- *
- * @param s file stream
- * @return 1 if has an error, 0 otherwise
- */
-static int file_error(IOStream *s){
-    return ferror(get_file(s));
-}
-
-/** Close a file stream.
- *
- * @param s file stream to close
- * @return result of the close
- */
-static int file_close(IOStream *s){
-    int result = 0;
-    result = fclose(get_file(s));
-    return result;
-}
-
-/** Free a file stream.
- *
- * @param s file stream
- */
-static void file_free(IOStream *s){
-    // Nothing extra to do - close did it all.
-}
-
-/** Create an IOStream for a stream.
- *
- * @param f stream to wrap
- * @return new IOStream using f for i/o
- */
-IOStream *file_stream_new(FILE *f){
-    IOStream *io = ALLOCATE(IOStream);
-    if(io){
-        io->methods = &file_methods;
-        io->data = (void*)f;
-    }
-    return io;
-}
-
-/** IOStream version of fopen().
- *
- * @param file name of the file to open
- * @param flags giving the mode to open in (as for fopen())
- * @return new stream for the open file, or 0 if failed
- */
-IOStream *file_stream_fopen(const char *file, const char *flags){
-    IOStream *io = 0;
-    FILE *fin = fopen(file, flags);
-    if(fin){
-        io = file_stream_new(fin);
-        if(!io){
-            fclose(fin);
-        }
-    }
-    return io;
-}
-
-/** IOStream version of fdopen().
- *
- * @param fd file descriptor
- * @param flags giving the mode to open in (as for fdopen())
- * @return new stream for the open file, or 0 if failed.  Always takes
- *         ownership of fd.
- */
-IOStream *file_stream_fdopen(int fd, const char *flags){
-    IOStream *io = 0;
-    FILE *fin = fdopen(fd, flags);
-    if(fin){
-        io = file_stream_new(fin);
-        if(!io){
-            fclose(fin);
-        }
-    }
-    return io;
-}
-#endif
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/file_stream.h
--- a/tools/vnet/libxutil/file_stream.h Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_FILE_STREAM_H_
-#define _XUTIL_FILE_STREAM_H_
-
-#ifndef __KERNEL__
-#include "iostream.h"
-#include <stdio.h>
-
-extern IOStream *file_stream_new(FILE *f);
-extern IOStream *file_stream_fopen(const char *file, const char *flags);
-extern IOStream *file_stream_fdopen(int fd, const char *flags);
-extern IOStream get_stream_stdout(void);
-extern IOStream get_stream_stderr(void);
-extern IOStream get_stream_stdin(void);
-
-extern int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size);
-#endif
-#endif /* !_XUTIL_FILE_STREAM_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/gzip_stream.c
--- a/tools/vnet/libxutil/gzip_stream.c Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2003 Hewlett-Packard Company.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * An IOStream implementation using zlib gzFile to provide
- * compression and decompression.
- */
-#ifndef __KERNEL__
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "zlib.h"
-
-#include "allocate.h"
-#include "gzip_stream.h"
-
-static int gzip_read(IOStream *s, void *buf, size_t n);
-static int gzip_write(IOStream *s, const void *buf, size_t n);
-static int gzip_error(IOStream *s);
-static int gzip_close(IOStream *s);
-static void gzip_free(IOStream *s);
-static int gzip_flush(IOStream *s);
-
-/** Methods used by a gzFile* IOStream. */
-static const IOMethods gzip_methods = {
-    read:  gzip_read,
-    write: gzip_write,
-    error: gzip_error,
-    close: gzip_close,
-    free:  gzip_free,
-    flush: gzip_flush,
-};
-
-/** Get the underlying gzFile*.
- * 
- * @param s gzip stream
- * @return the stream s wraps
- */
-static inline gzFile get_gzfile(IOStream *s){
-    return (gzFile)s->data;
-}
-
-/** Write to the underlying stream.
- *
- * @param stream destination
- * @param buf data
- * @param n number of bytes to write
- * @return number of bytes written
- */
-static int gzip_write(IOStream *s, const void *buf, size_t n){
-    return gzwrite(get_gzfile(s), (void*)buf, n);
-}
-
-/** Read from the underlying stream.
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to read
- * @return number of bytes read
- */
-static int gzip_read(IOStream *s, void *buf, size_t n){
-    return gzread(get_gzfile(s), buf, n);
-}
-
-/** Flush the underlying stream.
- *
- * @param s gzip stream
- * @return 0 on success, error code otherwise
- */
-static int gzip_flush(IOStream *s){
-    //return gzflush(get_gzfile(s), Z_NO_FLUSH);
-    return gzflush(get_gzfile(s), Z_SYNC_FLUSH);
-    //return gzflush(get_gzfile(s), Z_FULL_FLUSH);
-}
-
-/** Check if a stream has an error.
- *
- * @param s gzip stream
- * @return 1 if has an error, 0 otherwise
- */
-static int gzip_error(IOStream *s){
-    int err;
-    gzFile *gz = get_gzfile(s);
-    gzerror(gz, &err);
-    return (err == Z_ERRNO ? 1 /* ferror(gzfile(gz)) */ : err);
-}
-
-/** Close a gzip stream.
- *
- * @param s gzip stream to close
- * @return result of the close
- */
-static int gzip_close(IOStream *s){
-    int result = 0;
-    result = gzclose(get_gzfile(s));
-    return result;
-}
-
-/** Free a gzip stream.
- *
- * @param s gzip stream
- */
-static void gzip_free(IOStream *s){
-    // Nothing to do - close did it all.
-}
-
-/** Create an IOStream for a gzip stream.
- *
- * @param f stream to wrap
- * @return new IOStream using f for i/o
- */
-IOStream *gzip_stream_new(gzFile *f){
-    IOStream *io = ALLOCATE(IOStream);
-    if(io){
-        io->methods = &gzip_methods;
-        io->data = (void*)f;
-    }
-    return io;
-}
-
-/** IOStream version of fopen().
- *
- * @param file name of the file to open
- * @param flags giving the mode to open in (as for fopen())
- * @return new stream for the open file, or NULL if failed
- */
-IOStream *gzip_stream_fopen(const char *file, const char *flags){
-    IOStream *io = NULL;
-    gzFile *fgz;
-    fgz = gzopen(file, flags);
-    if(fgz){
-        io = gzip_stream_new(fgz);
-        if(!io){
-            gzclose(fgz);
-        }
-    }
-    return io;
-}
-
-/** IOStream version of fdopen().
- *
- * @param fd file descriptor
- * @param flags giving the mode to open in (as for fdopen())
- * @return new stream for the open file, or NULL if failed.  Always takes
- *         ownership of fd.
- */
-IOStream *gzip_stream_fdopen(int fd, const char *flags){
-    IOStream *io = NULL;
-    gzFile *fgz;
-    fgz = gzdopen(fd, flags);
-    if(fgz){
-        io = gzip_stream_new(fgz);
-        if(!io)
-            gzclose(fgz);
-    }
-    return io;
-}
-#endif
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/gzip_stream.h
--- a/tools/vnet/libxutil/gzip_stream.h Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2003 Hewlett-Packard Company.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_GZIP_STREAM_H_
-#define _XUTIL_GZIP_STREAM_H_
-
-#ifndef __KERNEL__
-#include "iostream.h"
-#include "zlib.h"
-
-extern IOStream *gzip_stream_new(gzFile *f);
-extern IOStream *gzip_stream_fopen(const char *file, const char *flags);
-extern IOStream *gzip_stream_fdopen(int fd, const char *flags);
-#endif
-#endif /* !_XUTIL_GZIP_STREAM_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/hash_table.c
--- a/tools/vnet/libxutil/hash_table.c  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,658 +0,0 @@
-/*
- * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifdef __KERNEL__
-#  include <linux/config.h>
-#  include <linux/module.h>
-#  include <linux/kernel.h>
-#  include <linux/errno.h>
-#else
-#  include <errno.h>
-#  include <stddef.h>
-#endif
-
-#include "allocate.h"
-#include "hash_table.h"
-
-/** @file
- * Base support for hashtables.
- *
- * Hash codes are reduced modulo the number of buckets to index tables,
- * so there is no need for hash functions to limit the range of hashcodes.
- * In fact it is assumed that hashcodes do not change when the number of
- * buckets in the table changes.
- */
-
-/*============================================================================*/
-/*
---------------------------------------------------------------------
-lookup2.c, by Bob Jenkins, December 1996, Public Domain.
-You can use this free for any purpose.  It has no warranty.
---------------------------------------------------------------------
-*/
-
-#define hashsize(n) ((ub4)1<<(n))
-#define hashmask(n) (hashsize(n)-1)
-
-/*
---------------------------------------------------------------------
-mix -- mix 3 32-bit values reversibly.
-For every delta with one or two bit set, and the deltas of all three
-  high bits or all three low bits, whether the original value of a,b,c
-  is almost all zero or is uniformly distributed,
-* If mix() is run forward or backward, at least 32 bits in a,b,c
-  have at least 1/4 probability of changing.
-* If mix() is run forward, every bit of c will change between 1/3 and
-  2/3 of the time.  (Well, 22/100 and 78/100 for some 2-bit deltas.)
-mix() was built out of 36 single-cycle latency instructions in a 
-  structure that could supported 2x parallelism, like so:
-      a -= b; 
-      a -= c; x = (c>>13);
-      b -= c; a ^= x;
-      b -= a; x = (a<<8);
-      c -= a; b ^= x;
-      c -= b; x = (b>>13);
-      ...
-  Unfortunately, superscalar Pentiums and Sparcs can't take advantage 
-  of that parallelism.  They've also turned some of those single-cycle
-  latency instructions into multi-cycle latency instructions.  Still,
-  this is the fastest good hash I could find.  There were about 2^^68
-  to choose from.  I only looked at a billion or so.
---------------------------------------------------------------------
-*/
-#define mix(a,b,c) \
-{ \
-  a -= b; a -= c; a ^= (c>>13); \
-  b -= c; b -= a; b ^= (a<<8); \
-  c -= a; c -= b; c ^= (b>>13); \
-  a -= b; a -= c; a ^= (c>>12);  \
-  b -= c; b -= a; b ^= (a<<16); \
-  c -= a; c -= b; c ^= (b>>5); \
-  a -= b; a -= c; a ^= (c>>3);  \
-  b -= c; b -= a; b ^= (a<<10); \
-  c -= a; c -= b; c ^= (b>>15); \
-}
-
-/*
---------------------------------------------------------------------
-hash() -- hash a variable-length key into a 32-bit value
-  k     : the key (the unaligned variable-length array of bytes)
-  len   : the length of the key, counting by bytes
-  level : can be any 4-byte value
-Returns a 32-bit value.  Every bit of the key affects every bit of
-the return value.  Every 1-bit and 2-bit delta achieves avalanche.
-About 36+6len instructions.
-
-The best hash table sizes are powers of 2.  There is no need to do
-mod a prime (mod is sooo slow!).  If you need less than 32 bits,
-use a bitmask.  For example, if you need only 10 bits, do
-  h = (h & hashmask(10));
-In which case, the hash table should have hashsize(10) elements.
-
-If you are hashing n strings (ub1 **)k, do it like this:
-  for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
-
-By Bob Jenkins, 1996.  bob_jenkins@xxxxxxxxxxxxxxxxx  You may use this
-code any way you wish, private, educational, or commercial.  It's free.
-
-See http://burlteburtle.net/bob/hash/evahash.html
-Use for hash table lookup, or anything where one collision in 2^32 is
-acceptable.  Do NOT use for cryptographic purposes.
---------------------------------------------------------------------
-*/
-
-static inline ub4 _hash(const ub1 *k, ub4 length, ub4 initval)
-//register ub1 *k;        /* the key */
-//register ub4  length;   /* the length of the key */
-//register ub4  initval;    /* the previous hash, or an arbitrary value */
-{
-    /*register*/ ub4 a,b,c,len;
-
-   /* Set up the internal state */
-   len = length;
-   a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
-   c = initval;           /* the previous hash value */
-
-   /*---------------------------------------- handle most of the key */
-   while (len >= 12)
-   {
-      a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
-      b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
-      c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
-      mix(a,b,c);
-      k += 12; len -= 12;
-   }
-
-   /*------------------------------------- handle the last 11 bytes */
-   c += length;
-   switch(len)              /* all the case statements fall through */
-   {
-   case 11: c+=((ub4)k[10]<<24);
-   case 10: c+=((ub4)k[9]<<16);
-   case 9 : c+=((ub4)k[8]<<8);
-      /* the first byte of c is reserved for the length */
-   case 8 : b+=((ub4)k[7]<<24);
-   case 7 : b+=((ub4)k[6]<<16);
-   case 6 : b+=((ub4)k[5]<<8);
-   case 5 : b+=k[4];
-   case 4 : a+=((ub4)k[3]<<24);
-   case 3 : a+=((ub4)k[2]<<16);
-   case 2 : a+=((ub4)k[1]<<8);
-   case 1 : a+=k[0];
-     /* case 0: nothing left to add */
-   }
-   mix(a,b,c);
-   /*-------------------------------------------- report the result */
-   return c;
-}
-
-ub4 hash(const ub1 *k, ub4 length, ub4 initval){
-    return _hash(k, length, initval);
-}
-
-/*============================================================================*/
-
-/** Get the bucket for a hashcode in a hash table.
- *
- * @param table to get bucket from
- * @param hashcode to get bucket for
- * @return bucket
- */
-inline HTBucket * get_bucket(HashTable *table, Hashcode hashcode){
-    return table->buckets + (hashcode % table->buckets_n);
-}
-
-/** Initialize a hash table.
- *
- * @param table to initialize
- */
-static void HashTable_init(HashTable *table){
-    int i;
-
-    for(i = 0; i < table->buckets_n; i++){
-        HTBucket *bucket = get_bucket(table, i);
-        bucket->head = NULL;
-        bucket->count = 0;
-    }
-    table->entry_count = 0;
-}
-
-/** Allocate a new hashtable.
- * If the number of buckets is not positive the default is used.
- *
- * @param buckets_n number of buckets
- * @return new hashtable or null
- */
-HashTable *HashTable_new(int buckets_n){
-    HashTable *z = ALLOCATE(HashTable);
-    if(!z) goto exit;
-    if(buckets_n <= 0){
-        buckets_n = HT_BUCKETS_N;
-    }
-    z->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket));
-    if(!z->buckets){
-        deallocate(z);
-        z = NULL;
-        goto exit;
-    }
-    z->buckets_n = buckets_n;
-    HashTable_init(z);
-  exit:
-    return z;
-}
-
-/** Free a hashtable.
- * Any entries are removed and freed.
- *
- * @param h hashtable (ignored if null)
- */
-void HashTable_free(HashTable *h){
-    if(h){
-        HashTable_clear(h);
-        deallocate(h->buckets);
-        deallocate(h);
-    }
-}
-
-/** Push an entry on the list in the bucket for a given hashcode.
- *
- * @param table to add entry to
- * @param hashcode for the entry
- * @param entry to add
- */
-static inline void push_on_bucket(HashTable *table, Hashcode hashcode,
-                                 HTEntry *entry){
-    HTBucket *bucket;
-    HTEntry *old_head;
-
-    bucket = get_bucket(table, hashcode);
-    old_head = bucket->head;
-    bucket->count++;
-    bucket->head = entry;
-    entry->next = old_head;
-}
-
-/** Change the number of buckets in a hashtable.
- * No-op if the number of buckets is not positive.
- * Existing entries are reallocated to buckets based on their hashcodes.
- * The table is unmodified if the number of buckets cannot be changed.
- *
- * @param table hashtable
- * @param buckets_n new number of buckets
- * @return 0 on success, error code otherwise
- */
-int HashTable_set_buckets_n(HashTable *table, int buckets_n){
-    int err = 0;
-    HTBucket *old_buckets = table->buckets;
-    int old_buckets_n = table->buckets_n;
-    int i;
-
-    if(buckets_n <= 0){
-        err = -EINVAL;
-        goto exit;
-    }
-    table->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket));
-    if(!table->buckets){
-        err = -ENOMEM;
-        table->buckets = old_buckets;
-        goto exit;
-    }
-    table->buckets_n = buckets_n;
-    for(i=0; i < old_buckets_n; i++){
-        HTBucket *bucket = old_buckets + i;
-        HTEntry *entry, *next;
-        for(entry = bucket->head; entry; entry = next){
-            next = entry->next;
-            push_on_bucket(table, entry->hashcode, entry);
-        }
-    }
-    deallocate(old_buckets);
-  exit:
-    return err;
-}
-
-/** Adjust the number of buckets so the table is neither too full nor too 
empty.
- * The table is unmodified if adjusting fails.
- *
- * @param table hash table
- * @param buckets_min minimum number of buckets (use default if 0 or negative)
- * @return 0 on success, error code otherwise
- */
-int HashTable_adjust(HashTable *table, int buckets_min){
-    int buckets_n = 0;
-    int err = 0;
-    if(buckets_min <= 0) buckets_min = HT_BUCKETS_N;
-    if(table->entry_count >= table->buckets_n){
-        // The table is dense - expand it.
-        buckets_n = 2 * table->buckets_n;
-    } else if((table->buckets_n > buckets_min) &&
-              (4 * table->entry_count < table->buckets_n)){
-        // The table is more than minimum size and sparse - shrink it.
-        buckets_n = 2 * table->entry_count;
-        if(buckets_n < buckets_min) buckets_n = buckets_min;
-    }
-    if(buckets_n){
-        err = HashTable_set_buckets_n(table, buckets_n);
-    }
-    return err;
-}
-
-/** Allocate a new entry for a given value.
- *
- * @param value to put in the entry
- * @return entry, or 0 on failure
- */
-HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value){
-    HTEntry *z = ALLOCATE(HTEntry);
-    if(z){
-        z->hashcode = hashcode;
-        z->key = key;
-        z->value = value;
-    }
-    return z;
-}
-
-/** Free an entry.
- *
- * @param z entry to free
- */
-inline void HTEntry_free(HTEntry *z){
-    if(z){
-        deallocate(z);
-    }
-}
-
-/** Free an entry in a hashtable.
- * The table's entry_free_fn is used is defined, otherwise 
- * the HTEntry itself is freed.
- *
- * @param table hashtable
- * @param entry to free
- */
-inline void HashTable_free_entry(HashTable *table, HTEntry *entry){
-    if(!entry) return;
-    if(table && table->entry_free_fn){
-        table->entry_free_fn(table, entry);
-    } else {
-        HTEntry_free(entry);
-    }
-}
-
-/** Get the first entry satisfying a test from the bucket for the
- * given hashcode.
- *
- * @param table to look in
- * @param hashcode indicates the bucket
- * @param test_fn test to apply to elements
- * @param arg first argument to calls to test_fn
- * @return entry found, or 0
- */
-inline HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode,
-                                     TableTestFn *test_fn, TableArg arg){
-    HTBucket *bucket;
-    HTEntry *entry = NULL;
-    HTEntry *next;
-
-    bucket = get_bucket(table, hashcode);
-    for(entry = bucket->head; entry; entry = next){
-        next = entry->next;
-        if(test_fn(arg, table, entry)){
-            break;
-        }
-    }
-    return entry;
-}
-
-/** Test hashtable keys for equality.
- * Uses the table's key_equal_fn if defined, otherwise pointer equality.
- *
- * @param key1 key to compare
- * @param key2 key to compare
- * @return 1 if equal, 0 otherwise
- */
-inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){
-    if(table->key_size){
-        return memcmp(key1, key2, table->key_size) == 0;
-    }
-    return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1 == 
key2);
-}
-
-/** Compute the hashcode of a hashtable key.
- * The table's key_hash_fn is used if defined, otherwise the address of
- * the key is hashed.
- *
- * @param table hashtable
- * @param key to hash
- * @return hashcode
- */
-inline Hashcode HashTable_key_hash(HashTable *table, void *key){
-    if(table->key_size){
-        return _hash(key, table->key_size, 0);
-    }
-    return (table->key_hash_fn 
-            ? table->key_hash_fn(key)
-            : hash_hvoid(0, &key, sizeof(key)));
-}
-
-/** Test if an entry has a given key.
- *
- * @param arg containing key to test for
- * @param table the entry is in
- * @param entry to test
- * @return 1 if the entry has the key, 0 otherwise
- */
-static inline int has_key(TableArg arg, HashTable *table, HTEntry *entry){
-    return HashTable_key_equal(table, arg.ptr, entry->key);
-}
-
-/** Get an entry with a given key.
- *
- * @param table to search
- * @param key to look for
- * @return entry if found, null otherwise
- */
-inline HTEntry * HashTable_get_entry(HashTable *table, void *key){
-    Hashcode hashcode;
-    HTBucket *bucket;
-    HTEntry *entry = NULL;
-    HTEntry *next;
-
-    hashcode = HashTable_key_hash(table, key);
-    bucket = get_bucket(table, hashcode);
-    for(entry = bucket->head; entry; entry = next){
-        next = entry->next;
-        if(HashTable_key_equal(table, key, entry->key)){
-            break;
-        }
-    }
-    return entry;
-}
-
-/** Get the value of an entry with a given key.
- *
- * @param table to search
- * @param key to look for
- * @return value if an entry was found, null otherwise
- */
-inline void * HashTable_get(HashTable *table, void *key){
-    HTEntry *entry = HashTable_get_entry(table, key);
-    return (entry ? entry->value : 0);
-}
-
-/** Print the buckets in a table.
- *
- * @param table to print
- */
-void show_buckets(HashTable *table, IOStream *io){
-    int i,j ;
-    IOStream_print(io, "entry_count=%d buckets_n=%d\n", table->entry_count, 
table->buckets_n);
-    for(i=0; i < table->buckets_n; i++){
-        if(0 || table->buckets[i].count>0){
-            IOStream_print(io, "bucket %3d %3d %10p ", i,
-                        table->buckets[i].count,
-                        table->buckets[i].head);
-            for(j = table->buckets[i].count; j>0; j--){
-                IOStream_print(io, "+");
-            }
-            IOStream_print(io, "\n");
-        }
-    }
-    HashTable_print(table, io); 
-}
-    
-/** Print an entry in a table.
- *
- * @param entry to print
- * @param arg a pointer to an IOStream to print to
- * @return 0
- */
-static int print_entry(TableArg arg, HashTable *table, HTEntry *entry){
-    IOStream *io = (IOStream*)arg.ptr;
-    IOStream_print(io, " b=%4lx h=%08lx |-> e=%8p k=%8p v=%8p\n",
-                entry->hashcode % table->buckets_n,
-                entry->hashcode,
-                entry, entry->key, entry->value);
-    return 0;
-}
-
-/** Print a hash table.
- *
- * @param table to print
- */
-void HashTable_print(HashTable *table, IOStream *io){
-    IOStream_print(io, "{\n");
-    HashTable_map(table, print_entry, (TableArg){ ptr: io });
-    IOStream_print(io, "}\n");
-}
-/*==========================================================================*/
-
-/** Add an entry to the bucket for the
- * given hashcode.
- *
- * @param table to insert in
- * @param hashcode indicates the bucket
- * @param key to add an entry for
- * @param value to add an entry for
- * @return entry on success, 0 on failure
- */
-inline HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void 
*key, void *value){
-    HTEntry *entry = HTEntry_new(hashcode, key, value);
-    if(entry){
-        push_on_bucket(table, hashcode, entry);
-        table->entry_count++;
-    }
-    return entry;
-}
-
-/** Move the front entry for a bucket to the correct point in the bucket order 
as
- * defined by the order function. If this is called every time a new entry is 
added
- * the bucket will be maintained in sorted order.
- *
- * @param table to modify
- * @param hashcode indicates the bucket
- * @param order entry comparison function
- * @return 0 if an entry was moved, 1 if not
- */
-int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn 
*order){
-    HTEntry *new_entry = NULL, *prev = NULL, *entry = NULL;
-    HTBucket *bucket;
-    int err = 1;
-
-    bucket = get_bucket(table, hashcode);
-    new_entry = bucket->head;
-    if(!new_entry || !new_entry->next) goto exit;
-    for(entry = new_entry->next; entry; prev = entry, entry = entry->next){
-        if(order(new_entry, entry) <= 0) break;
-    }
-    if(prev){
-        err = 0;
-        bucket->head = new_entry->next; 
-        new_entry->next = entry;
-        prev->next = new_entry;
-    }
-  exit:
-    return err;
-}
-
-/** Add an entry to a hashtable.
- * The entry is added to the bucket for its key's hashcode.
- *
- * @param table to insert in
- * @param key to add an entry for
- * @param value to add an entry for
- * @return entry on success, 0 on failure
- */
-inline HTEntry * HashTable_add(HashTable *table, void *key, void *value){
-    return HashTable_add_entry(table, HashTable_key_hash(table, key), key, 
value);
-}
-
-/** Remove entries satisfying a test from the bucket for the
- * given hashcode. 
- *
- * @param table to remove from
- * @param hashcode indicates the bucket
- * @param test_fn test to apply to elements
- * @param arg first argument to calls to test_fn
- * @return number of entries removed
- */
-inline int HashTable_remove_entry(HashTable *table, Hashcode hashcode,
-                                 TableTestFn *test_fn, TableArg arg){
-    HTBucket *bucket;
-    HTEntry *entry, *prev = NULL, *next;
-    int removed_count = 0;
-
-    bucket = get_bucket(table, hashcode);
-    for(entry = bucket->head; entry; entry = next){
-        next = entry->next;
-        if(test_fn(arg, table, entry)){
-            if(prev){
-                prev->next = next;
-            } else {
-                bucket->head = next;
-            }
-            bucket->count--;
-            table->entry_count--;
-            removed_count++;
-            HashTable_free_entry(table, entry);
-            entry = NULL;
-        }
-        prev = entry;
-    }
-    return removed_count;
-}
-
-/** Remove entries with a given key. 
- *
- * @param table to remove from
- * @param key of entries to remove
- * @return number of entries removed
- */
-inline int HashTable_remove(HashTable *table, void *key){
-    Hashcode hashcode;
-    HTBucket *bucket;
-    HTEntry *entry, *prev = NULL, *next;
-    int removed_count = 0;
-
-    hashcode = HashTable_key_hash(table, key);
-    bucket = get_bucket(table, hashcode);
-    for(entry = bucket->head; entry; entry = next){
-        next = entry->next;
-        if(HashTable_key_equal(table, key, entry->key)){
-            if(prev){
-                prev->next = next;
-            } else {
-                bucket->head = next;
-            }
-            bucket->count--;
-            table->entry_count--;
-            removed_count++;
-            HashTable_free_entry(table, entry);
-            entry = NULL;
-        }
-        prev = entry;
-    }
-    return removed_count;
-}
-
-/** Remove (and free) all the entries in a bucket.
- *
- * @param bucket to clear
- */
-static inline void bucket_clear(HashTable *table, HTBucket *bucket){
-    HTEntry *entry, *next;
-
-    for(entry = bucket->head; entry; entry = next){
-        next = entry->next;
-        HashTable_free_entry(table, entry);
-    }
-    bucket->head = NULL;
-    table->entry_count -= bucket->count;
-    bucket->count = 0;
-}
-
-/** Remove (and free) all the entries in a table.
- *
- * @param table to clear
- */
-void HashTable_clear(HashTable *table){
-    int i, n = table->buckets_n;
-
-    for(i = 0; i < n; i++){
-        bucket_clear(table, table->buckets + i);
-    }
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/hash_table.h
--- a/tools/vnet/libxutil/hash_table.h  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_HASH_TABLE_H_
-#define _XUTIL_HASH_TABLE_H_
-
-#include "iostream.h"
-#include "sys_string.h"
-
-typedef unsigned long Hashcode;
-
-/** Type used to pass parameters to table functions. */
-typedef union TableArg {
-    unsigned long ul;
-    void *ptr;
-} TableArg;
-
-/** An entry in a bucket list. */
-typedef struct HTEntry {
-    /** Hashcode of the entry's key. */
-    Hashcode hashcode;
-    /** The key for this entry. */
-    void *key;
-    /** The value in this entry. */
-    void *value;
-    /** The next entry in the list. */
-    struct HTEntry *next;
-} HTEntry;
-
-/** A bucket in a rule table. */
-typedef struct HTBucket {
-    /** Number of entries in the bucket. */
-    int count;
-    /** First entry in the bucket (may be null). */
-    HTEntry *head;
-} HTBucket;
-
-/** Default number of buckets in a hash table.
- * You want enough buckets so the lists in the buckets will typically be short.
- * If the hash function is good it doesn't matter whether the number of
- * buckets is prime or not.
- */
-//#define HT_BUCKETS_N 1
-//#define HT_BUCKETS_N 3
-//#define HT_BUCKETS_N 7
-//#define HT_BUCKETS_N 17
-//#define HT_BUCKETS_N 97
-//#define HT_BUCKETS_N 211
-//#define HT_BUCKETS_N 401
-#define HT_BUCKETS_N 1021
-
-typedef struct HashTable HashTable;
-
-/** Type for a function used to select table entries. */
-typedef int TableTestFn(TableArg arg, HashTable *table, HTEntry *entry);
-
-/** Type for a function to map over table entries. */
-typedef int TableMapFn(TableArg arg, HashTable *table, HTEntry *entry);
-
-/** Type for a function to free table entries. */
-typedef void TableFreeFn(HashTable *table, HTEntry *entry);
-
-/** Type for a function to hash table keys. */
-typedef Hashcode TableHashFn(void *key);
-
-/** Type for a function to test table keys for equality. */
-typedef int TableEqualFn(void *key1, void *key2);
-
-/** Type for a function to order table entries. */
-typedef int TableOrderFn(HTEntry *e1, HTEntry *e2);
-
-/** General hash table.
- * A hash table with a list in each bucket.
- * Functions can be supplied for freeing entries, hashing keys, and comparing 
keys.
- * These all default to 0, when default behaviour treating keys as integers is 
used.
- */
-struct HashTable {
-    /** Array of buckets, each with its own list. */
-    HTBucket *buckets;
-    /** Number of buckets in the bucket array. */
-    int buckets_n;
-    /** Number of entries in the table. */
-    int entry_count;
-    unsigned long key_size;
-    /** Function to free keys and values in entries. */
-    TableFreeFn *entry_free_fn;
-    /** Function to hash keys. */
-    TableHashFn *key_hash_fn;
-    /** Function to compare keys for equality. */
-    TableEqualFn *key_equal_fn;
-    /** Place for the user of the table to hang extra data. */
-    void *user_data;
-};
-
-extern HashTable *HashTable_new(int bucket_n);
-extern void HashTable_free(HashTable *table);
-extern HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value);
-extern void HTEntry_free(HTEntry *entry);
-extern int HashTable_set_bucket_n(HashTable *table, int bucket_n);
-extern void HashTable_clear(HashTable *table);
-extern HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void 
*key, void *value);
-extern HTEntry * HashTable_get_entry(HashTable *table, void *key);
-extern HTEntry * HashTable_add(HashTable *table, void *key, void *value);
-extern void * HashTable_get(HashTable *table, void *key);
-extern int HashTable_remove(HashTable *table, void *key);
-extern HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode,
-                                      TableTestFn *test_fn, TableArg arg);
-extern int HashTable_remove_entry(HashTable *table, Hashcode hashcode,
-                                   TableTestFn *test_fn, TableArg arg);
-extern void HashTable_print(HashTable *table, IOStream *out);
-extern int HashTable_set_buckets_n(HashTable *table, int buckets_n);
-extern int HashTable_adjust(HashTable *table, int buckets_min);
-
-extern int HashTable_order_bucket(HashTable *table, Hashcode hashcode, 
TableOrderFn *order);
-
-typedef unsigned long ub4;
-typedef unsigned char ub1;
-
-extern ub4 hash(const ub1 *k, ub4 length, ub4 initval);
-
-/** Hash some bytes starting with a given hashcode.
- *
- * @param h initial hashcode - use 0, a previous hash, or an arbitrary value
- * @param b bytes to hash
- * @param b_n number of bytes to hash
- * @return hashcode
- */
-static inline Hashcode hash_hvoid(Hashcode h, const void *b, unsigned b_n){
-    return hash(b, b_n, h);
-}
-
-/** Hash a string (null-terminated).
- *
- * @param s input to hash
- * @return hashcode
- */
-static inline Hashcode hash_string(char *s){
-    return (s ? hash_hvoid(0, s, strlen(s)) : 0);
-}
-
-/** Macro to declare variables for HashTable_for_each() to use.
- *
- * @param entry variable that is set to entries in the table
- */
-#define HashTable_for_decl(entry) \
-  HashTable *_var_table; \
-  HTBucket *_var_bucket; \
-  HTBucket *_var_end; \
-  HTEntry *_var_next; \
-  HTEntry *entry
-
-/** Macro to iterate over the entries in a hashtable.
- * Must be in a scope where HashTable_for_decl() has been used to declare
- * variables for it to use.
- * The variable 'entry' is iterated over entries in the table.
- * The code produced is syntactically a loop, so it must be followed by
- * a loop body, typically some statements in braces:
- * HashTable_for_each(entry, table){ ...loop body... }
- *
- * HashTable_for_each() and HashTable_for_decl() cannot be used for nested
- * loops as variables will clash.
- *
- * @note The simplest way to code a direct loop over the entries in a hashtable
- * is to use a loop over the buckets, with a nested loop over the entries
- * in a bucket. Using this approach in a macro means the macro contains
- * an opening brace, and calls to it must be followed by 2 braces!
- * To avoid this the code has been restructured so that it is a for loop.
- * So that statements could be used in the test expression of the for loop,
- * we have used the gcc statement expression extension ({ ... }).
- *
- * @param entry variable to iterate over the entries
- * @param table to iterate over (non-null)
- */
-#define HashTable_for_each(entry, table) \
-  _var_table = table; \
-  _var_bucket = _var_table->buckets; \
-  _var_end = _var_bucket + _var_table->buckets_n; \
-  for(entry=0, _var_next=0; \
-      ({ if(_var_next){ \
-             entry = _var_next; \
-             _var_next = entry->next; \
-          } else { \
-             while(_var_bucket < _var_end){ \
-                 entry = _var_bucket->head; \
-                 _var_bucket++; \
-                 if(entry){ \
-                      _var_next = entry->next; \
-                      break; \
-                 } \
-             } \
-          }; \
-         entry; }); \
-      entry = _var_next )
-
-/** Map a function over the entries in a table.
- * Mapping stops when the function returns a non-zero value.
- * Uses the gcc statement expression extension ({ ... }).
- *
- * @param table to map over
- * @param fn function to apply to entries
- * @param arg first argument to call the function with
- * @return 0 if fn always returned 0, first non-zero value otherwise
- */
-#define HashTable_map(table, fn, arg) \
-  ({ HashTable_for_decl(_var_entry); \
-    TableArg _var_arg = arg; \
-    int _var_value = 0; \
-    HashTable_for_each(_var_entry, table){ \
-        if((_var_value = fn(_var_arg, _var_table, _var_entry))) break; \
-    } \
-    _var_value; })
-
-/** Cast x to the type for a key or value in a hash table.
- * This avoids compiler warnings when using short integers
- * as keys or values (especially on 64-bit platforms).
- */
-#define HKEY(x) ((void*)(unsigned long)(x))
-
-/** Cast x from the type for a key or value in a hash table.
- * to an unsigned long. This avoids compiler warnings when using
- * short integers as keys or values (especially on 64-bit platforms).
- */
-#define HVAL(x) ((unsigned long)(x))
-
-#endif /* !_XUTIL_HASH_TABLE_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/iostream.c
--- a/tools/vnet/libxutil/iostream.c    Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "iostream.h"
-#include "sys_string.h"
-
-/** Print on a stream, like vfprintf().
- *
- * @param stream to print to
- * @param format for the print (as fprintf())
- * @param args arguments to print
- * @return result code from the print
- */
-int IOStream_vprint(IOStream *stream, const char *format, va_list args){
-  char buffer[1024];
-  int k = sizeof(buffer), n;
-
-  n = vsnprintf(buffer, k, (char*)format, args);
-  if(n < 0 || n > k ){
-      n = k;
-  }
-  n = IOStream_write(stream, buffer, n);
-  return n;
-}
-
-/** Print on a stream, like fprintf().
- *
- * @param stream to print to
- * @param format for the print (as fprintf())
- * @return result code from the print
- */
-int IOStream_print(IOStream *stream, const char *format, ...){
-  va_list args;
-  int result = -1;
-
-  va_start(args, format);
-  result = IOStream_vprint(stream, format, args);
-  va_end(args);
-  return result;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/iostream.h
--- a/tools/vnet/libxutil/iostream.h    Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_IOSTREAM_H_
-#define _XUTIL_IOSTREAM_H_
-
-#include <stdarg.h>
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#else
-#include <errno.h>
-#include <stdint.h>
-#include <stddef.h>
-#endif
-
-#include "allocate.h"
-
-/** End of input return value (for getc). */
-#define IOSTREAM_EOF -1
-
-/** An input/output abstraction.
- */
-typedef struct IOStream IOStream;
-
-/** Record of the functions to use for operations on an
- * IOStream implementation.
- */
-typedef struct IOMethods {
-    /** Read function.  Called with the user data, buffer to read into
-     * and number of bytes to read.  Must return number of bytes read
-     * on success, less than zero on error.
-     */
-    int (*read)(IOStream *stream, void *buf, size_t n);
-
-    /** Write function. Called with user data, buffer to write and
-     * number of bytes to write. Must return number of bytes written on
-     * success, less than zero otherwise.
-     */
-    int (*write)(IOStream *stream, const void *buf, size_t n);
-
-    int (*flush)(IOStream *s);
-
-    int (*error)(IOStream *s);
-
-    int (*close)(IOStream *s);
-
-    void (*free)(IOStream *s);
-
-    void (*lock)(IOStream *s);
-    void (*unlock)(IOStream *s);
-
-} IOMethods;
-
-/** Abstract i/o object.
- */
-struct IOStream {
-    /** Methods to use to implement operations. */
-    const IOMethods *methods;
-    /** Private state for the implementation. */
-    const void *data;
-    /** Flag indicating whether the stream is closed. */
-    int closed;
-    /** Number of bytes written. */
-    int written;
-    /** Number of bytes read. */
-    int read;
-    /** Flag indicating whether not to free when closed. */
-    int nofree;
-};
-
-
-/** IOStream version of stdin. */
-extern IOStream *iostdin;
-
-/** IOStream version of stdout, */
-extern IOStream *iostdout;
-
-/** IOStream version of stderr. */
-extern IOStream *iostderr;
-
-extern int IOStream_print(IOStream *io, const char *format, ...);
-extern int IOStream_vprint(IOStream *io, const char *format, va_list args);
-
-/** Read from a stream.
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to read
- * @return if ok, number of bytes read, otherwise negative error code
- */
-static inline int IOStream_read(IOStream *stream, void *buf, size_t n){
-    int result;
-    if(stream->closed){
-        result = -EIO;
-        goto exit;
-    }
-    if(!stream->methods || !stream->methods->read){
-        result = -EINVAL;
-        goto exit;
-    }
-    result = (stream->methods->read)(stream, buf, n);
-    if(result > 0){
-        stream->read += result;
-    }
-  exit:
-    return result;
-}
-
-/** Write to a stream.
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to write
- * @return if ok, number of bytes written, otherwise negative error code
- */
-static inline int IOStream_write(IOStream *stream, const void *buf, size_t n){
-    int result;
-    if(stream->closed){
-        result = -EIO;
-        goto exit;
-    }
-    if(!stream->methods || !stream->methods->write){
-        result = -EINVAL;
-        goto exit;
-    }
-    result = (stream->methods->write)(stream, buf, n);
-    if(result > 0){
-        stream->written += result;
-    }
-  exit:
-    return result;
-}
-
-/** Flush the stream.
- *
- * @param stream stream
- * @return 0 on success, negative error code otherwise
- */
-static inline int IOStream_flush(IOStream *stream){
-    int result = 0;
-    if(stream->closed){
-        result = -EIO;
-    } else if(stream->methods->flush){
-        result = (stream->methods->flush)(stream);
-    }
-    return result;
-}
-
-/** Check whether the stream has an error.
- *
- * @param stream to check
- * @return 1 for error, 0 otherwise
- */
-static inline int IOStream_error(IOStream *stream){
-    int err = 0;
-    if(stream->methods && stream->methods->error){
-       err = (stream->methods->error)(stream);
-    }
-    return err;
-}
-
-/** Close the stream.
- *
- * @param stream to close
- * @return 0 on success, negative error code otherwise
- */
-static inline int IOStream_close(IOStream *stream){
-    int err = 0;
-    if(!stream || stream->closed){
-        err = -EIO;
-        goto exit;
-    }
-    if(stream->methods && stream->methods->close){
-        err = (stream->methods->close)(stream);
-        stream->closed = 1;
-    }
-    if(stream->nofree) goto exit;
-    if(stream->methods && stream->methods->free){
-        (stream->methods->free)(stream);
-    }
-    *stream = (IOStream){};
-    deallocate(stream);
-  exit:
-    return err;
-}
-
-/** Test if the stream has been closed.
- *
- * @param stream to check
- * @return 1 if closed, 0 otherwise
- */
-static inline int IOStream_is_closed(IOStream *stream){
-    return stream->closed;
-}
-
-/** Print a character to a stream, like fputc().
- *
- * @param stream to print to
- * @param c character to print
- * @return result code from the print
- */
-static inline int IOStream_putc(IOStream *stream, int c){
-    int err;
-    unsigned char b = (unsigned char)c;
-    err = IOStream_write(stream, &b, 1);
-    if(err < 1){
-        err = IOSTREAM_EOF;
-    } else {
-        err = b;
-    }
-    return err;
-}
-
-/** Read from a stream, like fgetc().
- *
- * @param stream to read from
- * @return IOSTREAM_EOF on error, character read otherwise
- */
-static inline int IOStream_getc(IOStream *stream){
-    int err, rc;
-    unsigned char b;
-
-    err = IOStream_read(stream, &b, 1);
-    if(err < 1){
-        rc = IOSTREAM_EOF;
-    } else {
-        rc = b;
-    }
-    return rc;
-}
-
-/** Get number of bytes read.
- *
- * @param stream to get from
- * @return number of bytes read
- */
-static inline int IOStream_get_read(IOStream *stream){
-    return stream->read;
-}
-
-/** Get number of bytes written.
- *
- * @param stream to get from
- * @return number of bytes written
- */
-static inline int IOStream_get_written(IOStream *stream){
-    return stream->written;
-}
-
-
-#endif /* ! _XUTIL_IOSTREAM_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/kernel_stream.c
--- a/tools/vnet/libxutil/kernel_stream.c       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * An IOStream implementation using printk() for output.
- * Input is not implemented.
- */
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-
-#include "kernel_stream.h"
-#include "allocate.h"
-
-/** Number of characters in the output buffer.
- * The kernel uses 1024 for printk, so that should suffice.
- */
-#define BUF_N 1024
-
-/** State for a kernel stream. */
-typedef struct KernelData {
-    /** Stream lock. We need a lock to serialize access to the stream. */
-    spinlock_t lock;
-    /** Saved flags for locking. */
-    unsigned long flags;
-    /** Size of the output buffer. */
-    int buf_n;
-    /** Output buffer. */
-    char buf[BUF_N];
-} KernelData;
-
-static int kernel_write(IOStream *s, const void *msg, size_t n);
-static void kernel_free(IOStream *s);
-static void kernel_stream_lock(IOStream *s);
-static void kernel_stream_unlock(IOStream *s);
-
-/** Methods for a kernel stream. Output only. */
-static const IOMethods kernel_methods = {
-    write:  kernel_write,
-    free:   kernel_free,
-    lock:   kernel_stream_lock,
-    unlock: kernel_stream_unlock,
-};
-
-/** Shared state for kernel streams.
- * All implementations write using printk, so we can use
- * shared state and avoid allocating it.
- */
-static const KernelData kernel_data = {
-    lock:  SPIN_LOCK_UNLOCKED,
-    flags: 0,
-    buf_n: BUF_N,
-};
-
-/** Stream for kernel printk. */
-static IOStream iokernel = {
-    methods: &kernel_methods,
-    data:    &kernel_data,
-    nofree:  1,
-};
-
-/** Stream for kernel printk. */
-IOStream *iostdout = &iokernel;
-
-/** Stream for kernel printk. */
-IOStream *iostdin = &iokernel;
-
-/** Stream for kernel printk. */
-IOStream *iostderr = &iokernel;
-
-/** Get an output-only stream implementation using
- * printk(). The stream uses static storage, and must not be freed.
- *
- * @return kernel stream
- */
-IOStream get_stream_kernel(void){
-    return iokernel;
-}
-
-/** Obtain the lock on the stream state.
- *
- * @param kdata stream state
- */
-static inline void KernelData_lock(KernelData *kdata){
-    spin_lock_irqsave(&kdata->lock, kdata->flags);
-}
-
-/** Release the lock on the stream state.
- *
- * @param kdata stream state
- */
-static inline void KernelData_unlock(KernelData *kdata){
-    spin_unlock_irqrestore(&kdata->lock, kdata->flags);
-}
-
-/** Get the stream state.
- *
- * @param s kernel stream
- * @return stream state
- */
-static inline KernelData *get_kernel_data(IOStream *s){
-    return (KernelData*)s->data;
-}
-
-/** Obtain the lock on the stream state.
- *
- * @param s stream
- */
-void kernel_stream_lock(IOStream *s){
-    KernelData_lock(get_kernel_data(s));
-}
-
-/** Release the lock on the stream state.
- *
- * @param s stream
- */
-void kernel_stream_unlock(IOStream *s){
-    KernelData_unlock(get_kernel_data(s));
-}
-
-/** Write to a kernel stream.
- *
- * @param stream kernel stream
- * @param format print format
- * @param args print arguments
- * @return result of the print
- */
-static int kernel_write(IOStream *stream, const void *buf, size_t n){
-    KernelData *kdata = get_kernel_data(stream);
-    int k;
-    k = kdata->buf_n - 1;
-    if(n < k) k = n;
-    memcpy(kdata->buf, buf, k);
-    kdata->buf[k] = '\0';
-    printk(kdata->buf);
-    return k;
-}
-
-/** Free a kernel stream.
- * Frees the internal state of the stream.
- * Do not call this unless the stream was dynamically allocated.
- * Do not call this on a stream returned from get_stream_kernel().
- *
- * @param io stream to free
- */
-static void kernel_free(IOStream *io){
-    KernelData *kdata;
-    if(io == &iokernel) return;
-    kdata = get_kernel_data(io);
-    memset(kdata, 0, sizeof(*kdata));
-    deallocate(kdata);
-}
-#endif /* __KERNEL__ */
-
-
-
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/kernel_stream.h
--- a/tools/vnet/libxutil/kernel_stream.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_KERNEL_STREAM_H_
-#define _XUTIL_KERNEL_STREAM_H_
-
-#ifdef __KERNEL__
-#include "iostream.h"
-
-extern IOStream get_stream_kernel(void);
-#define get_stream_stdout get_stream_kernel
-
-#endif /* __KERNEL__ */
-#endif /* !_XUTIL_KERNEL_STREAM_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/lexis.c
--- a/tools/vnet/libxutil/lexis.c       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-/** @file
- * Lexical analysis.
- */
-
-#include "sys_string.h"
-#include "lexis.h"
-#include <errno.h>
-
-/** Check if a value lies in a (closed) range.
- *
- * @param x value to test
- * @param lo low end of the range
- * @param hi high end of the range
- * @return 1 if x is in the interval [lo, hi], 0 otherwise
- */
-inline static int in_range(int x, int lo, int hi){
-    return (lo <= x) && (x <= hi);
-}
-
-/** Determine if a string is an (unsigned) decimal number.
- * 
- * @param s pointer to characters to test
- * @param n length of string
- * @return 1 if s is a decimal number, 0 otherwise.
- */
-int is_decimal_number(const char *s, int n){
-    int i;
-    if(n <= 0)return 0;
-    for(i = 0; i < n; i++){
-        if(!in_decimal_digit_class(s[i])) return 0;
-    }
-    return 1;
-}
-
-/** Determine if a string is a hex number.
- * Hex numbers are 0, or start with 0x or 0X followed
- * by a non-zero number of hex digits (0-9,a-f,A-F).
- * 
- * @param s pointer to characters to test
- * @param n length of string
- * @return 1 if s is a hex number, 0 otherwise.
- */
-int is_hex_number(const char *s, int n){
-    int i;
-    if(n <= 0) return 0;
-    if(n == 1){
-        return s[0]=='0';
-    }
-    if(n <= 3) return 0;
-    if(s[0] != '0' || (s[1] != 'x' && s[1] != 'X')) return 0;
-    for(i = 2; i < n; i++){
-        if(!in_hex_digit_class(s[i])) return 0;
-    }
-    return 1;
-}
-
-/** Test if a string matches a keyword.
- * The comparison is case-insensitive.
- * The comparison fails if either argument is null.
- *
- * @param s string
- * @param k keyword
- * @return 1 if they match, 0 otherwise
- */
-int is_keyword(const char *s, const char *k){
-  return s && k && !strcasecmp(s, k);
-}
-
-/** Test if a string matches a character.
- *
- * @param s string
- * @param c character (non-null)
- * @return 1 if s contains exactly c, 0 otherwise
- */
-int is_keychar(const char *s, char c){
-  return c && (s[0] == c) && !s[1];
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/lexis.h
--- a/tools/vnet/libxutil/lexis.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _XUTIL_LEXIS_H_
-#define _XUTIL_LEXIS_H_
-
-#include "sys_string.h"
-
-#ifdef __KERNEL__
-#  include <linux/ctype.h>
-#else
-#  include <ctype.h>
-#endif
-
-/** @file
- * Lexical analysis.
- */
-
-/** Class of characters treated as space. */
-#define space_class ((char []){ '\n', '\r', '\t', ' ', '\f' , 0 })
-
-/** Class of separator characters. */
-#define sep_class "{}()<>[]!;\"'"
-
-#define comment_class "#"
-
-/** Determine if a character is in a given class.
- * 
- * @param c character to test
- * @param s null-terminated string of characters in the class
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_class(int c, const char *s){
-  return s && (strchr(s, c) != 0);
-}
-
-/** Determine if a character is in the space class.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_space_class(int c){
-    return in_class(c, space_class);
-}
-
-static inline int in_comment_class(int c){
-    return in_class(c, comment_class);
-}
-
-/** Determine if a character is in the separator class.
- * Separator characters terminate tokens, and do not need space
- * to separate them.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_sep_class(int c){
-    return in_class(c, sep_class);
-}
-
-/** Determine if a character is in the alpha class.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_alpha_class(int c){
-    return isalpha(c);
-}
-
-/** Determine if a character is in the octal digit class.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_octal_digit_class(int c){
-    return '0' <= c && c <= '7';
-}
-
-/** Determine if a character is in the decimal digit class.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_decimal_digit_class(int c){
-    return isdigit(c);
-}
-
-/** Determine if a character is in the hex digit class.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_hex_digit_class(int c){
-    return isdigit(c) || in_class(c, "abcdefABCDEF");
-}
-
-
-static inline int in_string_quote_class(int c){
-    return in_class(c, "'\"");
-}
-
-static inline int in_printable_class(int c){
-    return ('A' <= c && c <= 'Z')
-        || ('a' <= c && c <= 'z')
-        || ('0' <= c && c <= '9')
-        || in_class(c, "!$%&*+,-./:;<=>?@^_`{|}~");
-}
-
-extern int is_decimal_number(const char *s, int n);
-extern int is_hex_number(const char *s, int n);
-extern int is_keyword(const char *s, const char *k);
-extern int is_keychar(const char *s, char c);
-
-#endif /* !_XUTIL_LEXIS_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/mem_stream.c
--- a/tools/vnet/libxutil/mem_stream.c  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * IOStream subtype for input and output to memory.
- * Usable from user or kernel code (with __KERNEL__ defined).
- */
-
-#include "sys_string.h"
-#include "mem_stream.h"
-#include "allocate.h"
-
-/** Internal state for a memory stream.
- *
- * The memory stream buffer is treated as a circular buffer.
- * The lo and hi markers indicate positions in the buffer, but
- * are not reduced modulo the buffer size. This avoids the ambiguity
- * between a full and empty buffer when using reduced values.
- *
- * If x is a marker, then buf + (x % buf_n) is the corresponding
- * pointer into the buffer. When the buffer is empty, lo == hi,
- * and the corresponding pointers are equal. When the buffer is
- * full, hi == lo + buf_n, and the corresponding pointers
- * are also equal.
- *
- * Data is written after the high pointer and read from the lo pointer.
- * The value hi - lo is the number of bytes in the buffer.
- */
-typedef struct MemData {
-    /** Data buffer. */
-    char *buf;
-    /** Low marker - start of readable area. */
-    unsigned long lo;
-    /** High marker - end of readable area, start of writeable area. */
-    unsigned long hi;
-    /** Size of the buffer. */
-    unsigned int buf_n;
-    /** Maximum size the buffer can grow to. */
-    unsigned int buf_max;
-    /** Error code. */
-    int err;
-} MemData;
-
-/** Get number of bytes available to read.
- *
- * @param data mem stream
- * @return bytes
- */
-static inline int mem_len(struct MemData *data){
-    return data->hi - data->lo;
-}
-
-/** Get available space left in the buffer.
- *
- * @param data mem stream
- * @return bytes
- */
-static inline int mem_room(struct MemData *data){
-    return data->buf_n - mem_len(data);
-}
-
-/** Get a pointer to the start of the data in the buffer.
- *
- * @param data mem stream
- * @return lo pointer
- */
-static inline char * mem_lo(struct MemData *data){
-    return data->buf + (data->lo % data->buf_n);
-}
-
-/** Get a pointer to the end of the data in the buffer.
- *
- * @param data mem stream
- * @return hi pointer
- */
-static inline char * mem_hi(struct MemData *data){
-    return data->buf + (data->hi % data->buf_n);
-}
-
-/** Get a pointer to the end of the buffer.
- *
- * @param data mem stream
- * @return end pointer
- */
-static inline char * mem_end(struct MemData *data){
-    return data->buf + data->buf_n;
-}
-
-static int mem_error(IOStream *io);
-static int mem_close(IOStream *io);
-static void mem_free(IOStream *io);
-static int mem_write(IOStream *io, const void *msg, size_t n);
-static int mem_read(IOStream *io, void *buf, size_t n);
-
-/** Minimum delta used to increment the buffer. */
-static int delta_min = 256;
-
-/** Methods for a memory stream. */
-static IOMethods mem_methods = {
-    read:  mem_read,
-    write: mem_write,
-    error: mem_error,
-    close: mem_close,
-    free:  mem_free,
-};
-
-/** Get the memory stream state.
- *
- * @param io memory stream
- * @return state
- */
-static inline MemData *get_mem_data(IOStream *io){
-    return (MemData*)io->data;
-}
-
-/** Get the number of bytes available to read.
- *
- * @param io memory stream
- * @return number of bytes
- */
-int mem_stream_avail(IOStream *io){
-    MemData *data = get_mem_data(io);
-    return (data->err ? -data->err : mem_len(data));
-}
-
-/** Copy bytes from a memory stream into a buffer.
- *
- * @param data mem stream
- * @param buf buffer
- * @param n number of bytes to copy
- */
-static void mem_get(MemData *data, char *buf, size_t n){
-    char *start = mem_lo(data);
-    char *end = mem_end(data);
-    if (start + n < end) {
-        memcpy(buf, start, n);
-    } else {
-        int k = end - start;
-        memcpy(buf, start, k);
-        memcpy(buf + k, data->buf, n - k);
-    }
-}
-
-/** Copy bytes from a buffer into a memory stream.
- *
- * @param data mem stream
- * @param buf buffer
- * @param n number of bytes to copy
- */
-static void mem_put(MemData *data, const char *buf, size_t n){
-    char *start = mem_hi(data);
-    char *end = mem_end(data);
-    if(start + n < end){
-        memcpy(start, buf, n);
-    } else {
-        int k = end - start;
-        memcpy(start, buf, k);
-        memcpy(data->buf, buf + k, n - k);
-    }
-}
-
-/** Expand the buffer used by a memory stream.
- *
- * @param data mem stream
- * @param extra number of bytes to expand by
- * @return 0 on success, negative error otherwise
- */
-static int mem_expand(MemData *data, size_t extra){
-    int err = -ENOMEM;
-    int delta = (extra < delta_min ? delta_min : extra);
-    int buf_n;
-    char *buf;
-    if(data->buf_max > 0){
-        int delta_max = data->buf_max - data->buf_n;
-        if(delta > delta_max){
-            delta = extra;
-            if(delta > delta_max) goto exit;
-        }
-    }
-    buf_n = data->buf_n + delta;
-    buf = allocate(buf_n);
-    if(!buf) goto exit;
-    mem_get(data, buf, mem_len(data));
-    data->hi = mem_len(data);
-    data->lo = 0;
-    deallocate(data->buf);
-    data->buf = buf;
-    data->buf_n = buf_n;
-    err = 0;
-  exit:
-    if(err){
-        data->err = -err;
-    }
-    return err;
-}
-
-/** Write bytes from a buffer into a memory stream.
- * The internal buffer is expanded as needed to hold the data,
- * up to the stream maximum (if specified). If the buffer cannot
- * be expanded -ENOMEM is returned.
- *
- * @param io mem stream
- * @param buf buffer
- * @param n number of bytes to write
- * @return number of bytes written on success, negative error code otherwise
- */
-static int mem_write(IOStream *io, const void *msg, size_t n){
-    int room;
-    MemData *data = get_mem_data(io);
-    if(data->err) return -data->err;
-    room = mem_room(data);
-    if(n > room){
-        int err = mem_expand(data, n - room);
-        if(err) return err;
-    }
-    mem_put(data, msg, n);
-    data->hi += n;
-    return n;
-}
-
-/** Read bytes from a memory stream into a buffer.
- *
- * @param io mem stream
- * @param buf buffer
- * @param n maximum number of bytes to read
- * @return number of bytes read on success, negative error code otherwise
- */
-static int mem_read(IOStream *io, void *buf, size_t n){
-    int k;
-    MemData *data = get_mem_data(io);
-    if(data->err) return -data->err;
-    k = mem_len(data);
-    if(n > k){
-        n = k;
-    }
-    mem_get(data, buf, n);
-    data->lo += n;
-    return n;
-}
-
-/** Test if a memory stream has an error.
- *
- * @param io mem stream
- * @return 0 if ok, error code otherwise
- */
-static int mem_error(IOStream *io){
-    MemData *data = get_mem_data(io);
-    return data->err;
-}
-
-/** Close a memory stream.
- *
- * @param io mem stream
- * @return 0
- */
-static int mem_close(IOStream *io){
-    MemData *data = get_mem_data(io);
-    if(!data->err){
-        data->err = ENOTCONN;
-    }
-    return 0;
-}
-
-/** Free a memory stream.
- *
- * @param io mem stream
- */
-static void mem_free(IOStream *io){
-    MemData *data = get_mem_data(io);
-    deallocate(data->buf);
-    memzero(data, sizeof(*data));
-    deallocate(data);
-}
-
-/** Allocate and initialise a memory stream.
- *
- * @param buf_n initial buffer size (0 means default)
- * @param buf_max maximum buffer size (0 means no max)
- * @return new stream (free using IOStream_close)
- */
-IOStream *mem_stream_new_size(size_t buf_n, size_t buf_max){
-    int err = -ENOMEM;
-    MemData *data = ALLOCATE(MemData);
-    IOStream *io = NULL;
-    if(!data) goto exit;
-    io = ALLOCATE(IOStream);
-    if(!io) goto exit;
-    if(buf_n <= delta_min){
-        buf_n = delta_min;
-    }
-    if(buf_max > 0 && buf_max < buf_n){
-        buf_max = buf_n;
-    }
-    data->buf = allocate(buf_n);
-    if(!data->buf) goto exit;
-    data->buf_n = buf_n;
-    data->buf_max = buf_max;
-    io->methods = &mem_methods;
-    io->data = data;
-    io->nofree = 0;
-    err = 0;
-  exit:
-    if(err){
-        deallocate(data);
-        deallocate(io);
-        io = NULL;
-    }
-    return io;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/mem_stream.h
--- a/tools/vnet/libxutil/mem_stream.h  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_MEM_STREAM_H_
-#define _XUTIL_MEM_STREAM_H_
-
-#include "iostream.h"
-
-extern IOStream *mem_stream_new_size(size_t buf_n, size_t buf_max);
-
-extern int mem_stream_avail(IOStream *io);
-
-static inline IOStream *mem_stream_new(void){
-    return mem_stream_new_size(0, 0);
-}
-
-#endif /* !_XUTIL_MEM_STREAM_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/socket_stream.c
--- a/tools/vnet/libxutil/socket_stream.c       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * An IOStream implementation using sockets.
- */
-#ifndef __KERNEL__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include "allocate.h"
-#include "socket_stream.h"
-
-#define MODULE_NAME "sock"
-#define DEBUG 0
-//#undef DEBUG
-#include "debug.h"
-
-static int socket_read(IOStream *s, void *buf, size_t n);
-static int socket_write(IOStream *s, const void *buf, size_t n);
-static int socket_error(IOStream *s);
-static int socket_close(IOStream *s);
-static void socket_free(IOStream *s);
-static int socket_flush(IOStream *s);
-
-/** Methods used by a socket IOStream. */
-static const IOMethods socket_methods = {
-    read:  socket_read,
-    write: socket_write,
-    error: socket_error,
-    close: socket_close,
-    free:  socket_free,
-    flush: socket_flush,
-};
-
-/** Get the socket data.
- * 
- * @param io socket stream
- * @return data
- */
-static inline SocketData * socket_data(IOStream *io){
-    return (SocketData *)io->data;
-}
-
-/** Test if a stream is a socket stream.
- *
- * @param io stream
- * @return 0 if a socket stream, -EINVAL if not
- */
-int socket_stream_check(IOStream *io){
-    return (io && io->methods == &socket_methods ? 0 : -EINVAL);
-}
-
-/** Get the data for a socket stream.
- *
- * @param io stream
- * @param data return value for the data
- * @return 0 if a socket stream, -EINVAL if not
- */
-int socket_stream_data(IOStream *io, SocketData **data){
-    int err = socket_stream_check(io);
-    if(err){
-        *data = NULL;
-    } else {
-        *data = socket_data(io);
-    }
-    return err;
-}
-
-/** Set the destination address for a socket stream.
- *
- * @param io stream
- * @param addr address
- * @return 0 if a socket stream, -EINVAL if not
- */
-int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr){
-    int err = 0;
-    SocketData *data = NULL;
-    err = socket_stream_data(io, &data);
-    if(!err){
-        data->daddr = *addr;
-    }
-    return err;
-}
-
-/** Set the send flags for a socket stream.
- *
- * @param io stream
- * @param flags flags
- * @return 0 if a socket stream, -EINVAL if not
- */
-int socket_stream_set_flags(IOStream *io, int flags){
-    int err = 0;
-    SocketData *data = NULL;
-    err = socket_stream_data(io, &data);
-    if(!err){
-        data->flags = flags;
-    }
-    return err;
-}
-
-/** Write to the underlying socket using sendto.
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to write
- * @return number of bytes written
- */
-static int socket_write(IOStream *s, const void *buf, size_t n){
-    SocketData *data = socket_data(s);
-    struct sockaddr *daddr = (struct sockaddr *)&data->daddr;
-    socklen_t daddr_n = sizeof(data->daddr);
-    int k;
-    dprintf("> sock=%d addr=%s:%d n=%d\n",
-            data->fd, inet_ntoa(data->daddr.sin_addr), 
ntohs(data->daddr.sin_port), n);
-    if(0){
-        struct sockaddr_in self = {};
-        socklen_t self_n;
-        getsockname(data->fd, (struct sockaddr *)&self, &self_n);
-        dprintf("> sockname sock=%d %s:%d\n",
-                data->fd, inet_ntoa(self.sin_addr), ntohs(self.sin_port));
-    }
-    k = sendto(data->fd, buf, n, data->flags, daddr, daddr_n);
-    dprintf("> sendto=%d\n", k);
-    return k;
-}
-
-/** Read from the underlying stream using recv();
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to read
- * @return number of bytes read
- */
-static int socket_read(IOStream *s, void *buf, size_t n){
-    SocketData *data = socket_data(s);
-    int k;
-    struct sockaddr *saddr = (struct sockaddr *)&data->saddr;
-    socklen_t saddr_n = sizeof(data->saddr);
-    k = recvfrom(data->fd, buf, n, data->flags, saddr, &saddr_n);
-    return k;
-}
-
-/** Flush the socket (no-op).
- *
- * @param s socket stream
- * @return 0 on success, error code otherwise
- */
-static int socket_flush(IOStream *s){
-    return 0;
-}
-
-/** Check if a socket stream has an error (no-op).
- *
- * @param s socket stream
- * @return 1 if has an error, 0 otherwise
- */
-static int socket_error(IOStream *s){
-    // Read SOL_SOCKET/SO_ERROR ?
-    return 0;
-}
-
-/** Close a socket stream.
- *
- * @param s socket stream to close
- * @return result of the close
- */
-static int socket_close(IOStream *s){
-    SocketData *data = socket_data(s);
-    return close(data->fd);
-}
-
-/** Free a socket stream.
- *
- * @param s socket stream
- */
-static void socket_free(IOStream *s){
-    SocketData *data = socket_data(s);
-    deallocate(data);
-}
-
-/** Create an IOStream for a socket.
- *
- * @param fd socket to wtap
- * @return new IOStream using fd for i/o
- */
-IOStream *socket_stream_new(int fd){
-    int err = -ENOMEM;
-    IOStream *io = NULL;
-    SocketData *data = NULL;
-
-    io = ALLOCATE(IOStream);
-    if(!io) goto exit;
-    io->methods = &socket_methods;
-    data = ALLOCATE(SocketData);
-    if(!data) goto exit;
-    io->data = data;
-    data->fd = fd;
-    data->buf_n = sizeof(data->buf);
-    err = 0;
-  exit:
-    if(err){
-        if(io){
-            if(data) deallocate(data);
-            deallocate(io);
-            io = NULL;
-        }
-    }
-    return io;
-}
-
-#endif
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/socket_stream.h
--- a/tools/vnet/libxutil/socket_stream.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XEN_LIB_SOCKET_STREAM_H_
-#define _XEN_LIB_SOCKET_STREAM_H_
-
-#ifndef __KERNEL__
-#include "iostream.h"
-#include <stdio.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/** Data associated with a socket stream. */
-typedef struct SocketData {
-    /** The socket file descriptor. */
-    int fd;
-    /** Source address from last read (recvfrom). */
-    struct sockaddr_in saddr;
-    /** Destination address for writes (sendto). */
-    struct sockaddr_in daddr;
-    /** Write flags (sendto). */
-    int flags;
-    /** Buffer size. */
-    int buf_n;
-    /** Buffer for formatted printing. */
-    char buf[1024];
-} SocketData;
-
-extern IOStream *socket_stream_new(int fd);
-extern int socket_stream_data(IOStream *io, SocketData **data);
-extern int socket_stream_check(IOStream *io);
-extern int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr);
-extern int socket_stream_set_flags(IOStream *io, int flags);
-
-#endif
-#endif /* !_XEN_LIB_SOCKET_STREAM_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/string_stream.c
--- a/tools/vnet/libxutil/string_stream.c       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * IOStream subtype for input and output to strings.
- * Usable from user or kernel code (with __KERNEL__ defined).
- */
-
-#include "sys_string.h"
-#include "string_stream.h"
-#include "allocate.h"
-
-static int string_error(IOStream *io);
-static int string_close(IOStream *io);
-static void string_free(IOStream *io);
-static int string_write(IOStream *io, const void *msg, size_t n);
-static int string_read(IOStream *io, void *buf, size_t n);
-
-/** Methods for a string stream. */
-static IOMethods string_methods = {
-    read:  string_read,
-    write: string_write,
-    error: string_error,
-    close: string_close,
-    free:  string_free,
-};
-
-/** Get the string stream state.
- *
- * @param io string stream
- * @return state
- */
-static inline StringData *get_string_data(IOStream *io){
-    return (StringData*)io->data;
-}
-
-static int string_write(IOStream *io, const void *msg, size_t n){
-    StringData *data = get_string_data(io);
-    int k;
-
-    k = data->end - data->out;
-    if(n > k) n = k;
-    memcpy(data->out, msg, n);
-    data->out += n;
-    return n;
-}
-
-static int string_read(IOStream *io, void *buf, size_t n){
-    StringData *data = get_string_data(io);
-    int k;
-
-    k = data->end - data->in;
-    if(n > k) n = k;
-    memcpy(buf, data->in, k);
-    data->in += n;
-    return n;
-}
-
-/** Test if a string stream has an error.
- *
- * @param io string stream
- * @return 0 if ok, error code otherwise
- */
-static int string_error(IOStream *io){
-    StringData *data = get_string_data(io);
-    return data->out == NULL;
-}
-
-/** Close a string stream.
- *
- * @param io string stream
- * @return 0
- */
-static int string_close(IOStream *io){
-    StringData *data = get_string_data(io);
-    data->in = NULL;
-    data->out = NULL;
-    return 0;
-}
-
-/** Free a string stream.
- * The stream state is freed, but the underlying string is not.
- *
- * @param io string stream
- */
-static void string_free(IOStream *io){
-    StringData *data = get_string_data(io);
-    memzero(data, sizeof(*data));
-    deallocate(data);
-}
-
-/** Get the methods to use for a string stream.
- *
- * @return methods
- */
-IOMethods *string_stream_get_methods(void){
-    return &string_methods;
-}
-
-/** Initialise a string stream, usually from static data.
- * If the stream and StringData should be freed when
- * the stream is closed, unset io->nofree.
- * The string is not freed on close.
- *
- * @param io address of IOStream to fill in
- * @param data address of StringData to fill in
- * @param s string to use
- * @param n length of the string
- */
-void string_stream_init(IOStream *io, StringData *data, char *s, int n){
-    if(data && io){
-        memzero(data, sizeof(*data));
-        data->string = (char*)s;
-        data->in = data->string;
-        data->out = data->string;
-        data->size = n;
-        data->end = data->string + n;
-        memzero(io, sizeof(*io));
-        io->methods = &string_methods;
-        io->data = data;
-        io->nofree = 1;
-    }
-}
-
-/** Allocate and initialise a string stream.
- * The stream is freed on close, but the string is not.
- *
- * @param s string to use
- * @param n length of the string
- * @return new stream (free using IOStream_free)
- */
-IOStream *string_stream_new(char *s, int n){
-    int ok = 0;
-    StringData *data = ALLOCATE(StringData);
-    IOStream *io = ALLOCATE(IOStream);
-    if(data && io){
-        ok = 1;
-        string_stream_init(io, data, s, n);
-        io->nofree = 0;
-    }
-    if(!ok){
-        deallocate(data);
-        deallocate(io);
-        io = NULL;
-    }
-    return io;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/string_stream.h
--- a/tools/vnet/libxutil/string_stream.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_STRING_STREAM_H_
-#define _XUTIL_STRING_STREAM_H_
-
-#include "iostream.h"
-
-/** Internal state for a string stream.
- * Exposed here so that string streams can be statically created, using
- * string_stream_init().
- */
-typedef struct {
-    /** The string used for input and ouput. */
-    char *string;
-    /** Output pointer. */
-    char *out;
-    /** Input pointer. */
-    char *in;
-    /** Length of string. */
-    int size;
-    /** End marker. */
-    char *end;
-} StringData;
-
-extern IOMethods *string_stream_get_methods(void);
-extern IOStream *string_stream_new(char *s, int n);
-extern void string_stream_init(IOStream *stream, StringData *data, char *s, 
int n);
-
-#endif /* !_XUTIL_STRING_STREAM_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/sxpr.c
--- a/tools/vnet/libxutil/sxpr.c        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1230 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <stdarg.h>
-#include "sys_string.h"
-#include "lexis.h"
-#include "sys_net.h"
-#include "hash_table.h"
-#include "sxpr.h"
-
-#ifdef __KERNEL__
-#include <linux/errno.h>
-#else
-#include <errno.h>
-#endif
-
-#ifdef __KERNEL__
-#include <linux/random.h>
-
-int rand(void){
-    int v;
-    get_random_bytes(&v, sizeof(v));
-    return v;
-}
-
-#else
-#include <stdlib.h>
-#endif
-
-#undef free
-
-/** @file
- * General representation of sxprs.
- * Includes print, equal, and free functions for the sxpr types.
- *
- * Zero memory containing an Sxpr will have the value ONONE - this is 
intentional.
- * When a function returning an sxpr cannot allocate memory we return ONOMEM.
- *
- */
-
-static int atom_print(IOStream *io, Sxpr obj, unsigned flags);
-static int atom_equal(Sxpr x, Sxpr y);
-static void atom_free(Sxpr obj);
-static Sxpr atom_copy(Sxpr obj);
-
-static int string_print(IOStream *io, Sxpr obj, unsigned flags);
-static int string_equal(Sxpr x, Sxpr y);
-static void string_free(Sxpr obj);
-static Sxpr string_copy(Sxpr obj);
-
-static int cons_print(IOStream *io, Sxpr obj, unsigned flags);
-static int cons_equal(Sxpr x, Sxpr y);
-static void cons_free(Sxpr obj);
-static Sxpr cons_copy(Sxpr obj);
-
-static int null_print(IOStream *io, Sxpr obj, unsigned flags);
-static int none_print(IOStream *io, Sxpr obj, unsigned flags);
-static int int_print(IOStream *io, Sxpr obj, unsigned flags);
-static int bool_print(IOStream *io, Sxpr obj, unsigned flags);
-static int err_print(IOStream *io, Sxpr obj, unsigned flags);
-static int nomem_print(IOStream *io, Sxpr obj, unsigned flags);
-
-/** Type definitions. */
-static SxprType types[1024] = {
-    [T_NONE]     { .type=    T_NONE,     .name= "none",       .print= 
none_print      },
-    [T_NULL]     { .type=    T_NULL,     .name= "null",       .print= 
null_print      },
-    [T_UINT]     { .type=    T_UINT,     .name= "int",        .print= 
int_print,      },
-    [T_BOOL]     { .type=    T_BOOL,     .name= "bool",       .print= 
bool_print,     },
-    [T_ERR]      { .type=    T_ERR,      .name= "err",        .print= 
err_print,      },
-    [T_NOMEM]    { .type=    T_ERR,      .name= "nomem",      .print= 
nomem_print,    },
-    [T_ATOM]     { .type=    T_ATOM,     .name= "atom",       .print= 
atom_print,
-                   .pointer= TRUE,
-                   .free=    atom_free,
-                   .equal=   atom_equal,
-                   .copy=    atom_copy,
-                 },
-    [T_STRING]   { .type=    T_STRING,   .name= "string",     .print= 
string_print,
-                   .pointer= TRUE,
-                   .free=    string_free,
-                   .equal=   string_equal,
-                   .copy=    string_copy,
-                 },
-    [T_CONS]     { .type=    T_CONS,     .name= "cons",       .print= 
cons_print,
-                   .pointer= TRUE,
-                   .free=    cons_free,
-                   .equal=   cons_equal,
-                   .copy=    cons_copy,
-                 },
-};
-
-/** Number of entries in the types array. */
-static int type_sup = sizeof(types)/sizeof(types[0]);
-
-/** Define a type.
- * The tydef must have a non-zero type code.
- * It is an error if the type code is out of range or already defined.
- *
- * @param tydef type definition
- * @return 0 on success, error code otherwise
- */
-int def_sxpr_type(SxprType *tydef){
-    int err = 0;
-    int ty = tydef->type;
-    if(ty < 0 || ty >= type_sup){
-        err = -EINVAL;
-        goto exit;
-    }
-    if(types[ty].type){
-        err = -EEXIST;
-        goto exit;
-    }
-    types[ty] = *tydef;
-  exit:
-    return err;
-    
-}
-
-/** Get the type definition for a given type code.
- *
- * @param ty type code
- * @return type definition or null
- */
-SxprType *get_sxpr_type(int ty){
-    if(0 <= ty && ty < type_sup){
-        return types+ty;
-    }
-    return NULL;
-}
-
-/** The default print function.
- *
- * @param io stream to print to
- * @param x sxpr to print
- * @param flags print flags
- * @return number of bytes written on success
- */
-int default_print(IOStream *io, Sxpr x, unsigned flags){
-    return IOStream_print(io, "#<%u %lu>\n", get_type(x), get_ul(x));
-}
-
-/** The default equal function.
- * Uses eq().
- *
- * @param x sxpr to compare
- * @param y sxpr to compare
- * @return 1 if equal, 0 otherwise
- */
-int default_equal(Sxpr x, Sxpr y){
-    return eq(x, y);
-}
-
-/** General sxpr print function.
- * Prints an sxpr on a stream using the print function for the sxpr type.
- * Printing is controlled by flags from the PrintFlags enum.
- * If PRINT_TYPE is in the flags the sxpr type is printed before the sxpr
- * (for debugging).
- *
- * @param io stream to print to
- * @param x sxpr to print
- * @param flags print flags
- * @return number of bytes written
- */
-int objprint(IOStream *io, Sxpr x, unsigned flags){
-    SxprType *def = get_sxpr_type(get_type(x));
-    ObjPrintFn *print_fn = (def && def->print ? def->print : default_print);
-    int k = 0;
-    if(!io) return k;
-    if(flags & PRINT_TYPE){
-        k += IOStream_print(io, "%s:", def->name);
-    }
-    if(def->pointer && (flags & PRINT_ADDR)){
-        k += IOStream_print(io, "<%p>", get_ptr(x));
-    }
-    k += print_fn(io, x, flags);
-    return k;
-}
-
-Sxpr objcopy(Sxpr x){
-    SxprType *def = get_sxpr_type(get_type(x));
-    ObjCopyFn *copy_fn = (def ? def->copy : NULL);
-    Sxpr v;
-    if(copy_fn){
-        v = copy_fn(x);
-    } else if(def->pointer){
-        v = ONOMEM;
-    } else {
-        v = x;
-    }
-    return v;
-}
-
-/** General sxpr free function.
- * Frees an sxpr using the free function for its type.
- * Free functions must recursively free any subsxprs.
- * If no function is defined then the default is to
- * free sxprs whose type has pointer true.
- * Sxprs must not be used after freeing.
- *
- * @param x sxpr to free
- */
-void objfree(Sxpr x){
-    SxprType *def = get_sxpr_type(get_type(x));
-
-    if(def){
-        if(def->free){
-            def->free(x);
-        } else if (def->pointer){
-            hfree(x);
-        }
-    }
-}
-
-/** General sxpr equality function.
- * Compares x and y using the equal function for x.
- * Uses default_equal() if x has no equal function.
- *
- * @param x sxpr to compare
- * @param y sxpr to compare
- * @return 1 if equal, 0 otherwise
- */
-int objequal(Sxpr x, Sxpr y){
-    SxprType *def = get_sxpr_type(get_type(x));
-    ObjEqualFn *equal_fn = (def && def->equal ? def->equal : default_equal);
-    return equal_fn(x, y);
-}
-
-/** Search for a key in an alist.
- * An alist is a list of conses, where the cars
- * of the conses are the keys. Compares keys using equality.
- *
- * @param k key
- * @param l alist to search
- * @return first element of l with car k, or ONULL
- */
-Sxpr assoc(Sxpr k, Sxpr l){
-    for( ; CONSP(l) ; l = CDR(l)){
-        Sxpr x = CAR(l);
-        if(CONSP(x) && objequal(k, CAR(x))){
-            return x;   
-        }
-    }
-    return ONULL;
-}
-
-/** Search for a key in an alist.
- * An alist is a list of conses, where the cars
- * of the conses are the keys. Compares keys using eq.
- *
- * @param k key
- * @param l alist to search
- * @return first element of l with car k, or ONULL
- */
-Sxpr assocq(Sxpr k, Sxpr l){
-    for( ; CONSP(l); l = CDR(l)){
-        Sxpr x = CAR(l);
-        if(CONSP(x) && eq(k, CAR(x))){
-            return x;
-        }
-    }
-    return ONULL;
-}
-
-/** Add a new key and value to an alist.
- *
- * @param k key
- * @param l value
- * @param l alist
- * @return l with the new cell added to the front
- */
-Sxpr acons(Sxpr k, Sxpr v, Sxpr l){
-    Sxpr x, y;
-    x = cons_new(k, v);
-    if(NOMEMP(x)) return x;
-    y = cons_new(x, l);
-    if(NOMEMP(y)) cons_free_cells(x);
-    return y;
-}
-
-/** Test if a list contains an element.
- * Uses sxpr equality.
- *
- * @param l list
- * @param x element to look for
- * @return a tail of l with x as car, or ONULL
- */
-Sxpr cons_member(Sxpr l, Sxpr x){
-    for( ; CONSP(l) && !eq(x, CAR(l)); l = CDR(l)){}
-    return l;
-}
-
-/** Test if a list contains an element satisfying a test.
- * The test function is called with v and an element of the list.
- *
- * @param l list
- * @param test_fn test function to use
- * @param v value for first argument to the test
- * @return a tail of l with car satisfying the test, or 0
- */
-Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){
-    for( ; CONSP(l) && !test_fn(v, CAR(l)); l = CDR(l)){ }
-    return l;
-}
-
-/** Test if the elements of list 't' are a subset of the elements
- * of list 's'. Element order is not significant.
- *
- * @param s element list to check subset of
- * @param t element list to check if is a subset
- * @return 1 if is a subset, 0 otherwise
- */
-int cons_subset(Sxpr s, Sxpr t){
-    for( ; CONSP(t); t = CDR(t)){
-        if(!CONSP(cons_member(s, CAR(t)))){
-            return 0;
-        }
-    }
-    return 1;
-}
-
-/** Test if two lists have equal sets of elements.
- * Element order is not significant.
- *
- * @param s list to check
- * @param t list to check
- * @return 1 if equal, 0 otherwise
- */
-int cons_set_equal(Sxpr s, Sxpr t){
-    return cons_subset(s, t) && cons_subset(t, s);
-}
-
-#ifdef USE_GC
-/*============================================================================*/
-/* The functions inside this ifdef are only safe if GC is used.
- * Otherwise they may leak memory.
- */
-
-/** Remove an element from a list (GC only).
- * Uses sxpr equality and removes all instances, even
- * if there are more than one.
- *
- * @param l list to remove elements from
- * @param x element to remove
- * @return modified input list
- */
-Sxpr cons_remove(Sxpr l, Sxpr x){
-    return cons_remove_if(l, eq, x);
-}
-
-/** Remove elements satisfying a test (GC only).
- * The test function is called with v and an element of the set.
- *
- * @param l list to remove elements from
- * @param test_fn function to use to decide if an element should be removed
- * @return modified input list
- */
-Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){
-    Sxpr prev = ONULL, elt, next;
-
-    for(elt = l; CONSP(elt); elt = next){
-        next = CDR(elt);
-        if(test_fn(v, CAR(elt))){
-            if(NULLP(prev)){
-                l = next;
-            } else {
-                CDR(prev) = next;
-            }
-        }
-    }
-    return l;
-}
-
-/** Set the value for a key in an alist (GC only).
- * If the key is present, changes the value, otherwise
- * adds a new cell.
- *
- * @param k key
- * @param v value
- * @param l alist
- * @return modified or extended list
- */
-Sxpr setf(Sxpr k, Sxpr v, Sxpr l){
-    Sxpr e = assoc(k, l);
-    if(NULLP(e)){
-        l = acons(k, v, l);
-    } else {
-        CAR(CDR(e)) = v;
-    }
-    return l;
-}
-/*============================================================================*/
-#endif /* USE_GC */
-
-/** Create a new atom with the given name.
- *
- * @param name the name
- * @return new atom
- */
-Sxpr atom_new(char *name){
-    Sxpr n, obj = ONOMEM;
-    long v;
-
-    // Don't always want to do this.
-    if(0 && convert_atol(name, &v) == 0){
-        obj = OINT(v);
-    } else {
-        n = string_new(name);
-        if(NOMEMP(n)) goto exit;
-        obj = HALLOC(ObjAtom, T_ATOM);
-        if(NOMEMP(obj)){
-            string_free(n);
-            goto exit;
-        }
-        OBJ_ATOM(obj)->name = n;
-    }
-  exit:
-    return obj;
-}
-
-/** Free an atom.
- *
- * @param obj to free
- */
-void atom_free(Sxpr obj){
-    // Interned atoms are shared, so do not free.
-    if(OBJ_ATOM(obj)->interned) return;
-    objfree(OBJ_ATOM(obj)->name);
-    hfree(obj);
-}
-
-/** Copy an atom.
- *
- * @param obj to copy
- */
-Sxpr atom_copy(Sxpr obj){
-    Sxpr v;
-    if(OBJ_ATOM(obj)->interned){
-        v = obj;
-    } else {
-        v = atom_new(atom_name(obj));
-    }
-    return v;
-}
-
-/** Print an atom. Prints the atom name.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes printed
- */
-int atom_print(IOStream *io, Sxpr obj, unsigned flags){
-    return objprint(io, OBJ_ATOM(obj)->name, flags);
-}
-
-/** Atom equality.
- *
- * @param x to compare
- * @param y to compare
- * @return 1 if equal, 0 otherwise
- */
-int atom_equal(Sxpr x, Sxpr y){
-    int ok;
-    ok = eq(x, y);
-    if(ok) goto exit;
-    ok = ATOMP(y) && string_equal(OBJ_ATOM(x)->name, OBJ_ATOM(y)->name);
-    if(ok) goto exit;
-    ok = STRINGP(y) && string_equal(OBJ_ATOM(x)->name, y);
-  exit:
-    return ok;
-}
-
-/** Get the name of an atom.
- *
- * @param obj atom
- * @return name
- */
-char * atom_name(Sxpr obj){
-    return string_string(OBJ_ATOM(obj)->name);
-}
-
-int atom_length(Sxpr obj){
-    return string_length(OBJ_ATOM(obj)->name);
-}
-
-/** Get the C string from a string sxpr.
- *
- * @param obj string sxpr
- * @return string
- */
-char * string_string(Sxpr obj){
-    return OBJ_STRING(obj)->data;
-}
-
-/** Get the length of a string.
- *
- * @param obj string
- * @return length
- */
-int string_length(Sxpr obj){
-    return OBJ_STRING(obj)->len;
-}
-
-/** Create a new string. The input string is copied,
- * and must be null-terminated.
- *
- * @param s characters to put in the string
- * @return new sxpr
- */
-Sxpr string_new(char *s){
-    int n = (s ? strlen(s) : 0);
-    return string_new_n(s, n);
-}
-
-/** Create a new string. The input string is copied,
- * and need not be null-terminated.
- *
- * @param s characters to put in the string (may be null)
- * @param n string length
- * @return new sxpr
- */
-Sxpr string_new_n(char *s, int n){
-    Sxpr obj;
-    obj = halloc(sizeof(ObjString) + n + 1, T_STRING);
-    if(!NOMEMP(obj)){
-        char *str = OBJ_STRING(obj)->data;
-        OBJ_STRING(obj)->len = n;
-        if(s){
-            memcpy(str, s, n);
-            str[n] = '\0';
-        } else {
-            memset(str, 0, n + 1);
-        }
-    }
-    return obj;
-}
-
-/** Free a string.
- *
- * @param obj to free
- */
-void string_free(Sxpr obj){
-    hfree(obj);
-}
-
-/** Copy a string.
- *
- * @param obj to copy
- */
-Sxpr string_copy(Sxpr obj){
-    return string_new_n(string_string(obj), string_length(obj));
-}
-
-/** Determine if a string needs escapes when printed
- * using the given flags.
- *
- * @param str string to check
- * @param n string length
- * @param flags print flags
- * @return 1 if needs escapes, 0 otherwise
- */
-int needs_escapes(char *str, int n, unsigned flags){
-    char *c;
-    int i;
-    int val = 0;
-
-    if(str){
-        for(i=0, c=str; i<n; i++, c++){
-            if(in_alpha_class(*c)) continue;
-            if(in_decimal_digit_class(*c)) continue;
-            if(in_class(*c, "/._+:@~-")) continue;
-            val = 1;
-            break;
-        }
-    }
-    return val;
-}
-
-char randchar(void){
-    int r;
-    char c;
-    for( ; ; ){
-        r = rand();
-        c = (r >> 16) & 0xff;
-        if('a' <= c && c <= 'z') break;
-    }
-    return c;
-}
-
-int string_contains(char *s, int s_n, char *k, int k_n){
-    int i, n = s_n - k_n;
-    for(i=0; i < n; i++){
-        if(!memcmp(s+i, k, k_n)) return 1;
-    }
-    return 0;
-}
-
-int string_delim(char *s, int s_n, char *d, int d_n){
-    int i;
-    if(d_n < 4) return -1;
-    memset(d, 0, d_n+1);
-    for(i=0; i<3; i++){
-        d[i] = randchar();
-    }
-    for( ; i < d_n; i++){
-        if(!string_contains(s, s_n, d, i)){
-            return i;
-        }
-        d[i] = randchar();
-    }
-    return -1;
-}
-
-/** Print the bytes in a string as-is.
- *
- * @param io stream
- * @param str string
- * @param n length
- * @return bytes written or error code
- */
-int _string_print_raw(IOStream *io, char *str, int n){
-    int k = 0;
-    k = IOStream_write(io, str, n);
-    return k;
-}
-
-/** Print a string in counted data format.
- *
- * @param io stream
- * @param str string
- * @param n length
- * @return bytes written or error code
- */
-int _string_print_counted(IOStream *io, char *str, int n){
-    int k = 0;
-    k += IOStream_print(io, "%c%c%d%c",
-                        c_data_open, c_data_count, n, c_data_count);
-    k += IOStream_write(io, str, n);
-    return k;
-}
-  
-/** Print a string in quoted data format.
- *
- * @param io stream
- * @param str string
- * @param n length
- * @return bytes written or error code
- */
-int _string_print_quoted(IOStream *io, char *str, int n){
-    int k = 0;
-    char d[10];
-    int d_n;
-    d_n = string_delim(str, n, d, sizeof(d) - 1);
-    k += IOStream_print(io, "%c%c%s%c",
-                        c_data_open, c_data_quote, d, c_data_quote);
-    k += IOStream_write(io, str, n);
-    k += IOStream_print(io, "%c%s%c", c_data_quote, d, c_data_quote);
-    return k;
-}
-
-/** Print a string as a quoted string.
- *
- * @param io stream
- * @param str string
- * @param n length
- * @return bytes written or error code
- */
-int _string_print_string(IOStream *io, char *str, int n){
-    int k = 0;
-    
-    k += IOStream_print(io, "\"");
-    if(str){
-        char *s, *t;
-        for(s = str, t = str + n; s < t; s++){
-            if(*s < ' ' || *s >= 127 ){
-                switch(*s){
-                case '\a': k += IOStream_print(io, "\\a");  break;
-                case '\b': k += IOStream_print(io, "\\b");  break;
-                case '\f': k += IOStream_print(io, "\\f");  break;
-                case '\n': k += IOStream_print(io, "\\n");  break;
-                case '\r': k += IOStream_print(io, "\\r");  break;
-                case '\t': k += IOStream_print(io, "\\t");  break;
-                case '\v': k += IOStream_print(io, "\\v");  break;
-                default:
-                    // Octal escape;
-                    k += IOStream_print(io, "\\%o", *s);
-                    break;
-                }
-            } else if(*s == c_double_quote ||
-                      *s == c_single_quote ||
-                      *s == c_escape){
-                k += IOStream_print(io, "\\%c", *s);
-            } else {
-                k+= IOStream_print(io, "%c", *s);
-            }
-        }
-    }
-    k += IOStream_print(io, "\"");
-    return k;
-}
-
-/** Print a string to a stream, with escapes if necessary.
- *
- * @param io stream to print to
- * @param str string
- * @param n string length
- * @param flags print flags
- * @return number of bytes written
- */
-int _string_print(IOStream *io, char *str, int n, unsigned flags){
-    int k = 0;
-    if((flags & PRINT_COUNTED)){
-        k = _string_print_counted(io, str, n);
-    } else if((flags & PRINT_RAW) || !needs_escapes(str, n, flags)){
-        k = _string_print_raw(io, str, n);
-    } else if(n > 50){
-        k = _string_print_quoted(io, str, n);
-    } else {
-        k = _string_print_string(io, str, n);
-    }
-    return k;
-}
-
-/** Print a string to a stream, with escapes if necessary.
- *
- * @param io stream to print to
- * @param obj string
- * @param flags print flags
- * @return number of bytes written
- */
-int string_print(IOStream *io, Sxpr obj, unsigned flags){
-    return _string_print(io,
-                         OBJ_STRING(obj)->data,
-                         OBJ_STRING(obj)->len,
-                         flags);
-}
-
-int string_eq(char *s, int s_n, char *t, int t_n){
-    return (s_n == t_n) && (memcmp(s, t, s_n) == 0);
-}
-
-/** Compare an sxpr with a string for equality.
- *
- * @param x string to compare with
- * @param y sxpr to compare
- * @return 1 if equal, 0 otherwise
- */
-int string_equal(Sxpr x, Sxpr y){
-    int ok = 0;
-    ok = eq(x,y);
-    if(ok) goto exit;
-    ok = has_type(y, T_STRING) &&
-        string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len,
-                  OBJ_STRING(y)->data, OBJ_STRING(y)->len);
-    if(ok) goto exit;
-    ok = has_type(y, T_ATOM) &&
-        string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len,
-                  atom_name(y), atom_length(y));
-  exit:
-    return ok;
-}
-
-/** Create a new cons cell.
- * The cell is ONOMEM if either argument is.
- *
- * @param car sxpr for the car
- * @param cdr sxpr for the cdr
- * @return new cons
- */
-Sxpr cons_new(Sxpr car, Sxpr cdr){
-    Sxpr obj;
-    if(NOMEMP(car) || NOMEMP(cdr)){
-        obj = ONOMEM;
-    } else {
-        obj = HALLOC(ObjCons, T_CONS);
-        if(!NOMEMP(obj)){
-            ObjCons *z = OBJ_CONS(obj);
-            z->car = car;
-            z->cdr = cdr;
-        }
-    }
-    return obj;
-}
-
-/** Push a new element onto a list.
- *
- * @param list list to add to
- * @param elt element to add
- * @return 0 if successful, error code otherwise
- */
-int cons_push(Sxpr *list, Sxpr elt){
-    Sxpr l;
-    l = cons_new(elt, *list);
-    if(NOMEMP(l)) return -ENOMEM;
-    *list = l;
-    return 0;
-}
-
-/** Free a cons. Recursively frees the car and cdr.
- *
- * @param obj to free
- */
-void cons_free(Sxpr obj){
-    Sxpr next;
-    for(; CONSP(obj); obj = next){
-        next = CDR(obj);
-        objfree(CAR(obj));
-        hfree(obj);
-    }
-    if(!NULLP(obj)){
-        objfree(obj);
-    }
-}
-
-/** Copy a cons. Recursively copies the car and cdr.
- *
- * @param obj to copy
- */
-Sxpr cons_copy(Sxpr obj){
-    Sxpr v = ONULL;
-    Sxpr l = ONULL, x = ONONE;
-    for(l = obj; CONSP(l); l = CDR(l)){
-        x = objcopy(CAR(l));
-        if(NOMEMP(x)) goto exit;
-        x = cons_new(x, v);
-        if(NOMEMP(x)) goto exit;
-        v = x;
-    }
-    v = nrev(v);
-  exit:
-    if(NOMEMP(x)){
-        objfree(v);
-        v = ONOMEM;
-    }
-    return v;
-}
-
-/** Free a cons and its cdr cells, but not the car sxprs.
- * Does nothing if called on something that is not a cons.
- *
- * @param obj to free
- */
-void cons_free_cells(Sxpr obj){
-    Sxpr next;
-    for(; CONSP(obj); obj = next){
-        next = CDR(obj);
-        hfree(obj);
-    }
-}
-
-/** Print a cons.
- * Prints the cons in list format if the cdrs are conses.
- * uses pair (dot) format if the last cdr is not a cons (or null).
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-int cons_print(IOStream *io, Sxpr obj, unsigned flags){
-    int first = 1;
-    int k = 0;
-    k += IOStream_print(io, "(");
-    for( ; CONSP(obj) ; obj = CDR(obj)){
-        if(first){ 
-            first = 0;
-        } else {
-            k += IOStream_print(io, " ");
-        }
-        k += objprint(io, CAR(obj), flags);
-    }
-    if(!NULLP(obj)){
-        k += IOStream_print(io, " . ");
-        k += objprint(io, obj, flags);
-    }
-    k += IOStream_print(io, ")");
-    return (IOStream_error(io) ? -1 : k);
-}
-
-/** Compare a cons with another sxpr for equality.
- * If y is a cons, compares the cars and cdrs recursively.
- *
- * @param x cons to compare
- * @param y sxpr to compare
- * @return 1 if equal, 0 otherwise
- */
-int cons_equal(Sxpr x, Sxpr y){
-    return CONSP(y) &&
-        objequal(CAR(x), CAR(y)) &&
-        objequal(CDR(x), CDR(y));
-}
-
-/** Return the length of a cons list.
- *
- * @param obj list
- * @return length
- */
-int cons_length(Sxpr obj){
-    int count = 0;
-    for( ; CONSP(obj); obj = CDR(obj)){
-        count++;
-    }
-    return count;
-}
-
-/** Destructively reverse a cons list in-place.
- * If the argument is not a cons it is returned unchanged.
- * 
- * @param l to reverse
- * @return reversed list
- */
-Sxpr nrev(Sxpr l){
-    if(CONSP(l)){
-        // Iterate down the cells in the list making the cdr of
-        // each cell point to the previous cell. The last cell 
-        // is the head of the reversed list.
-        Sxpr prev = ONULL;
-        Sxpr cell = l;
-        Sxpr next;
-
-        while(1){
-            next = CDR(cell);
-            CDR(cell) = prev;
-            if(!CONSP(next)) break;
-            prev = cell;
-            cell = next;
-        }
-        l = cell;
-    }
-    return l;
-}
-
-/** Print the null sxpr.        
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int null_print(IOStream *io, Sxpr obj, unsigned flags){
-    return IOStream_print(io, "()");
-}
-
-/** Print the `unspecified' sxpr none.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int none_print(IOStream *io, Sxpr obj, unsigned flags){
-    return IOStream_print(io, "<none>");
-}
-
-/** Print an integer.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int int_print(IOStream *io, Sxpr obj, unsigned flags){
-    return IOStream_print(io, "%d", OBJ_INT(obj));
-}
-
-/** Print a boolean.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int bool_print(IOStream *io, Sxpr obj, unsigned flags){
-    return IOStream_print(io, (OBJ_UINT(obj) ? k_true : k_false));
-}
-
-/** Print an error.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int err_print(IOStream *io, Sxpr obj, unsigned flags){
-    int err = OBJ_INT(obj);
-    if(err < 0) err = -err;
-    return IOStream_print(io, "[error:%d:%s]", err, strerror(err));
-}
-
-/** Print the 'nomem' sxpr.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int nomem_print(IOStream *io, Sxpr obj, unsigned flags){
-    return IOStream_print(io, "[ENOMEM]");
-}
-
-int sxprp(Sxpr obj, Sxpr name){
-    return CONSP(obj) && objequal(CAR(obj), name);
-}
-
-/** Get the name of an element.
- * 
- * @param obj element
- * @return name
- */
-Sxpr sxpr_name(Sxpr obj){
-    Sxpr val = ONONE;
-    if(CONSP(obj)){
-        val = CAR(obj);
-    } else if(STRINGP(obj) || ATOMP(obj)){
-        val = obj;
-    }
-    return val;
-}
-
-int sxpr_is(Sxpr obj, char *s){
-    if(ATOMP(obj)) return string_eq(atom_name(obj), atom_length(obj), s, 
strlen(s));
-    if(STRINGP(obj)) return string_eq(string_string(obj), string_length(obj), 
s, strlen(s));
-    return 0;
-}
-
-int sxpr_elementp(Sxpr obj, Sxpr name){
-    int ok = 0;
-    ok = CONSP(obj) && objequal(CAR(obj), name);
-    return ok;
-}
-
-/** Get the attributes of an sxpr.
- * 
- * @param obj sxpr
- * @return attributes
- */
-Sxpr sxpr_attributes(Sxpr obj){
-    Sxpr val = ONULL;
-    if(CONSP(obj)){
-        obj = CDR(obj);
-        if(CONSP(obj)){
-            obj = CAR(obj);
-            if(sxprp(obj, intern("@"))){
-                val = CDR(obj);
-            }
-        }
-    }
-    return val;
-}
-
-Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def){
-    Sxpr val = ONONE;
-    val = assoc(sxpr_attributes(obj), key);
-    if(CONSP(val) && CONSP(CDR(val))){
-        val = CADR(def);
-    } else {
-        val = def;
-    }
-    return val;
-}
-
-/** Get the children of an sxpr.
- * 
- * @param obj sxpr
- * @return children
- */
-Sxpr sxpr_children(Sxpr obj){
-    Sxpr val = ONULL;
-    if(CONSP(obj)){
-        val = CDR(obj);
-        if(CONSP(val) && sxprp(CAR(val), intern("@"))){
-            val = CDR(val);
-        }
-    }
-    return val;
-}
-
-Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def){
-    Sxpr val = ONONE;
-    Sxpr l;
-    for(l = sxpr_children(obj); CONSP(l); l = CDR(l)){
-        if(sxprp(CAR(l), name)){
-            val = CAR(l);
-            break;
-        }
-    }
-    if(NONEP(val)) val = def;
-    return val;
-}
-
-Sxpr sxpr_child0(Sxpr obj, Sxpr def){
-    Sxpr val = ONONE;
-    Sxpr l = sxpr_children(obj);
-    if(CONSP(l)){
-        val = CAR(l);
-    } else {
-        val = def;
-    }
-    return val;
-}
-
-Sxpr sxpr_childN(Sxpr obj, int n, Sxpr def){
-    Sxpr val = def;
-    Sxpr l;
-    int i;
-    for (i = 0, l = sxpr_children(obj); CONSP(l); i++, l = CDR(l)){
-        if(i == n){
-            val = CAR(l);
-            break;
-        }
-    }
-    return val;
-}
-    
-Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def){
-    Sxpr val = ONONE;
-    val = sxpr_child(obj, name, ONONE);
-    if(NONEP(val)){
-        val = def;
-    } else {
-        val = sxpr_child0(val, def);
-    }
-    return val;
-}
-
-/** Table of interned symbols. Indexed by symbol name. */
-static HashTable *symbols = NULL;
-
-/** Hash function for entries in the symbol table.
- *
- * @param key to hash
- * @return hashcode
- */
-static Hashcode sym_hash_fn(void *key){
-    return hash_string((char*)key);
-}
-
-/** Key equality function for the symbol table.
- *
- * @param x to compare
- * @param y to compare
- * @return 1 if equal, 0 otherwise
- */
-static int sym_equal_fn(void *x, void *y){
-    return !strcmp((char*)x, (char*)y);
-}
-
-/** Entry free function for the symbol table.
- *
- * @param table the entry is in
- * @param entry being freed
- */
-static void sym_free_fn(HashTable *table, HTEntry *entry){
-    if(entry){
-        objfree(((ObjAtom*)entry->value)->name);
-        HTEntry_free(entry);
-    }
-}
-        
-/** Initialize the symbol table.
- *
- * @return 0 on sucess, error code otherwise
- */
-static int init_symbols(void){
-    symbols = HashTable_new(100);
-    if(symbols){
-        symbols->key_hash_fn = sym_hash_fn;
-        symbols->key_equal_fn = sym_equal_fn;
-        symbols->entry_free_fn = sym_free_fn;
-        return 0;
-    }
-    return -1;
-}
-
-/** Cleanup the symbol table. Frees the table and all its symbols.
- */
-void cleanup_symbols(void){
-    HashTable_free(symbols);
-    symbols = NULL;
-}
-
-/** Get the interned symbol with the given name.
- * No new symbol is created.
- *
- * @return symbol or null
- */
-Sxpr get_symbol(char *sym){
-    HTEntry *entry;
-    if(!symbols){
-        if(init_symbols()) return ONOMEM;
-        return ONULL;
-    }
-    entry = HashTable_get_entry(symbols, sym);
-    if(entry){
-        return OBJP(T_ATOM, entry->value);
-    } else {
-        return ONULL;
-    }
-}
-
-/** Get the interned symbol with the given name.
- * Creates a new symbol if necessary.
- *
- * @return symbol
- */
-Sxpr intern(char *sym){
-    Sxpr symbol = get_symbol(sym);
-    if(NULLP(symbol)){
-        if(!symbols) return ONOMEM;
-        symbol = atom_new(sym);
-        if(!NOMEMP(symbol)){
-            OBJ_ATOM(symbol)->interned = TRUE;
-            HashTable_add(symbols, atom_name(symbol), get_ptr(symbol));
-        }
-    }
-    return symbol;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/sxpr.h
--- a/tools/vnet/libxutil/sxpr.h        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-#ifndef _XUTIL_SXPR_H_
-#define _XUTIL_SXPR_H_
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/types.h>
-#else
-#include <stdint.h>
-#endif
-
-#include "hash_table.h"
-#include "iostream.h"
-#include "allocate.h"
-
-/** @file
- * Definitions for rules and sxprs.
- */
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-/** Sxpr type. */
-typedef int16_t TypeCode;
-
-/** A typed sxpr handle.*/
-typedef struct Sxpr {
-    /** Sxpr type. */
-    TypeCode type;
-    union {
-        /** Sxpr value. */
-        unsigned long ul;
-        /** Pointer. */
-        void *ptr;
-    } v;
-} Sxpr;
-
-/** Get the integer value from an sxpr.
- *
- * @param obj sxpr
- * @return value
- */
-static inline unsigned long get_ul(Sxpr obj){
-    return obj.v.ul;
-}
-
-/** Get the pointer value from an sxpr.
- *
- * @param obj sxpr
- * @return value
- */
-static inline void * get_ptr(Sxpr obj){
-    return obj.v.ptr;
-}
-
-/** Create an sxpr containing a pointer.
- *
- * @param ty typecode
- * @param val pointer
- * @return sxpr
- */
-static inline Sxpr obj_ptr(TypeCode ty, void *val){
-    return (Sxpr){ .type= ty, .v= { .ptr= val } };
-}
-
-/** Create an sxpr containing an integer.
- *
- * @param ty typecode
- * @param val integer
- * @return sxpr
- */
-static inline Sxpr obj_ul(TypeCode ty, unsigned long val){
-    return (Sxpr){ .type= ty, .v= { .ul= val } };
-}
-
-/** Get the type of an sxpr.
- *
- * @param obj sxpr
- * @return type
- */
-static inline TypeCode get_type(Sxpr obj){
-    return obj.type;
-}
-
-/** Check the type of an sxpr.
- *
- * @param obj sxpr
- * @param type to check
- * @return 1 if has the type, 0 otherwise
- */
-static inline int has_type(Sxpr obj, TypeCode type){
-    return get_type(obj) == type;
-}
-
-/** Compare sxprs for literal equality of type and value.
- *
- * @param x sxpr to compare
- * @param y sxpr to compare
- * @return 1 if equal, 0 otherwise
- */
-static inline int eq(Sxpr x, Sxpr y){
-    return ((get_type(x) == get_type(y)) && (get_ul(x) == get_ul(y)));
-}
-
-/** The 'unspecified' sxpr. */
-#define T_NONE       ((TypeCode)0)
-/** The empty list. */
-#define T_NULL       ((TypeCode)1)
-/** Unsigned integer. */
-#define T_UINT       ((TypeCode)2)
-/** A string. */
-#define T_STRING     ((TypeCode)3)
-/** An atom. */
-#define T_ATOM       ((TypeCode)4)
-/** A boolean. */
-#define T_BOOL       ((TypeCode)5)
-
-/** A cons (pair or list). */
-#define T_CONS       ((TypeCode)10)
-
-/** An error. */
-#define T_ERR        ((TypeCode)40)
-/** Sxpr type to indicate out of memory. */
-#define T_NOMEM      ((TypeCode)41)
-
-typedef struct ObjString {
-    int len;
-    char data[0];
-} ObjString;
-
-/** An atom. */
-typedef struct ObjAtom {
-    Sxpr name;
-    Hashcode hashcode;
-    int interned;
-} ObjAtom;
-
-/** A cons (pair). */
-typedef struct ObjCons {
-    Sxpr car;
-    Sxpr cdr;
-} ObjCons;
-
-/** Flags for sxpr printing. */
-enum PrintFlags {
-    PRINT_RAW           = 0x001,
-    PRINT_TYPE          = 0x002,
-    PRINT_PRETTY        = 0x004,
-    PRINT_COUNTED       = 0x008,
-    PRINT_ADDR          = 0x010,
-};
-
-extern int _string_print(IOStream *io, char *str, int n, unsigned flags);
-extern int _string_print_raw(IOStream *io, char *str, int n);
-extern int _string_print_counted(IOStream *io, char *str, int n);
-extern int _string_print_quoted(IOStream *io, char *str, int n);
-extern int _string_print_string(IOStream *io, char *str, int n);
-
-/** An integer sxpr.
- *
- * @param ty type
- * @param val integer value
- */
-#define OBJI(ty, val) obj_ul(ty, val)
-
-/** Make an integer sxpr.
- * @param x value
- */
-#define OINT(x)       OBJI(T_UINT,  x)
-
-/** Make an error sxpr.
- *
- * @param x value
- */
-#define OERR(x)       OBJI(T_ERR,   x)
-
-/** Out of memory constant. */
-#define ONOMEM        OBJI(T_NOMEM, 0)
-
-/** The `unspecified' constant. */
-#define ONONE         OBJI(T_NONE,  0)
-
-/** Empty list constant. */
-#define ONULL         OBJI(T_NULL,  0)
-
-/** False constant. */
-#define OFALSE        OBJI(T_BOOL,  0)
-
-/** True constant. */
-#define OTRUE         OBJI(T_BOOL,  1)
-
-/** A pointer sxpr.
- * If the pointer is non-null, returns an sxpr containing it.
- * If the pointer is null, returns ONOMEM.
- *
- * @param ty type
- * @param val pointer
- */
-static inline Sxpr OBJP(int ty, void *val){
-    return (val ? obj_ptr(ty, val) : ONOMEM);
-}
-
-/** Make an integer sxpr containing a pointer.
- *
- * @param val pointer
- */
-static inline Sxpr PTR(void *val){
-    return OBJP(T_UINT, (void*)(val));
-}
-
-/** Allocate some memory and return an sxpr containing it.
- * Returns ONOMEM if allocation failed.
- *
- * @param n number of bytes to allocate
- * @param ty typecode
- * @return sxpr
- */
-static inline Sxpr halloc(int n, int ty){
-    return OBJP(ty, allocate(n));
-}
-
-/** Allocate an sxpr containing a pointer to the given type.
- *
- * @param _ctype type (uses sizeof to determine how many bytes to allocate)
- * @param _tycode typecode
- * @return sxpr, ONOMEM if allocation failed
- */
-#define HALLOC(_ctype, _tycode) halloc(sizeof(_ctype), _tycode)
-
-/* Recognizers for the various sxpr types.  */
-#define ATOMP(obj)        has_type(obj, T_ATOM)
-#define BOOLP(obj)        has_type(obj, T_BOOL)
-#define CONSP(obj)        has_type(obj, T_CONS)
-#define ERRP(obj)         has_type(obj, T_ERR)
-#define INTP(obj)         has_type(obj, T_UINT)
-#define NOMEMP(obj)       has_type(obj, T_NOMEM)
-#define NONEP(obj)        has_type(obj, T_NONE)
-#define NULLP(obj)        has_type(obj, T_NULL)
-#define STRINGP(obj)      has_type(obj, T_STRING)
-
-#define TRUEP(obj)    get_ul(obj)
-
-/** Convert an sxpr to an unsigned integer. */
-#define OBJ_UINT(x)   get_ul(x)
-/** Convert an sxpr to an integer. */
-#define OBJ_INT(x)    (int)get_ul(x)
-
-/* Conversions of sxprs to their values.
- * No checking is done.
- */
-#define OBJ_STRING(x)  ((ObjString*)get_ptr(x))
-#define OBJ_CONS(x)    ((ObjCons*)get_ptr(x))
-#define OBJ_ATOM(x)    ((ObjAtom*)get_ptr(x))
-#define OBJ_SET(x)     ((ObjSet*)get_ptr(x))
-#define CAR(x)         (OBJ_CONS(x)->car)
-#define CDR(x)         (OBJ_CONS(x)->cdr)
-
-#define CAAR(x)        (CAR(CAR(x)))
-#define CADR(x)        (CAR(CDR(x)))
-#define CDAR(x)        (CDR(CAR(x)))
-#define CDDR(x)        (CDR(CDR(x)))
-
-/** Checked version of CAR
- *
- * @param x sxpr
- * @return CAR if a cons, x otherwise
- */
-static inline Sxpr car(Sxpr x){
-    return (CONSP(x) ? CAR(x) : x);
-}
-
-/** Checked version of CDR.
- *
- * @param x sxpr
- * @return CDR if a cons, null otherwise
- */
-static inline Sxpr cdr(Sxpr x){
-    return (CONSP(x) ? CDR(x) : ONULL);
-}
-
-typedef int ObjPrintFn(IOStream *io, Sxpr obj, unsigned flags);
-typedef int ObjEqualFn(Sxpr obj, Sxpr other);
-typedef void ObjFreeFn(Sxpr obj);
-typedef Sxpr ObjCopyFn(Sxpr obj);
-
-/** An sxpr type definition. */
-typedef struct SxprType {
-    TypeCode type;
-    char *name;
-    int pointer;
-    ObjPrintFn *print;
-    ObjEqualFn *equal;
-    ObjFreeFn *free;
-    ObjCopyFn *copy;
-} SxprType;
-
-extern int def_sxpr_type(SxprType *tydef);
-extern SxprType *get_sxpr_type(int ty);
-
-/** Free the pointer in an sxpr.
- *
- * @param x sxpr containing a pointer
- */
-static inline void hfree(Sxpr x){
-    deallocate(get_ptr(x));
-}
-
-extern int objprint(IOStream *io, Sxpr x, unsigned flags);
-extern int objequal(Sxpr x, Sxpr y);
-extern void objfree(Sxpr x);
-extern Sxpr objcopy(Sxpr x);
-
-extern void cons_free_cells(Sxpr obj);
-extern Sxpr intern(char *s);
-
-extern Sxpr assoc(Sxpr k, Sxpr l);
-extern Sxpr assocq(Sxpr k, Sxpr l);
-extern Sxpr acons(Sxpr k, Sxpr v, Sxpr l);
-extern Sxpr nrev(Sxpr l);
-extern Sxpr cons_member(Sxpr l, Sxpr x);
-extern Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
-extern int cons_subset(Sxpr s, Sxpr t);
-extern int cons_set_equal(Sxpr s, Sxpr t);
-
-#ifdef USE_GC
-extern Sxpr cons_remove(Sxpr l, Sxpr x);
-extern Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
-#endif
-
-extern Sxpr atom_new(char *name);
-extern char * atom_name(Sxpr obj);
-extern int atom_length(Sxpr obj);
-
-extern Sxpr string_new(char *s);
-extern Sxpr string_new_n(char *s, int n);
-extern char * string_string(Sxpr obj);
-extern int string_length(Sxpr obj);
-
-extern Sxpr cons_new(Sxpr car, Sxpr cdr);
-extern int cons_push(Sxpr *list, Sxpr elt);
-extern int cons_length(Sxpr obj);
-
-Sxpr sxpr_name(Sxpr obj);
-int sxpr_is(Sxpr obj, char *s);
-int sxpr_elementp(Sxpr obj, Sxpr name);
-Sxpr sxpr_attributes(Sxpr obj);
-Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def);
-Sxpr sxpr_children(Sxpr obj);
-Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def);
-Sxpr sxpr_childN(Sxpr obj, int n, Sxpr def);
-Sxpr sxpr_child0(Sxpr obj, Sxpr def);
-Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def);
-
-/** Create a new atom.
- *
- * @param s atom name
- * @return new atom
- */
-static inline Sxpr mkatom(char *s){
-    return atom_new(s);
-}
-
-/** Create a new string sxpr.
- *
- * @param s string bytes (copied)
- * @return new string
- */
-static inline Sxpr mkstring(char *s){
-    return string_new(s);
-}
-
-/** Create an integer sxpr.
- *
- * @param i value
- * @return sxpr
- */
-static inline Sxpr mkint(int i){
-    return OBJI(T_UINT, i);
-}
-
-/** Create a boolean sxpr.
- *
- * @param b value
- * @return sxpr
- */
-static inline Sxpr mkbool(int b){
-    return OBJI(T_BOOL, (b ? 1 : 0));
-}
-
-/* Constants used in parsing and printing. */
-#define k_list_open    "("
-#define c_list_open    '('
-#define k_list_close   ")"
-#define c_list_close   ')'
-#define k_true         "true"
-#define k_false        "false"
-
-#define c_escape       '\\'
-#define c_single_quote '\''
-#define c_double_quote '"'
-#define c_string_open  c_double_quote
-#define c_string_close c_double_quote
-
-#define c_data_open    '<'
-#define c_data_quote   '<'
-#define c_data_count   '*'
-//#define c_data_open    '['
-//#define c_data_close   ']'
-//#define c_binary       '*'
-
-#define c_var          '$'
-#define c_eval         '!'
-#define c_concat_open  '{'
-#define c_concat_close '}'
-
-#endif /* ! _XUTIL_SXPR_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/sxpr_parser.c
--- a/tools/vnet/libxutil/sxpr_parser.c Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1002 +0,0 @@
-/*
- * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifdef __KERNEL__
-#  include <linux/config.h>
-#  include <linux/module.h>
-#  include <linux/kernel.h>
-#  include <linux/string.h>
-#  include <linux/errno.h>
-#else
-#  include <stdlib.h>
-#  include <errno.h>
-#endif
-
-#include "sys_net.h"
-
-#include "iostream.h"
-#include "lexis.h"
-#include "sxpr_parser.h"
-#include "sys_string.h"
-#include "enum.h"
-
-/** @file
- * Sxpr parsing.
- *
- * So that the parser does not leak memory, all sxprs constructed by
- * the parser must be freed on error.  On successful parse the sxpr
- * returned becomes the responsibility of the caller.
- *
- * @author Mike Wray <mike.wray@xxxxxxxxxx>
- */
-
-#ifdef DEBUG
-#define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, 
__FUNCTION__, ##args)
-#else
-#define dprintf(fmt, args...) do{ }while(0)
-#endif
-
-#undef printf
-#define printf(fmt, args...)   IOStream_print(iostdout, fmt, ##args)
-
-static int state_start(Parser *p, char c);
-static int begin_start(Parser *p, char c);
-
-#if 0
-/** Print a parse error.
- *
- * @param in parser
- * @param msg format followed by printf arguments
- */
-static void eprintf(Parser *in, char *msg, ...){
-    va_list args;
-    if(in->error_out){
-        va_start(args, msg);
-        IOStream_vprint(in->error_out, msg, args);
-        va_end(args);
-    }
-}
-
-/** Print a parse warning.
- *
- * @param in parser
- * @param msg format followed by printf arguments
- */
-static void wprintf(Parser *in, char *msg, ...){
-    va_list args;
-    if(in->error_out){
-        va_start(args, msg);
-        IOStream_vprint(in->error_out, msg, args);
-        va_end(args);
-    }
-}
-#endif
-
-
-/*============================================================================*/
-
-/** Record defining the message for a parse error. */
-typedef struct {
-    ParseErrorId id;
-    char *message;
-} ParseError;
-
-/** Format for printing parse error messages. */
-#define PARSE_ERR_FMT "parse error> line %3d, column %2d: %s"
-
-/** Message catalog for the parse error codes. */
-static ParseError catalog[] = {
-    { PARSE_ERR_UNSPECIFIED,            "unspecified error" },
-    { PARSE_ERR_NOMEM,                  "out of memory" },
-    { PARSE_ERR_UNEXPECTED_EOF,         "unexpected end of input" },
-    { PARSE_ERR_TOKEN_TOO_LONG,         "token too long" },
-    { PARSE_ERR_INVALID_SYNTAX,         "syntax error" },
-    { PARSE_ERR_INVALID_ESCAPE,         "invalid escape" },
-    { 0, NULL }
-};
-
-/** Number of entries in the message catalog. */
-const static int catalog_n = sizeof(catalog)/sizeof(ParseError);
-
-/** Set the parser error stream.
- * Parse errors are reported on the the error stream if it is non-null.
- * 
- * @param z parser
- * @param error_out error stream
- */
-void Parser_set_error_stream(Parser *z, IOStream *error_out){
-    z->error_out = error_out;
-}
-
-/** Get the parser error message for an error code.
- *
- * @param id error code
- * @return error message (empty string if the code is unknown)
- */
-static char *get_message(ParseErrorId id){
-    int i;
-    for(i = 0; i < catalog_n; i++){
-        if(id == catalog[i].id){
-            return catalog[i].message;
-        }
-    }
-    return "";
-}
-
-#if 0
-/** Get the line number.
- *
- * @param in parser
- */
-static int get_line(Parser *in){
-    return in->line_no;
-}
-
-/** Get the column number.
- *
- * @param in parser
- */
-static int get_column(Parser *in){
-    return in->char_no;
-}
-#endif
-
-/** Get the line number the current token started on.
- *
- * @param in parser
- */
-static int get_tok_line(Parser *in){
-    return in->tok_begin_line;
-}
-
-/** Get the column number the current token started on.
- *
- * @param in parser
- */
-static int get_tok_column(Parser *in){
-    return in->tok_begin_char;
-}
-
-/** Return the current token.
- * The return value points at the internal buffer, so
- * it must not be modified (or freed). Use copy_token() if you need a copy.
- *
- * @param p parser
- * @return token
- */
-char *peek_token(Parser *p){
-    return p->tok;
-}
-
-int token_len(Parser *p){
-    return p->tok_end - p->tok;
-}
-
-/** Return a copy of the current token.
- * The returned value should be freed when finished with.
- *
- * @param p parser
- * @return copy of token
- */
-char *copy_token(Parser *p){
-    int n = token_len(p);
-    char *buf = allocate(n + 1);
-    if(buf){
-        memcpy(buf, peek_token(p), n);
-        buf[n] = '\0';
-    }
-    return buf;
-}
-
-void new_token(Parser *p){
-    memset(p->buf, 0, p->buf_end - p->buf);
-    p->tok = p->buf;
-    p->tok_end = p->tok;
-    p->tok_begin_line = p->line_no;
-    p->tok_begin_char = p->char_no;
-}
-
-/** Report a parse error.
- * Does nothing if the error stream is null or there is no error.
- *
- * @param in parser
- */
-static void report_error(Parser *in){
-    if(in->error_out && in->err){
-        char *msg = get_message(in->err);
-        char *tok = peek_token(in);
-        IOStream_print(in->error_out, PARSE_ERR_FMT,
-                       get_tok_line(in), get_tok_column(in), msg);
-        if(tok && tok[0]){
-            IOStream_print(in->error_out, " '%s'", tok);
-        }
-        IOStream_print(in->error_out, "\n");
-    }
-}
-
-/** Get the error message for the current parse error code.
- * Does nothing if there is no error.
- *
- * @param in parser
- * @param buf where to place the message
- * @param n maximum number of characters to place in buf
- * @return current error code (zero for no error)
- */
-int Parser_error_message(Parser *in, char *buf, int n){
-    if(in->err){
-        char *msg = get_message(in->err);
-        snprintf(buf, n, PARSE_ERR_FMT, get_tok_line(in),
-                 get_tok_column(in), msg);
-    }
-    return in->err;
-}
-
-/** Flag a parse error. All subsequent reads will fail.
- * Does not change the parser error code if it is already set.
- *
- * @param in parser
- * @param id error code
- */
-int Parser_error_id(Parser *in, ParseErrorId id){
-    if(!in->err){
-        in->err = id;
-        report_error(in);
-    }
-    return -EINVAL;
-}
-
-/** Flag an unspecified parse error.
- *
- * @param in parser
- */
-int Parser_error(Parser *in){
-    return Parser_error_id(in, PARSE_ERR_INVALID_SYNTAX);
-}
-
-/** Test if the parser's error flag is set.
- *
- * @param in parser
- * @return 1 if set, 0 otherwise
- */
-int Parser_has_error(Parser *in){
-    return (in->err > 0);
-}
-
-/** Test if the parser is at end of input.
- *
- * @param in parser
- * @return 1 if at EOF, 0 otherwise
- */
-int Parser_at_eof(Parser *p){
-    return p->eof;
-}
-
-void ParserState_free(ParserState *z){
-    if(!z) return;
-    objfree(z->val);
-    deallocate(z);
-}
-
-int ParserState_new(ParserStateFn *fn, char *name,
-                    ParserState *parent, ParserState **val){
-    int err = -ENOMEM;
-    ParserState *z;
-    z = ALLOCATE(ParserState);
-    if(!z) goto exit;
-    z->name = name;
-    z->fn = fn;
-    z->parent = parent;
-    z->val = ONULL;
-    err = 0;
-  exit:
-    *val = (err ? NULL : z);
-    return err;
-}
-
-void Parser_pop(Parser *p){
-    ParserState *s = p->state;
-    if(!s) return;
-    dprintf("Parser_pop> %s\n", s->name);
-    p->state = s->parent;
-    if (p->start_state == s) {
-        p->start_state = NULL;
-    }
-    ParserState_free(s);
-}
-
-/** Free a parser.
- * No-op if the parser is null.
- *
- * @param z parser 
- */
-void Parser_free(Parser *z){
-    if(!z) return;
-    // Hmmm. Need to free states, but careful about double free of values.
-    while(z->state){
-        objfree(z->state->val);
-        Parser_pop(z);
-    }
-    if(z->buf) deallocate(z->buf);
-    objfree(z->val);
-    z->val = ONONE;
-    deallocate(z);
-}
-
-int Parser_push(Parser *p, ParserStateFn *fn, char *name){
-    dprintf("Parser_push> %s\n", name);
-    return ParserState_new(fn, name, p->state, &p->state);
-}
-        
-int Parser_return(Parser *p){
-    int err = 0;
-    Sxpr val = ONONE;
-    if(!p->state){
-        err = -EINVAL;
-        goto exit;
-    }
-    val = p->state->val;
-    p->state->val = ONONE;
-    Parser_pop(p);
-    if(p->state){
-        err = cons_push(&p->state->val, val);
-    } else {
-        val = nrev(val);
-        p->val = val;
-    }
-  exit:
-    if(err){
-        objfree(val);
-    }
-    return err;
-}
-
-/** Reset the fields of a parser to initial values.
- *
- * @param z parser
- */
-static void reset(Parser *z){
-    // leave flags
-    // leave error_out
-    while(z->state){
-        Parser_pop(z);
-    }
-    z->val = ONONE;
-    z->eof = 0;
-    z->err = 0;
-    z->line_no = 1;
-    z->char_no = 0;
-    memset(z->buf, 0, z->buf_end - z->buf);
-    z->tok = z->buf;
-    z->tok_end = z->tok;
-    z->tok_begin_line = 0;
-    z->tok_begin_char = 0;
-    z->start_state = NULL;
-}
-
-/** Create a new parser. The error stream defaults to null.
- */
-Parser * Parser_new(void){
-    Parser *z = ALLOCATE(Parser);
-    int n = PARSER_BUF_SIZE;
-    int err = -ENOMEM;
-  
-    if(!z) goto exit;
-    z->buf = allocate(n);
-    if(!z->buf) goto exit;
-    err = 0;
-    z->buf_end = z->buf + n;
-    z->begin = begin_start;
-    reset(z);
-  exit:
-    if(err){
-        Parser_free(z);
-        z = NULL;
-    }
-    return z;
-}
-
-/** Get the next character.
- * Records the character read in the parser,
- * and sets the line and character counts.
- *
- * @param p parser
- * @return error flag: 0 on success, non-zero on error
- */
-static int input_char(Parser *p, char c){
-    int err = 0;
-    if(c=='\n'){
-        p->line_no++;
-        p->char_no = 0;
-    } else {
-        p->char_no++;
-    }
-    return err;
-}
-
-int save_char(Parser *p, char c){
-    int err = 0;
-    if(p->tok_end >= p->buf_end){
-        int buf_n = (p->buf_end - p->buf) + PARSER_BUF_INCREMENT;
-        char *buf = allocate(buf_n);
-        if(!buf){
-            err = -ENOMEM;
-            goto exit;
-        }
-        memcpy(buf, p->buf, p->tok_end - p->buf);
-        p->buf_end = buf + buf_n;
-        p->tok     = buf + (p->tok     - p->buf);
-        p->tok_end = buf + (p->tok_end - p->buf);
-        deallocate(p->buf);
-        p->buf = buf;
-    }
-    *p->tok_end++ = c;
-  exit:
-    return err;
-}
-
-/** Determine if a character is a separator.
- *
- * @param p parser
- * @param c character to test
- * @return 1 if a separator, 0 otherwise
- */
-static int is_separator(Parser *p, char c){
-    return in_sep_class(c);
-}
-
-int Parser_set_value(Parser *p, Sxpr obj){
-    int err = 0;
-    if(NOMEMP(obj)){
-        err = -ENOMEM;
-    } else {
-        p->state->val = obj;
-    }
-    return err;
-}
-    
-int Parser_intern(Parser *p){
-    Sxpr obj = intern(peek_token(p));
-    return Parser_set_value(p, obj);
-}
-
-int Parser_atom(Parser *p){
-    Sxpr obj;
-    long v;
-    if(Parser_flags(p, PARSE_INT) &&
-       convert_atol(peek_token(p), &v) == 0){
-        obj = OINT(v);
-    } else {
-        obj = atom_new(peek_token(p));
-    }
-    return Parser_set_value(p, obj);
-}
-
-int Parser_string(Parser *p){
-    Sxpr obj = string_new_n(peek_token(p), token_len(p));
-    return Parser_set_value(p, obj);
-}
-
-int Parser_data(Parser *p){
-    Sxpr obj = string_new_n(peek_token(p), token_len(p));
-    return Parser_set_value(p, obj);
-}
-
-int Parser_uint(Parser *p){
-    unsigned int x = htonl(*(unsigned int *)peek_token(p));
-    return Parser_set_value(p, OINT(x));
-}
-
-static int get_escape(char c, char *d){
-    int err = 0;
-    switch(c){
-    case 'a':            *d = '\a'; break;
-    case 'b':            *d = '\b'; break;
-    case 'f':            *d = '\f'; break;
-    case 'n':            *d = '\n'; break;
-    case 'r':            *d = '\r'; break;
-    case 't':            *d = '\t'; break;
-    case 'v':            *d = '\v'; break;
-    case c_escape:       *d = c_escape; break;
-    case c_single_quote: *d = c_single_quote; break;
-    case c_double_quote: *d = c_double_quote; break;
-    default:
-        err = -EINVAL;
-    }
-    return err;
-}
-
-int Parser_ready(Parser *p){
-    return CONSP(p->val) || (p->start_state && CONSP(p->start_state->val));
-}
-
-Sxpr Parser_get_val(Parser *p){
-    Sxpr v = ONONE, w = ONONE;
-    if(CONSP(p->val)){
-    } else if (p->start_state && CONSP(p->start_state->val)){
-        p->val = p->start_state->val;
-        p->val = nrev(p->val);
-        p->start_state->val = ONULL;
-    }  else {
-        goto exit;
-    }
-    w = p->val;
-    v = CAR(w);
-    p->val = CDR(w);
-    hfree(w);
-  exit:
-    return v;
-}
-
-Sxpr Parser_get_all(Parser *p){
-    Sxpr v = ONULL;
-    if(CONSP(p->val)){
-        v = p->val;
-        p->val = ONONE;
-    } else if(p->start_state && CONSP(p->start_state->val)){
-        v = p->start_state->val;
-        p->start_state->val = ONULL;
-        v = nrev(v);
-    }
-    return v;
-}
-
-static int state_comment(Parser *p, char c){
-    int err = 0;
-    if(c == '\n' || Parser_at_eof(p)){
-        Parser_pop(p);
-    } else {
-        err = input_char(p, c);
-    }
-    return err;
-}
-
-static int begin_comment(Parser *p, char c){
-    int err = 0;
-    err = Parser_push(p, state_comment, "comment");
-    if(err) goto exit;
-    err = input_char(p, c);
-  exit:
-    return err;
-}
-
-static int end_string(Parser *p){
-    int err = 0;
-    err = Parser_string(p);
-    if(err) goto exit;
-    err = Parser_return(p);
-  exit:
-    return err;
-}
-
-static int octaldone(Parser *p){
-    int err = 0;
-    char d = (char)(p->state->ival & 0xff);
-    Parser_pop(p);
-    err = Parser_input_char(p, d);
-    return err;
-}
-
-static int octaldigit(Parser *p, int d){
-    int err = 0;
-    p->state->ival *= 8;
-    p->state->ival += d; 
-    p->state->count++;
-    if(err) goto exit;
-    if(p->state->ival < 0 || p->state->ival > 0xff){
-        err = Parser_error(p);
-        goto exit;
-    }
-    if(p->state->count == 3){
-        err = octaldone(p);
-    }
-  exit:
-    return err;
-}
-
-static int state_octal(Parser *p, char c){
-    int err = 0;
-    if(Parser_at_eof(p)){
-        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
-        goto exit;
-    } else if('0' <= c && c <= '7'){
-        err = octaldigit(p, c - '0');
-    } else {
-        err = octaldone(p);
-        if(err) goto exit;
-        Parser_input_char(p, c);
-    }
-  exit:
-    return err;
-}
-
-static int hexdone(Parser *p){
-    int err = 0;
-    char d = (char)(p->state->ival & 0xff);
-    Parser_pop(p);
-    err = Parser_input_char(p, d);
-    return err;
-}
-    
-static int hexdigit(Parser *p, int d){
-    int err = 0;
-    p->state->ival *= 16;
-    p->state->ival += d; 
-    p->state->count++;
-    if(err) goto exit;
-    if(p->state->ival < 0 || p->state->ival > 0xff){
-        err = Parser_error(p);
-        goto exit;
-    }
-    if(p->state->count == 2){
-        err = hexdone(p);
-    }
-  exit:
-    return err;
-}
-    
-static int state_hex(Parser *p, char c){
-    int err = 0;
-    if(Parser_at_eof(p)){
-        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
-        goto exit;
-    } else if('0' <= c && c <= '9'){
-        err = hexdigit(p, c - '0');
-    } else if('A' <= c && c <= 'F'){
-        err = hexdigit(p, c - 'A' + 10);
-    } else if('a' <= c && c <= 'f'){
-        err = hexdigit(p, c - 'a' + 10);
-    } else if(p->state->count){
-        err = hexdone(p);
-        if(err) goto exit;
-        Parser_input_char(p, c);
-    }
-  exit:
-    return err;
-}
-
-static int state_escape(Parser *p, char c){
-    int err = 0;
-    char d;
-    if(Parser_at_eof(p)){
-        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
-        goto exit;
-    }
-    if(get_escape(c, &d) == 0){
-        err = save_char(p, d);
-        if(err) goto exit;
-        Parser_pop(p);
-    } else if(c == 'x'){
-        p->state->fn = state_hex;
-        p->state->ival = 0;
-        p->state->count = 0;
-    } else {
-        p->state->fn = state_octal;
-        p->state->ival = 0;
-        p->state->count = 0;
-        err = Parser_input_char(p, c);
-    }
-  exit:
-    return err;
-}
-
-static int state_string(Parser *p, char c){
-    int err = 0;
-    if(Parser_at_eof(p)){
-        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
-    } else if(c == p->state->delim){
-        err = end_string(p);
-    } else if(c == '\\'){
-        err = Parser_push(p, state_escape, "escape");
-    } else {
-        err = save_char(p, c);
-    }
-    return err;
-}
-
-static int begin_string(Parser *p, char c){
-    int err = 0;
-    err = Parser_push(p, state_string, "string");
-    if(err) goto exit;
-    new_token(p);
-    p->state->delim = c;
-  exit:
-    return err;
-}
-
-static int end_atom(Parser *p){
-    int err = 0;
-    err = Parser_atom(p);
-    if(err) goto exit;
-    err = Parser_return(p);
-  exit:
-    return err;
-}
-
-static int state_atom(Parser *p, char c){
-    int err = 0;
-    if(Parser_at_eof(p)){
-        err = end_atom(p);
-    } else if(is_separator(p, c) ||
-              in_space_class(c) ||
-              in_comment_class(c)){
-        err = end_atom(p);
-        if(err) goto exit;
-        err = Parser_input_char(p, c);
-    } else {
-        err = save_char(p, c);
-    }
-  exit:
-    return err;
-}
-
-static int begin_atom(Parser *p, char c){
-    int err = 0;
-    err = Parser_push(p, state_atom, "atom");
-    if(err) goto exit;
-    new_token(p);
-    err = save_char(p, c);
-  exit:
-    return err;
-}
-
-static int end_data(Parser *p){
-    int err = 0;
-    err = Parser_data(p);
-    if(err) goto exit;
-    err = Parser_return(p);
-  exit:
-    return err;
-}
-
-static int counted_data(Parser *p, char c){
-    int err = 0;
-    err = save_char(p, c);
-    if(err) goto exit;
-    if(token_len(p) == p->state->count){
-        err = end_data(p);
-    }
-  exit:
-    return err;
-}
-
-static int counted_data_count(Parser *p, char c){
-    int err = 0;
-    if(c == p->state->delim){
-        new_token(p);
-        p->state->count = p->state->ival;
-        p->state->fn = counted_data;
-    } else if('0' <= c && c <= '9'){
-        p->state->ival *= 10;
-        p->state->ival += c - '0';
-    } else {
-        err = -EINVAL;
-    }
-    return err;
-}
-
-static int quoted_data(Parser *p, char c){
-    int err = 0;
-    int count = p->state->count;
-    err = save_char(p, c);
-    if(err) goto exit;
-    // Check that buf is longer than delim and
-    // ends with delim. If so, trim delim off and return.
-    if((token_len(p) >= count) &&
-       !memcmp(p->tok_end - count, p->buf, count)){
-        p->tok_end -= count;
-        end_data(p);
-    }
-  exit:
-    return err;
-}
-
-static int quoted_data_delim(Parser *p, char c){
-    // Saves the delim in the token buffer.
-    int err = 0;
-    err = save_char(p, c);
-    if(err) goto exit;
-    if(c == p->state->delim){
-        p->state->fn = quoted_data;
-        p->state->count = token_len(p);
-        // Advance the token pointer past the delim.
-        p->tok = p->tok_end;
-    }
-  exit:
-    return err;
-}
-
-static int state_data(Parser *p, char c){
-    // Quoted data:
-    // <<delim< anything not containing delimiter<delim<
-    // Where 'delim' is anything not containing '<'.
-    // Counted data:
-    // <*nnn..* N bytes
-    // Where nnn... is N in decimal (
-    int err = 0;
-    switch(c){
-    case c_data_count:
-        p->state->delim = c;
-        p->state->fn = counted_data_count;
-        p->state->ival = 0;
-        new_token(p);
-        break;
-    case c_data_quote:
-        p->state->delim = c;
-        p->state->fn = quoted_data_delim;
-        new_token(p);
-        err = save_char(p, c);
-        break;
-    default:
-        err = Parser_error(p);
-        break;
-    }
-    return err;
-}
-
-static int begin_data(Parser *p, char c){
-    int err = 0;
-    err = Parser_push(p, state_data, "data");
-    if(err) goto exit;
-    new_token(p);
-  exit:
-    return err;
-}
-
-static int state_list(Parser *p, char c){
-    int err = 0;
-    dprintf(">\n");
-    if(Parser_at_eof(p)){
-        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
-    } else if(c == c_list_close){
-        p->state->val = nrev(p->state->val);
-        err = Parser_return(p);
-    } else {
-        err = state_start(p, c);
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-    
-}
-
-static int begin_list(Parser *p, char c){
-    return Parser_push(p, state_list, "list");
-}
-
-static int state_start(Parser *p, char c){
-    int err = 0;
-    dprintf(">\n");
-    if(Parser_at_eof(p)){
-        err = Parser_return(p);
-    } else if(in_space_class(c)){
-        //skip
-    } else if(in_comment_class(c)){
-        begin_comment(p, c);
-    } else if(c == c_list_open){
-        begin_list(p, c);
-    } else if(c == c_list_close){
-        err = Parser_error(p);
-    } else if(in_string_quote_class(c)){
-        begin_string(p, c);
-    } else if(c == c_data_open){
-        begin_data(p, c);
-    } else if(in_printable_class(c)){
-        begin_atom(p, c);
-    } else if(c == 0x04){
-        //ctrl-D, EOT: end-of-text.
-        Parser_input_eof(p);
-    } else {
-        err = Parser_error(p);
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-int begin_start(Parser *p, char c){
-    int err = 0;
-    dprintf(">\n");
-    err = Parser_push(p, state_start, "start");
-    if(err) goto exit;
-    p->start_state = p->state;
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-int Parser_input_char(Parser *p, char c){
-    int err = 0;
-    if(Parser_at_eof(p)){
-        //skip;
-    } else {
-        input_char(p, c);
-    }
-    if(!p->state){
-        err = p->begin(p, c);
-        if(err) goto exit;
-    }
-    err = p->state->fn(p, c);
-  exit:
-    return err;
-}
-
-int Parser_input_eof(Parser *p){
-    int err = 0;
-    p->eof = 1;
-    err = Parser_input_char(p, IOSTREAM_EOF);
-    return err;
-}
-
-int Parser_input(Parser *p, char *buf, int buf_n){
-    int err = 0;
-    int i = 0;
-    dprintf("> buf_n=%d\n", buf_n);
-    if(buf_n <= 0){
-        buf_n = 0;
-        err = Parser_input_eof(p);
-        goto exit;
-    }
-    dprintf("> buf=|%*s|\n", buf_n, buf);
-    for(i = 0; i < buf_n; i++){
-        err = Parser_input_char(p, buf[i]);
-        if(err) goto exit;
-    }
-  exit:
-    err = (err < 0 ? err : buf_n);
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-#ifdef SXPR_PARSER_MAIN
-/* Stuff for standalone testing. */
-
-#include "file_stream.h"
-//#include "string_stream.h"
-
-/** Main program for testing.
- * Parses input and prints it.
- *
- * @param argc number of arguments
- * @param argv arguments
- * @return error code
- */
-int main(int argc, char *argv[]){
-    Parser *pin;
-    int err = 0;
-    char buf[1024];
-    int k;
-    Sxpr obj;
-    int i = 0;
-
-    pin = Parser_new();
-    Parser_set_error_stream(pin, iostdout);
-    dprintf("> parse...\n");
-    while(1){
-        k = fread(buf, 1, 100, stdin);
-        if(k>=0){
-            buf[k+1] = '\0';
-        }
-        err = Parser_input(pin, buf, k);
-        while(Parser_ready(pin)){
-            obj = Parser_get_val(pin);
-            printf("obj %d\n", i++);
-            objprint(iostdout, obj, 0); printf("\n");
-        }
-        if(k <= 0) break;
-    }
-    dprintf("> err=%d\n", err);
-    return 0;
-}
-#endif
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/sxpr_parser.h
--- a/tools/vnet/libxutil/sxpr_parser.h Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _XUTIL_SXPR_PARSER_H_
-#define _XUTIL_SXPR_PARSER_H_
-
-#include "sxpr.h"
-#include "iostream.h"
-
-/** @file
- * Sxpr parsing definitions.
- */
-
-/** Initial size of a parser input buffer.
- */
-#define PARSER_BUF_SIZE 512
-
-/** Input buffer size increment (when it's full).
- */
-#define PARSER_BUF_INCREMENT 512
-
-struct Parser;
-typedef int ParserStateFn(struct Parser *, char c);
-
-typedef struct ParserState {
-    struct ParserState *parent;
-    Sxpr val;
-    int ival;
-    int count;
-    char delim;
-    ParserStateFn *fn;
-    char *name;
-} ParserState;
-
-typedef struct Parser {
-    /** Initial state function. */
-    ParserStateFn *begin;
-    /** Parse value. */
-    Sxpr val;
-    /** Error reporting stream (null for no reports). */
-    IOStream *error_out;
-    /** End-of-file flag, */
-    int eof;
-    /** Error flag. Non-zero if there has been a read error. */
-    int err;
-    /** Line number on input (from 1). */
-    int line_no;
-    /** Column number of input (reset on new line). */
-    int char_no;
-    /** Buffer for reading tokens. */
-    char *buf;
-    char *buf_end;
-    char *tok;
-    char *tok_end;
-    /** Line the last token started on. */
-    int tok_begin_line;
-    /** Character number the last token started on. */
-    int tok_begin_char;
-    /** Parsing flags. */
-    int flags;
-    ParserState *state;
-    ParserState *start_state;
-} Parser;
-
-/** Parser error codes. */
-typedef enum {
-    PARSE_ERR_NONE=0,
-    PARSE_ERR_UNSPECIFIED,
-    PARSE_ERR_NOMEM,
-    PARSE_ERR_UNEXPECTED_EOF,
-    PARSE_ERR_TOKEN_TOO_LONG,
-    PARSE_ERR_INVALID_SYNTAX,
-    PARSE_ERR_INVALID_ESCAPE,
-} ParseErrorId;
-
-
-/** Parser flags. */
-enum {
-    /** Convert integer atoms to ints. */
-    PARSE_INT=1,
-};
-
-/** Raise some parser flags.
- *
- * @param in parser
- * @param flags flags mask
- */
-static inline void Parser_flags_raise(Parser *in, int flags){
-    in->flags |= flags;
-}
-
-/** Lower some parser flags.
- *
- * @param in parser
- * @param flags flags mask
- */
-static inline void Parser_flags_lower(Parser *in, int flags){
-    in->flags &= ~flags;
-}
-
-/** Clear all parser flags.
- *
- * @param in parser
- */
-static inline void Parser_flags_clear(Parser *in){
-    in->flags = 0;
-}
-
-static inline int Parser_flags(Parser *in, int flags){
-    return in->flags & flags;
-}
-
-extern void Parser_free(Parser *z);
-extern Parser * Parser_new(void);
-extern int Parser_input(Parser *p, char *buf, int buf_n);
-extern int Parser_input_eof(Parser *p);
-extern int Parser_input_char(Parser *p, char c);
-extern void Parser_set_error_stream(Parser *z, IOStream *error_out);
-
-extern int Parser_error_message(Parser *in, char *buf, int n);
-extern int Parser_has_error(Parser *in);
-extern int Parser_at_eof(Parser *in);
-
-extern int Parser_ready(Parser *p);
-extern Sxpr Parser_get_val(Parser *p);
-extern Sxpr Parser_get_all(Parser *p);
-
-/* Internal parser api. */
-void Parser_pop(Parser *p);
-int Parser_push(Parser *p, ParserStateFn *fn, char *name);
-int Parser_return(Parser *p);
-int Parser_at_eof(Parser *p);
-int Parser_error(Parser *in);
-int Parser_set_value(Parser *p, Sxpr val);
-int Parser_intern(Parser *p);
-int Parser_string(Parser *p);
-int Parser_data(Parser *p);
-int Parser_uint(Parser *p);
-
-char *peek_token(Parser *p);
-char *copy_token(Parser *p);
-void new_token(Parser *p);
-int save_char(Parser *p, char c);
-int token_len(Parser *p);
-
-#endif /* ! _XUTIL_SXPR_PARSER_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/sys_net.c
--- a/tools/vnet/libxutil/sys_net.c     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include "sys_net.h"
-#include "sys_string.h"
-
-#ifdef __KERNEL__
-#  include <linux/errno.h>
-#else
-#  include <errno.h>
-#endif
-
-/** @file
- * All network data are kept in network order and only converted to
- * host order for display. Network data includes IP addresses, port numbers and
- * network masks.
- */
-
-/** Maximum value for a port. */
-#define PORT_MAX 0xffff
-
-/** Convert a number of bits to a network mask
- * for IP addresses. The number of bits must
- * be in the range 1-31.
- *
- * @param n number of bits to set in the mask
- * @return value with n high bits set (in network order)
- */
-unsigned long bits_to_mask(int n){
-    unsigned long mask = (n ? (1 << 31) : 0);
-    int i;
-    for(i=1; i<n; i++){
-        mask |= (mask >> 1);
-    }
-    return htonl(mask);
-}
-
-/** Convert a network mask to a number of bits.
- *
- * @param mask network mask in network order
- * @return number of bits in mask
- */
-int mask_to_bits(unsigned long mask){
-    // Start with n set to the number of bits in the mask. Then reduce n by
-    // the number of low zero bits in the mask.
-    int n = 32;
-    for(mask = ntohl(mask);
-        (mask & 1)==0 && n>0;
-        mask >>= 1){
-        n--;
-    }
-    return n;
-}
-
-/** Get the index of the first occurrence of a character in a string.
- * Stops at end of string or after n characters.
- *
- * @param s input string
- * @param n maximum number of charactes to search
- * @param c character to look for
- * @return index of first occurrence, -1 if not found
- */
-inline static int indexof(const char *s, int n, char c){
-    int i;
-    for(i=0; i<n && *s; i++, s++){
-        if(*s == c) return i;
-    }
-    return -1;
-}
-
-/** Convert an IPv4 address in dot notation into an unsigned long (in network 
order).
- *
- * @param s input string
- * @param address where to put the address
- * @return 0 on success, negative on error
- */
-int get_inet_addr(const char *s, unsigned long *address){
-    // Number of bits in a byte.
-    const int BYTE_BITS = 8;
-    // Number of bytes in a word.
-    const int WORD_BYTES = 4;
-    // Max value for a component of an address.
-    const int ADDR_MAX  = 255;
-    // Separator for components of an address.
-    const char dot = '.';
-
-    int n;
-    unsigned long addr = 0;
-    unsigned long v;
-    int i;
-    int err = -EINVAL;
-    // Bit shift for the current byte.
-    int shift = BYTE_BITS * (WORD_BYTES - 1);
-    char buf[64];
-
-    n = strlen(s);
-    if(n >= sizeof(buf)){
-        goto exit;
-    }
-    for(i=0; i < WORD_BYTES; i++){
-        int idx = indexof(s, n, dot);
-        idx = (idx < 0 ? strlen(s) : idx);
-        strncpy(buf, s, idx); buf[idx]='\0';
-        if(convert_atoul(buf, &v)){
-            goto exit;
-        }
-        if(v < 0 || v > ADDR_MAX){
-            goto exit;
-        }
-        addr |= (v << shift);
-        if(idx == n) break;
-        shift -= BYTE_BITS;
-        s += idx+1;
-    }
-    err = 0;
-  exit:
-    addr = htonl(addr);
-    *address = (err ? 0 : addr);
-    return err;
-}
-
-#ifdef __KERNEL__
-/** Convert an address in network order to IPv4 dot notation.
- * The return value is a static buffer which is overwritten on each call.
- *
- * @param inaddr address (in network order)
- * @return address in dot notation
- */
-char *inet_ntoa(struct in_addr inaddr){
-    static char address[16] = {};
-    uint32_t addr = ntohl(inaddr.s_addr);
-    snprintf(address, sizeof(address), "%d.%d.%d.%d",
-            (unsigned)((addr >> 24) & 0xff),
-            (unsigned)((addr >> 16) & 0xff),
-            (unsigned)((addr >>  8) & 0xff),
-            (unsigned)((addr      ) & 0xff));
-    return address;
-}
-
-
-/** Convert a string in IPv4 dot notation to an int in network order.
- *
- * @param address address in dot notation
- * @param inp result of conversion (in network order)
- * @return 0 on success, error code on error
- */
-int inet_aton(const char *address, struct in_addr *inp){
-    int err = 0; 
-    unsigned long addr;
-    
-    err = get_inet_addr(address, &addr);
-    if(err) goto exit;
-    inp->s_addr = addr;
-  exit:
-    return err;
-}
-#endif
-
-/** Convert a hostname or IPv4 address string to an address in network order.
- *
- * @param name input hostname or address string
- * @param address where to put the address
- * @return 0 if address found OK, nonzero otherwise
- */
-int get_host_address(const char *name, unsigned long *address){
-#ifdef __KERNEL__
-    return get_inet_addr(name, address);
-#else
-    struct hostent *host = gethostbyname(name);
-    if(!host){
-        return -ENOENT;
-    }
-    *address = ((struct in_addr *)(host->h_addr))->s_addr;
-    return 0;
-#endif
-}
-
-/** Convert a service name to a port (in network order).
- *
- * @param name service name
- * @param port where to put the port
- * @return 0 if service port found OK, negative otherwise
- */
-int get_service_port(const char *name, unsigned long *port){
-#ifdef __KERNEL__
-    return -ENOSYS;
-#else
-    struct servent *service;
-    service = getservbyname(name, 0);
-    if(!service){
-        return -EINVAL;
-    }
-    *port = service->s_port;
-    return 0;
-#endif
-}
-
-/** Convert a port number (in network order) to a service name.
- *
- * @param port the port number
- * @return service name if found OK, NULL otherwise
- */
-char *get_port_service(unsigned long port){
-#ifdef __KERNEL__
-    return NULL;
-#else
-    struct servent *service = getservbyport(port, 0);
-    return (service ? service->s_name : NULL);
-#endif
-}
-
-/** Convert a decimal integer or service name to a port (in network order).
- *
- * @param s input to convert
- * @param port where to put the port
- * @return 0 if port found OK, -1 otherwise
- */
-int convert_service_to_port(const char *s, unsigned long *port){
-    int err = 0;
-    unsigned long value;
-    if(convert_atoul(s, &value) == 0){
-        int ok = (0 <= value) && (value <= PORT_MAX);
-        if(ok){
-            value = htons((unsigned short)value);
-        } else {
-            err = -EINVAL;
-        }
-    } else {
-        err = get_service_port(s, &value);
-    }
-    *port = (err ? 0: value);
-    return err;
-}
-
-#define MAC_ELEMENT_N  6 // Number of elements in a MAC address.
-#define MAC_DIGIT_N    2 // Number of digits in an element in a MAC address.
-#define MAC_LENGTH    17 //((MAC_ELEMENT_N * MAC_DIGIT_N) + MAC_ELEMENT_N - 1)
-
-/** Convert a mac address from a string of the form
- * XX:XX:XX:XX:XX:XX to numerical form (an array of 6 unsigned chars).
- * Each X denotes a hex digit: 0..9, a..f, A..F.
- * Also supports using '-' as the separator instead of ':'.
- *
- * @param mac_in string to convert
- * @param mac destination for the value
- * @return 0 on success, -1 on error
- */
-int mac_aton(const char *mac_in, unsigned char *mac){
-    int err = 0;
-    int i, j;
-    const char *p;
-    char sep = 0;
-    unsigned char d;
-    if(!mac_in || strlen(mac_in) != MAC_LENGTH){
-        err = -1;
-        goto exit;
-    }
-    for(i = 0, p = mac_in; i < MAC_ELEMENT_N; i++){
-        d = 0;
-        if(i){
-            if(!sep){
-                if(*p == ':' || *p == '-') sep = *p;
-            }
-            if(sep && *p == sep){
-                p++;
-            } else {
-                err = -1;
-                goto exit;
-            }
-        }
-        for(j = 0; j < MAC_DIGIT_N; j++, p++){
-            if(j) d <<= 4;
-            if(*p >= '0' && *p <= '9'){
-                d += (*p - '0');
-            } else if(*p >= 'A' && *p <= 'F'){
-                d += (*p - 'A') + 10;
-            } else if(*p >= 'a' && *p <= 'f'){
-                d += (*p - 'a') + 10;
-            } else {
-                err = -1;
-                goto exit;
-            }
-        }
-        mac[i] = d;
-    }
-  exit:
-    return err;
-}
-
-/** Convert a MAC address from numerical form to a string.
- *
- * @param mac address to convert
- * @return static string value
- */
-char *mac_ntoa(const unsigned char *mac){
-    static char buf[MAC_LENGTH + 1];
-    int buf_n = sizeof(buf);
-
-    memset(buf, 0, buf_n);
-    snprintf(buf, buf_n, "%02x:%02x:%02x:%02x:%02x:%02x",
-             mac[0], mac[1], mac[2],
-             mac[3], mac[4], mac[5]);
-    buf[buf_n - 1] = '\0';
-    return buf;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/sys_net.h
--- a/tools/vnet/libxutil/sys_net.h     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_SYS_NET_H_
-#define _XUTIL_SYS_NET_H_
-/** @file
- *
- * Replacement for standard network includes.
- * Works in user or kernel code.
- */
-
-extern int get_inet_addr(const char *s, unsigned long *address);
-extern unsigned long bits_to_mask(int n);
-extern int mask_to_bits(unsigned long mask);
-extern int get_host_address(const char *name, unsigned long *address);
-extern int get_service_port(const char *name, unsigned long *port);
-extern char *get_port_service(unsigned long port);
-extern int convert_service_to_port(const char *s, unsigned long *port);
-
-#ifdef __KERNEL__
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h> 
-
-#ifndef htonl
-#define htonl(x) __constant_htonl(x)
-#endif
-
-#ifndef ntohl
-#define ntohl(x) __constant_ntohl(x)
-#endif
-
-#ifndef htons
-#define htons(x) __constant_htons(x)
-#endif
-
-#ifndef ntohs
-#define ntohs(x) __constant_ntohs(x)
-#endif
-
-#include <linux/in.h>
-extern char *inet_ntoa(struct in_addr inaddr);
-extern int inet_aton(const char *address, struct in_addr *inp);
-
-#else
-
-#include <limits.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-
-#endif
-
-extern char *mac_ntoa(const unsigned char *macaddr);
-extern int mac_aton(const char *addr, unsigned char *macaddr);
-
-#endif /* !_XUTIL_SYS_NET_H_ */
-
-
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/sys_string.c
--- a/tools/vnet/libxutil/sys_string.c  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifdef __KERNEL__
-#  include <linux/config.h>
-#  include <linux/module.h>
-#  include <linux/kernel.h>
-#  include <linux/errno.h>
-#else
-#  include <errno.h>
-#endif
-
-#include "allocate.h"
-#include "sys_string.h"
-
-#ifdef __KERNEL__
-
-#define deferr(_err) case _err: return #_err
-
-extern char *strerror(int err)
-{
-    switch(err){
-        deferr(EPERM);
-        deferr(ENOENT);
-        deferr(ESRCH);
-        deferr(EINTR);
-        deferr(EIO);
-        deferr(EINVAL);
-        deferr(ENOMEM);
-        deferr(EACCES);
-        deferr(EFAULT);
-        deferr(EBUSY);
-        
-    default:
-        return "ERROR";
-    }
-}
-
-#endif
-
-/** Set the base to use for converting a string to a number.  Base is
- * hex if starts with 0x, otherwise decimal.
- *
- * @param s input string
- * @param base where to put the base
- * @return rest of s to parse as a number
- */
-inline static const char * convert_set_base(const char *s, int *base){
-    *base = 10;
-    if(s){
-        if(*s=='0'){
-            s++;
-            if(*s=='x' || *s=='X'){
-                *base = 16;
-                s++;
-            }
-        }
-    }
-    return s;
-}
-
-/** Set the sign to use for converting a string to a number.
- * Value is 1 for positive, -1 for negative.
- *
- * @param s input string
- * @param sign where to put the sign
- * @return rest of s to parse as a number
- */
-inline static const char * convert_set_sign(const char *s, int *sign){
-    *sign = 1;
-    if(s){
-        if(*s == '+'){
-            *sign = 1;
-            s++;
-        } else if (*s == '-'){
-            *sign = -1;
-            s++;
-        }
-    }
-    return s;
-}
-
-/** Get the numerical value of a digit in the given base.
- *
- * @param c digit character
- * @param base to use
- * @return numerical value of digit in range 0..base-1 or
- * -1 if not in range for the base
- */
-inline static int convert_get_digit(char c, int base){
-    int d;
-
-    if('0'<=c  && c<='9'){
-        d = c - '0';
-    } else if('a'<=c && c<='f'){
-        d = c - 'a' + 10;
-    } else if('A'<=c && c<='F'){
-        d = c - 'A' + 10;
-    } else {
-        d = -1;
-    }
-    return (d < base ? d : -1);
-}
-
-/** Convert a string to an unsigned long by parsing it as a number.
- * Will accept hex or decimal in usual C syntax.
- *
- * @param str input string
- * @param val where to put the result
- * @return 0 if converted OK, negative otherwise
- */
-int convert_atoul(const char *str, unsigned long *val){
-    int err = 0;
-    unsigned long v = 0;
-    int base;
-    const char *s = str;
-
-    if(!s) {
-        err = -EINVAL;
-        goto exit;
-    }
-    s = convert_set_base(s, &base);
-    for( ; !err && *s; s++){
-        int digit = convert_get_digit(*s, base);
-        if(digit<0){
-            err = -EINVAL;
-            goto exit;
-        }
-        v *= base;
-        v += digit;
-    } 
-  exit:
-    *val = (err ? 0 : v);
-    return err;
-}
-
-/** Convert a string to a long by parsing it as a number.
- * Will accept hex or decimal in usual C syntax.
- *
- * @param str input string
- * @param val where to put the result
- * @return 0 if converted OK, negative otherwise
- */
-int convert_atol(const char *str, long *val){
-    int err = 0;
-    unsigned long v = 0;
-    int base, sign = 1;
-    const char *s = str;
-
-    if(!s) {
-        err = -EINVAL;
-        goto exit;
-    }
-    s = convert_set_sign(s, &sign);
-    s = convert_set_base(s, &base);
-    for( ; !err && *s; s++){
-        int digit = convert_get_digit(*s, base);
-        if(digit<0){
-            err = -EINVAL;
-            goto exit;
-        }
-        v *= base;
-        v += digit;
-    } 
-    if(sign < 0) v = -v;
-  exit:
-    *val = (err ? 0 : v);
-    return err;
-}
-
-/** Combine a directory path with a relative path to produce
- * a new path.
- *
- * @param s directory path
- * @param t relative path
- * @return new combined path s/t
- */
-int path_concat(char *s, char *t, char **val){
-    int err = 0;
-    int sn, tn, vn;
-    char *v;
-    sn = strlen(s);
-    if(sn > 0 && s[sn-1] == '/'){
-        sn--;
-    }
-    tn = strlen(t);
-    if(tn > 0 && t[0] == '/'){
-        tn--;
-    }
-    vn = sn+tn+1;
-    v = (char*)allocate(vn+1);
-    if(!v){
-        err = -ENOMEM;
-        goto exit;
-    }
-    strncpy(v, s, sn);
-    v[sn] = '/';
-    strncpy(v+sn+1, t, tn);
-    v[vn] = '\0';
-  exit:
-    *val = (err ? NULL : v);
-    return err;    
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/sys_string.h
--- a/tools/vnet/libxutil/sys_string.h  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_SYS_STRING_H_
-#define _XUTIL_SYS_STRING_H_
-/** @file
- * Replacement for standard string includes.
- * Works in user or kernel code.
- */
-/*============================================================================*/
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <stdarg.h>
-#include "allocate.h"
-
-extern char *strerror(int err);
-
-#if 0
-static inline int tolower(int c){
-    return (c>='A' && c<='Z' ? (c-'A')+'a' : c);
-}
-#endif
-
-static inline int isalpha(int c){
-    return (c>='A' && c<='Z') || (c>='a' && c<='z');
-}
-
-static inline int isdigit(int c){
-   return (c>='0' && c<='9');
-}
-
-#if 0
-static inline int strcasecmp(const char *s1, const char *s2){
-       int c1, c2;
-
-       do {
-               c1 = tolower(*s1++);
-               c2 = tolower(*s2++);
-       } while (c1 && c1 == c2);
-       return c1 - c2;
-}
-#endif
-
-static inline char * strdup(const char *s){
-    int n = (s ? 1+strlen(s) : 0);
-    char *copy = (n ? allocate(n) : NULL);
-    if(copy){
-        strcpy(copy, s);
-    }
-    return copy;
-}
-
-/*============================================================================*/
-#else
-#include <string.h>
-#include <stdio.h>
-
-#ifndef _GNU_SOURCE
-static inline size_t strnlen(const char *s, size_t n){
-    int k = 0;
-    if(s){
-       for(k=0; *s && k<n; s++, k++){}
-    }
-    return k;
-}
-#endif
-
-#endif
-/*============================================================================*/
-
-extern int convert_atoul(const char *s, unsigned long *v);
-extern int convert_atol(const char *s, long *v);
-extern int path_concat(char *s, char *t, char **val);
-
-#endif /* !_XUTIL_SYS_STRING_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/util.c
--- a/tools/vnet/libxutil/util.c        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2002 - 2004 Mike Wray <mike.wray@xxxxxx>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include "sys_net.h"
-#include "sys_string.h"
-
-#ifndef __KERNEL__
-#  include <grp.h>   
-#  include <pwd.h>  
-#endif
-
-#include "util.h"
-
-
-/** @file Various utility functions.
- */
-
-/** Print an address (in network order) as an IPv4 address string
- * in dot notation.
- *
- * @param io where to print address
- * @param address to print (in network order)
- * @return bytes printed
- */
-int print_address(IOStream *io, unsigned long address){
-#ifdef __KERNEL__
-    address = ntohl(address);
-    return IOStream_print(io, "%u.%u.%u.%u", 
-                          (unsigned)((address >> 24) & 0xff),
-                          (unsigned)((address >> 16) & 0xff),
-                          (unsigned)((address >>  8) & 0xff),
-                          (unsigned)((address      ) & 0xff));
-#else
-    struct in_addr inaddr = { s_addr: address };
-    return IOStream_print(io, inet_ntoa(inaddr));
-#endif
-}
-
-/** Get the protocol number for a protocol.
- *
- * @param name protocol name
- * @param protocol where to put the protocol number
- * @return 0 if OK, error otherwise
- */  
-int get_protocol_number(char *name, unsigned long *protocol){
-#ifdef __KERNEL__
-    return -1;
-#else
-    struct protoent *proto = getprotobyname(name);
-    if(!proto){
-       return -1;
-    }
-    *protocol = proto->p_proto;
-    return 0;
-#endif
-}
-
-/** Get the protocol name for a protocol number.
- *
- * @param protocol number
- * @return name or null
- */
-char *get_protocol_name(unsigned long protocol){
-#ifdef __KERNEL__
-    return 0;
-#else
-    struct protoent *proto = getprotobynumber(protocol);
-    if(!proto){
-       return 0;
-    }
-    return proto->p_name;
-#endif
-}
-
-/** Get the host name for an address.
- *
- * @param addr address
- * @return host name or null
- */
-char *get_host_name(unsigned long addr){
-#ifdef __KERNEL__
-    return 0;
-#else
-    struct in_addr inaddr;
-    struct hostent *host = 0;
-
-    inaddr.s_addr = addr;
-    host = gethostbyaddr((char*)&inaddr, sizeof(inaddr), AF_INET);
-    if(!host) return NULL;
-    return host->h_name;
-#endif
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/libxutil/util.h
--- a/tools/vnet/libxutil/util.h        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2002 - 2004 Mike Wray <mike.wray@xxxxxx>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _XEN_LIB_UTIL_H_
-#define _XEN_LIB_UTIL_H_
-
-#include "iostream.h"
-
-extern int print_address(IOStream *io, unsigned long address);
-extern int get_protocol_number(char *name, unsigned long *protocol);
-extern char *get_protocol_name(unsigned long protocol);
-extern char *get_host_name(unsigned long addr);
-
-#endif /* ! _XEN_LIB_UTIL_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/scripts/Makefile
--- a/tools/vnet/scripts/Makefile       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-# -*- mode: Makefile; -*-
-#============================================================================
-XEN_ROOT        = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-.PHONY: all
-all:
-
-.PHONY: install
-install:
-       $(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
-       $(INSTALL_PROG) vn $(DESTDIR)$(SBINDIR)
-
-.PHONY: clean
-clean:
diff -r 223f61702bda -r 28f04a659506 tools/vnet/scripts/vn
--- a/tools/vnet/scripts/vn     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,901 +0,0 @@
-#!/usr/bin/env python2.4
-#  -*- mode: python; -*-
-#============================================================================
-# Copyright (C) 2005, 2006 Mike Wray <mike.wray@xxxxxx>
-#
-# This library is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-#============================================================================
-
-# Vnet (network virtualization) control utility.
-
-import os
-import os.path
-import re
-import socket
-import sys
-from getopt import getopt, GetoptError
-
-from xen.xend import sxp
-from xen.xend.PrettyPrint import prettyprint
-
-# Path of unix-domain socket to vnetd.
-VNETD_PATH = "/tmp/vnetd"
-
-def vnetd_running():
-    return os.path.exists(VNETD_PATH)
-
-def vnetd_open():
-    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-    sock.connect(VNETD_PATH)
-    fi = sock.makefile('r', 0)
-    fo = sock.makefile('w', 0)
-    return (fi, fo)
-
-os.defpath += ':/sbin:/usr/sbin:/usr/local/sbin'
-CMD_IFCONFIG = 'ifconfig'
-CMD_BRCTL    = 'brctl'
-
-opts = None
-
-class Opts:
-
-    def __init__(self, **kwds):
-        for (k, v) in kwds.items():
-            setattr(self, k, v)
-
-opts = Opts(verbose=False, dryrun=False)
-
-def set_opts(val):
-    global opts
-    opts = val
-    return opts
-
-def cmd(prog, *args):
-    """Execute command 'prog' with 'args', optionally printing the command.
-    """
-    global opts
-    command = " ".join([ prog ] + map(str, args))
-    if opts.verbose:
-        print command
-    if not opts.dryrun:
-        os.system(command)
-
-def vif_bridge_add(bridge, vif):
-    """Add a network interface to a bridge.
-    """
-    cmd(CMD_BRCTL, 'addif', bridge, vif)
-
-def vif_bridge_rem(bridge, vif):
-    """Remove a network interface from a bridge.
-    """
-    cmd(CMD_BRCTL, 'delif', bridge, vif)
-
-def bridge_create(bridge, **kwd):
-    """Create a bridge.
-    Defaults hello time to 0, forward delay to 0 and stp off.
-    """
-    cmd(CMD_BRCTL, 'addbr', bridge)
-    if kwd.get('hello', None) is None:
-        kwd['hello'] = 0
-    if kwd.get('fd', None) is None:
-        kwd['fd'] = 0
-    if kwd.get('stp', None) is None:
-        kwd['stp'] = 'off'
-    bridge_set(bridge, **kwd)
-    cmd(CMD_IFCONFIG, bridge, "up")
-
-def bridge_set(bridge, hello=None, fd=None, stp=None):
-    """Set bridge parameters.
-    """
-    if hello is not None:
-        cmd(CMD_BRCTL, 'sethello', bridge, hello)
-    if fd is not None:
-        cmd(CMD_BRCTL, 'setfd', bridge, fd)
-    if stp is not None:
-        cmd(CMD_BRCTL, 'stp', bridge, stp)
-
-def bridge_del(bridge):
-    """Delete a bridge.
-    """
-    cmd(CMD_IFCONFIG, bridge, 'down')
-    cmd(CMD_BRCTL, 'delbr', bridge)
-
-class Bridge:
-    # Network interfaces are at /sys/class/net/*.
-    # A bridge interface has ./bridge dir, ./brif is dir of bridged interfaces
-    # (symlinks to the brport dirs).
-    # If an interface is bridged ./brport is bridged port info,
-    # brport/bridge is a symlink to the bridge.
-
-    INTERFACE_DIR = "/sys/class/net"
-
-    def isBridge(klass, dev):
-        """Test if a network interface is a bridge.
-        """
-        devdir = os.path.join(klass.INTERFACE_DIR, dev)
-        brdir = os.path.join(devdir, "bridge")
-        try:
-            os.stat(brdir)
-            return True
-        except:
-            return False
-
-    isBridge = classmethod(isBridge)
-
-    def getInterfaces(klass):
-        """Get a list of the network interfaces.
-        """
-        try:
-            v = os.listdir(klass.INTERFACE_DIR)
-            v.sort()
-            return v
-        except:
-            return []
-
-    getInterfaces = classmethod(getInterfaces)
-
-    def getInterfaceAddr(klass, intf):
-        intfdir = os.path.join(klass.INTERFACE_DIR, intf)
-        addrfile = os.path.join(intfdir, "address")
-        try:
-            f = file(addrfile, "rb")
-        except Exception, ex:
-            #print ex
-            return None
-        try:
-            return f.readline().strip()
-        finally:
-            f.close()
-
-    getInterfaceAddr = classmethod(getInterfaceAddr)
-
-    def getBridges(klass):
-        """Get a list of the bridges.
-        """
-        return [ dev for dev in klass.getInterfaces() if klass.isBridge(dev) ]
-
-    getBridges = classmethod(getBridges)
-
-    def getBridgeInterfaces(klass, dev):
-        """Get a list of the interfaces attached to a bridge.
-        """
-        devdir = os.path.join(klass.INTERFACE_DIR, dev)
-        intfdir = os.path.join(devdir, "brif")
-        try:
-            v = os.listdir(intfdir)
-            v.sort()
-            return v
-        except:
-            return []
-
-    getBridgeInterfaces = classmethod(getBridgeInterfaces)
-
-    def getBridge(klass, dev):
-        """Get the bridge an interface is attached to (if any).
-        """
-        devdir = os.path.join(klass.INTERFACE_DIR, dev)
-        brfile = os.path.join(devdir, "brport/bridge")
-        try:
-            brpath = os.readlink(brfile)
-            return os.path.basename(brpath)
-        except:
-            return None
-
-    getBridge = classmethod(getBridge)
-
-def vnet_cmd(expr):
-    """Send a command expression to the vnet implementation.
-    """
-    if vnetd_running():
-        (fi, fo) = vnetd_open()
-    else:
-        fi = None
-        fo = file("/proc/vnet/policy", "wb")
-    try:
-        sxp.show(expr, fo)
-        fo.flush()
-    finally:
-        if fi: fi.close()
-        if fo: fo.close()
-
-def varp_flush():
-    """Flush the varp cache.
-    """
-    expr = ['varp.flush']
-    return vnet_cmd(expr)
-
-def vif_add(vnetid, vmac):
-    """Tell the vnet implementation to add a vif to a vnet.
-    """
-    expr = ['vif.add', ['vnet', vnetid], ['vmac', vmac]]
-    return vnet_cmd(expr)
-
-def vif_del(vnetid, vmac):
-    """Tell the vnet implementation to delete a vif from a vnet.
-    """
-    expr = ['vif.del', ['vnet', vnetid], ['vmac', vmac]]
-    return vnet_cmd(expr)
-
-def vnet_add(vnetid, vnetif=None, security=None):
-    """Tell the vnet implementation to add a vnet.
-    """
-    expr = ['vnet.add', ['id', vnetid]]
-    if vnetif:
-        expr.append(['vnetif', vnetif])
-    if security:
-        expr.append(['security', security])
-    return vnet_cmd(expr)
-
-def peer_add(addr, port=None):
-    expr = ['peer.add', ['addr', addr]]
-    if port:
-        expr.append(['port', port])
-    return vnet_cmd(expr)
-    
-def peer_del(addr, port=None):
-    expr = ['peer.del', ['addr', addr]]
-    return vnet_cmd(expr)
-
-def vnet_del(vnetid):
-    """Tell the vnet implementation to delete a vnet.
-    """
-    expr = ['vnet.del', ['id', vnetid]]
-    return vnet_cmd(expr)
-
-def vnet_create(vnetid, vnetif=None, bridge=None, security=None):
-    """Tell the vnet implementation to add a vnet.
-    If 'bridge' is non-null, create the bridge and add the vnet interface
-    to it.
-    """
-    vnet_add(vnetid, vnetif=vnetif, security=security)
-    val = vnet_lookup(vnetid)
-    if not vnetif:
-        vnetif = sxp.child_value(val, "vnetif")
-    vmac = get_mac(vnetif)
-    emac = get_mac("eth0") or get_mac("eth1") or get_mac("eth2")
-    if emac and vmac != emac:
-        set_mac(vnetif, emac)
-    cmd(CMD_IFCONFIG, vnetif, 'up')
-    if bridge:
-        bridge_create(bridge)
-        vif_bridge_add(bridge, vnetif)
-    return val
-        
-def vnet_delete(vnet, delbridge=False):
-    """Tell the vnet implementation to delete a vnet.
-    If the vnet interface is attached to a bridge,
-    remove it from the bridge, and if delbridge is true
-    delete the bridge.
-    """
-    v = vnet_lookup(vnet)    
-    if not v:
-        raise GetoptError("vnet not found: %s" % vnet)
-    vnetid = sxp.child_value(v, "id")
-    vnetif = sxp.child_value(v, "vnetif")
-    bridge = Bridge.getBridge(vnetif)
-    if bridge:
-        vif_bridge_rem(bridge, vnetif)
-        if delbridge:
-            bridge_del(bridge)
-    return vnet_del(vnetid)
-
-def get_mac(intf):
-    """Get the mac address of an interface.
-    """
-    try:
-        return Bridge.getInterfaceAddr(intf)
-    except:
-        pass
-
-    hwre = re.compile(".*\s+HWaddr\s+(?P<mac>\S*)\s+.*")
-    fin = os.popen("%s %s" % (CMD_IFCONFIG, intf), 'r')
-    try:
-        for x in fin:
-            m = hwre.match(x)
-            if not m:
-                continue
-            info = m.groupdict()
-            return info['mac']
-        return None
-    finally:
-        fin.close()
-
-def set_mac(intf, mac):
-    cmd(CMD_IFCONFIG, intf, 'down')
-    cmd(CMD_IFCONFIG, intf, 'hw', 'ether', mac)
-    cmd(CMD_IFCONFIG, intf, 'up')
-
-def get_addr(host):
-    return socket.gethostbyname(host)
-
-def get_port(srv):
-    return srv
-
-def vnetidof(v):
-    """Normalise a vnet id. Adds leading 0 fields to make up 8 if
-    there aren't enough. Pads all fields to 4 hex digits.
-    """
-    try:
-        l = v.split(":")
-        l = [ int(x or 0, 16) for x in l ]
-        l = [ 0 ] * (8 - len(l)) + l
-        return ":".join([ "%04x" % x for x in l ])
-    except:
-        return None
-
-def vnet_lookup(vnet, vnets=None):
-    """Find the vnet with the given vnet id or vnet interface.
-
-    @param vnet id or interface
-    @param vnets list of vnet info to use (get from implementation if None)
-    @return vnet info or None if not found
-    """
-    vnetid = vnetidof(vnet)
-    if vnets is None:
-        vnets = vnet_list()
-    for v in vnets:
-        vid = sxp.child_value(v, "id")
-        if vid == vnet or vid == vnetid:
-            return v
-        if sxp.child_value(v, "vnetif") == vnet:
-            return v
-    return None
-
-def get_vnetid(vnet):
-    """Get the normalised vnet id of the given vnet id or vnet interface.
-    Raises an error if the vnet cannot be found.
-    """
-    v = vnet_lookup(vnet)
-    if not v:
-        raise GetoptError("vnet not found: %s" % vnet)
-    vnetid = sxp.child_value(v, "id")
-    return vnetid
-
-def vif_list():
-    """Get the list of vif info from the vnet implementation.
-    """
-    if vnetd_running():
-        (fi, fo) = vnetd_open()
-        sxp.show(['vif.list'], fo)
-        fo.flush()
-    else:
-        fi = file("/proc/vnet/vifs")
-        fo = None
-    try:
-        return sxp.parse(fi) or []
-    finally:
-        if fi: fi.close()
-        if fo: fo.close()
-
-def vnets_filter(vnetlist, vnets):
-    """Filter a list of vnet info by a list of vnet ids or interfaces.
-    """
-    if vnets is None:
-        val = vnetlist
-    else:
-        val = []
-        for x in vnets:
-            v = vnet_lookup(x, vnets=vnetlist)
-            if not v:
-                continue
-            val.append(v)
-    return val
-
-def vnet_list(vnets=None):
-    """Get the list of vnet info from the vnet implementation,
-    sorted by vnet id.
-
-    @param vnets list of vnet ids or interfaces to filter the results by
-    """
-    if vnetd_running():
-        (fi, fo) = vnetd_open()
-        sxp.show(['vnet.list'], fo)
-        fo.flush()
-    else:
-        fi = file("/proc/vnet/vnets")
-        fo = None
-    try:
-        val = vnets_filter(sxp.parse(fi) or [], vnets)
-        val.sort(lambda x, y:
-                   cmp(sxp.child_value(x, "id"),
-                       sxp.child_value(y, "id")))
-        return val
-    finally:
-        if fi: fi.close()
-        if fo: fo.close()
-        
-def vnif_list(vnets=None):
-    """Get the list of vnet interface names from the vnet implementation.
-
-    @param vnets list of vnet ids or interfaces to filter the results by
-    """
-    vnifs = []
-    for v in vnet_list(vnets=vnets):
-        vnetif = sxp.child_value(v, "vnetif")
-        if vnetif:
-            vnifs.append(vnetif)
-    return vnifs
-        
-def varp_list():
-    """Get the list of varp info from the vnet implementation.
-    """
-    if vnetd_running():
-        (fi, fo) = vnetd_open()
-        sxp.show(['varp.list'], fo)
-        fo.flush()
-    else:
-        fi = file("/proc/vnet/varp")
-        fo = None
-    try:
-        return sxp.parse(fi) or []
-    finally:
-        if fi: fi.close()
-        if fo: fo.close()
-
-def peer_list():
-    if vnetd_running():
-        (fi, fo) = vnetd_open()
-        sxp.show(['peer.list'], fo)
-        fo.flush()
-    else:
-        fi = file("/proc/vnet/peers")
-        fo = None
-    try:
-        return sxp.parse(fi) or []
-    finally:
-        if fi: fi.close()
-        if fo: fo.close()
-
-class Opt:
-    """Declares command-line options for a command.
-    """
-
-    def getopt(klass, argv, opts, args):
-        """Get options and args from argv.
-        The value opts in the return value has an attribute for
-        eacho option or arg. The value args in the return value
-        is the remaining arguments.
-
-        @param argv arguments
-        @param opts option specifiers (list of Opt objects)
-        @param args arg specififiers (list of Arg objects)
-        @return (opts, args)
-        """
-        shortopts = "".join([ x.optShort() for x in opts ])
-        longopts  = [ x.optLong() for x in opts ]
-        (ovals, oargs) = getopt(argv[1:], shortopts, longopts)
-        odir = Opts()
-        for x in opts:
-            x.setDefault(odir)
-        for (k, v) in ovals:
-            for x in opts:
-                x.setOpt(k, v, odir)
-        argc = len(oargs)
-        if len(oargs) < len(args):
-            raise GetoptError("insufficient arguments for %s" % argv[0])
-        for (x, v) in zip(args, oargs):
-            x.setArg(v, odir)
-        return (odir, oargs[len(args): ])
-
-    getopt = classmethod(getopt)
-
-    def gethelp(klass, opts, args):
-        l = []
-        for x in opts:
-            l.append(x.help())
-        for x in args:
-            l.append(x.help())
-        return " ".join(l)
-
-    gethelp = classmethod(gethelp)
-
-    """A command=-line option.
-
-    @param name option name (this attribute is set to value in opts)
-    @param short short option flag (single-character string)
-    @param long long option name (defaults to option name, pass "" to suppress)
-    @param arg argument name (option has no arg if not specified)
-    """
-    def __init__(self, name, short=None, long=None, arg=False):
-        self.name = name
-        self.short = short
-        if long is None:
-            long = name
-        elif not long:
-            long = None
-        self.long = long
-        self.arg = arg
-
-    def help(self):
-        s = self.keyShort()
-        l = self.keyLong()
-        if s and l:
-            return "[%s | %s]" % (s, l)
-        else:
-            return s or l
-
-    def keyShort(self):
-        if self.short:
-            return "-%s" % self.short
-        else:
-            return None
-
-    def keyLong(self):
-        if self.long:
-            return "--%s" % self.long
-        else:
-            return None
-
-    def optLong(self):
-        if not self.long:
-            return None
-        if self.arg:
-            return "%s=" % self.long
-        else:
-            return self.long
-
-    def optShort(self):
-        if not self.short:
-            return None
-        if self.arg:
-            return "%s:" % self.short
-        else:
-            return self.short
-
-    def setDefault(self, vals):
-        if self.arg:
-            setattr(vals, self.name, None)
-        else:
-            setattr(vals, self.name, False)
-
-    def setOpt(self, k, v, vals):
-        if k in [ self.keyShort(), self.keyLong() ]:
-            if self.arg:
-                setattr(vals, self.name, v)
-            else:
-                if v not in [ None, '' ]:
-                    raise GetoptError("option %s does not take an argument" % 
k)
-                setattr(vals, self.name, True)
-
-class Arg:
-
-    """A command-line parameter. Args get their values from arguments
-    left over after option processing and are assigned in order.
-    The value is accessible as the attribute called 'name' in opts.
-
-    @param name argument name
-    """
-    def __init__(self, name):
-        self.name = name
-
-    def setArg(self, v, vals):
-        setattr(vals, self.name, v)
-
-    def help(self):
-        return "<%s>" % self.name
-            
-class VnMain:
-
-    """Methods beginning with this prefix are commands.
-    They must all have arguments like this:
-
-    op_foo(self, argv, args, opts)
-
-    argv: original command-line arguments
-    args: arguments left after option processing
-    opts: option and arg values (accessible as attributes)
-
-    Method options are specified by setting attribute
-    .opts on the method to a list of Option objects.
-    For args set .args to a list of Arg objects.
-    Use .use for short usage string, .help for long help.
-
-    Each option or arg defines an attribute in opts. For example
-    an option with name 'foo' is accessible as 'opts.foo'.
-    """
-    opPrefix = "op_"
-
-    def __init__(self, argv):
-        if argv:
-            self.name = argv[0]
-        else:
-            self.name = "vn"
-        self.argv = argv
-        self.argc = len(argv)
-
-    def error(self, v):
-        print >>sys.stderr, "%s: %s" % (self.name, v)
-        sys.exit(1)
-        
-    def getFunction(self, opname):
-        key = self.opPrefix + opname.replace("-", "_")
-        fn = getattr(self, key, None)
-        if not fn:
-            raise ValueError("unknown command: %s" % opname)
-        return fn
-    
-    def main(self):
-        if self.argc < 2:
-            args = ["help"]
-        else:
-            args = self.argv[1:]
-        try:
-            fn = self.getFunction(args[0])
-        except ValueError, ex:
-            self.error(ex)
-        try:
-            fnopts = self.getOpts(fn)
-            fnargs = self.getArgs(fn)
-            (opts, parms) = Opt.getopt(args, fnopts, fnargs)
-            return fn(args, parms, opts)
-        except GetoptError, ex:
-            self.error(ex)
-        except ValueError, ex:
-            self.error(ex)
-        except Exception, ex:
-            import traceback; traceback.print_exc()
-            self.error(ex)
-
-    def getOpts(self, meth):
-        return getattr(meth, "opts", [])
-    
-    def getArgs(self, meth):
-        return getattr(meth, "args", [])
-    
-    def getUse(self, meth):
-        return getattr(meth, "use", "")
-    
-    def getHelp(self, meth):
-        return getattr(meth, "help", "") or self.getUse(meth)
-
-    def fnHelp(self, meth):
-        return Opt.gethelp(self.getOpts(meth), self.getArgs(meth))
-
-    def printHelp(self, fn, opt_long):
-        meth = getattr(self, fn)
-        opname = fn[len(self.opPrefix):].replace("_", "-")
-        if opt_long:
-            help = self.getHelp(meth)
-            print "\n  %s" % opname
-            if help:
-                print "%s" % help
-        else:
-            use = self.getUse(meth)
-            print "  %s %s" % (opname, self.fnHelp(meth))
-            if use:
-                print "\t\t%s" % use
-
-    def show_vnif(self, dev):
-        cmd(CMD_IFCONFIG, dev)
-        bridge = Bridge.getBridge(dev)
-        if bridge:
-            print "          Bridge:", bridge
-            interfaces = Bridge.getBridgeInterfaces(bridge)
-            if dev in interfaces:
-                interfaces.remove(dev)
-            if interfaces:
-                print "          Interfaces:", ", ".join(interfaces)
-            print
-
-    def op_help(self, argv, args, opts):
-        if opts.long:
-            print '%s <command> <options>' % self.name
-            print self.long_help
-        else:
-            print '%s:' % self.name
-        l = dir(self)
-        l.sort()
-        for fn in l:
-            if fn.startswith(self.opPrefix):
-                self.printHelp(fn, opts.long)
-        print
-
-    op_help.opts = [ Opt('long', short='l') ]
-
-    def op_vnets(self, argv, args, opts):
-        vnets = vnet_list(vnets=args or None)
-        for v in vnets:
-            prettyprint(v, width=50)
-            print
-            if not opts.long:
-                continue
-            vnif = sxp.child_value(v, "vnetif")
-            if not vnif:
-                continue
-            self.show_vnif(vnif)
-        if opts.all:
-            vnetids = {}
-            for v in vnets:
-                vnetids[sxp.child_value(v, "id")] = v
-            for v in vif_list():
-                vnet = sxp.child_value(v, "vnet")
-                if vnet not in vnetids:
-                    continue
-                prettyprint(v)
-                print
-            for v in varp_list():
-                prettyprint(v)
-                print
-
-    op_vnets.opts = [ Opt('all', short='a'), Opt('long', short='l') ]
-
-    def op_vnifs(self, argv, args, opts):
-        vnifs = vnif_list(vnets=args or None)
-        for vnif in vnifs:
-            self.show_vnif(vnif)
-
-    def op_vifs(self, argv, args, opts):
-        for v in vif_list():
-            prettyprint(v)
-            print
-
-    def op_varp(self, argv, args, opts):
-        for v in varp_list():
-            prettyprint(v)
-            print
-
-    def op_varp_flush(self, argv, args, opts):
-        varp_flush()
-
-    def op_vnet_create(self, argv, args, opts):
-        return vnet_create(opts.vnet,
-                           vnetif=opts.vnetif,
-                           bridge=opts.bridge,
-                           security=opts.security)
-
-    op_vnet_create.args = [ Arg('vnet') ]
-    op_vnet_create.opts = [ Opt('security', short='s', arg="SECURITY"),
-                            Opt('bridge', short='b', arg="BRIDGE"),
-                            Opt('vnetif', short='v', arg="VNETIF") ]
-
-    def op_vnet_delete(self, argv, args, opts):
-        vnetid = get_vnetid(opts.vnet)
-        return vnet_delete(vnetid, delbridge=opts.bridge)
-
-    op_vnet_delete.args = [ Arg('vnet') ]
-    op_vnet_delete.opts = [ Opt('bridge', short='b') ]
-
-    def op_vif_add(self, argv, args, opts):
-        vnetid = get_vnetid(opts.vnet)
-        if opts.interface:
-            vmac = get_mac(opts.vmac)
-            if not vmac:
-                raise ValueError("interface not found: %s" % opts.vmac)
-        else:
-            vmac = opts.vmac
-        return vif_add(vnetid, vmac)
-
-    op_vif_add.args = [ Arg('vnet'), Arg('vmac') ]
-    op_vif_add.opts = [ Opt('interface', short='i') ]
-
-    def op_vif_delete(self, argv, args, opts):
-        vnetid = get_vnetid(opts.vnet)
-        if opts.interface:
-            vmac = get_mac(opts.vmac)
-        else:
-            vmac = opts.vmac
-        return vif_del(vnetid, vmac)
-
-    op_vif_delete.args = [ Arg('vnet'), Arg('vmac') ]
-    op_vif_delete.opts = [ Opt('interface', short='i') ]
-
-    def op_peer_add(self, argv, args, opts):
-        addr = get_addr(opts.addr)
-        if(opts.port):
-            port = get_port(opts.port)
-        else:
-            port = None
-        return peer_add(addr, port)
-        
-    op_peer_add.args = [ Arg('addr') ]
-    op_peer_add.opts = [ Opt('port', short='p') ]
-    
-    def op_peer_delete(self, argv, args, opts):
-        addr = get_addr(opts.addr)
-        return peer_del(addr)
-
-    op_peer_delete.args = [ Arg('addr') ]
-    
-    def op_peers(self, argv, args, opts):
-        for v in peer_list():
-            prettyprint(v)
-            print
-
-    def op_bridges(self, argv, args, opts):
-        if opts.long:
-            for bridge in Bridge.getBridges():
-                cmd(CMD_IFCONFIG, bridge)
-                interfaces = Bridge.getBridgeInterfaces(bridge)
-                if interfaces:
-                    print "          Interfaces:", ", ".join(interfaces)
-                    print
-        else:
-            for bridge in Bridge.getBridges():
-                print bridge,
-                interfaces = Bridge.getBridgeInterfaces(bridge)
-                if interfaces:
-                    print ":", ", ".join(interfaces)
-                else:
-                    print
-            
-    op_bridges.opts = [ Opt('long', short='l') ]
-
-    def op_insmod(self, argv, args, opts):
-        """Insert the vnet kernel module."""
-        cmd("/etc/xen/scripts/vnet-insert", *args)
-
-    long_help          = """Control utility for vnets (virtual networking).
-Report bugs to Mike Wray <mike.wray@xxxxxx>.
-"""
-
-    op_help.use        = "Print help."
-    op_help.help       = "Print help, long help if the option -l or --long is 
given."
-
-    op_vnets.use       = """Print vnets."""
-    op_vnets.help      = """Print vnet information, where options are:
-    -a, -all           Print vnets, vifs and varp info.
-    -l, --long         Print ifconfigs for vnet interfaces."""
-
-    op_vifs.use        = "Print vifs."
-
-    op_vnifs.use       = "Print ifconfigs for vnet network interfaces."
-
-    op_varp.use        = "Print varp info and entries in the varp cache."
-
-    op_varp_flush.use  = "Flush the varp cache."
-    
-    op_vnet_create.use = "Create a vnet."
-
-    op_vnet_delete.use = "Delete a vnet."
-    op_vnet_delete.help = """Delete a vnet.
-    -b, --bridge       Delete the bridge the vnet interface is attached to.
-    """
-
-    op_vif_add.use     = "Add a vif to a vnet."
-    op_vif_add.help    = """Add a vif to a vnet. Not usually needed as vifs
-are added automatically.
-    -i, --interface    The vmac is the name of an interface to get the mac 
from."""
-
-    op_vif_delete.use  = "Delete a vif from a vnet."
-    op_vif_delete.help = """Delete a vif from a vnet. Not usually needed as 
vifs
-are removed periodically.
-    -i, --interface    The vmac is the name of an interface to get the mac 
from."""
-
-    op_peer_add.use    = "Add a peer."
-    op_peer_add.help   = """Add a peer: <addr> <port>
-Vnets use multicast to discover interfaces, but networks are often configured
-not to forward multicast. Vnets forward multicasts to peers using UDP.
-Only add peers if multicasts are not working, check with
-
-ping -b 224.10.0.1
-
-Only add peers at one machine in a subnet, otherwise you may cause forwarding
-loops.
-"""
-
-    op_peer_delete.use = "Delete a peer."
-    op_peer_delete.help= "Delete a peer: <addr>"
-
-    op_peers.use       = "List peers."
-    op_peers.help      = "List peers."
-
-    op_bridges.use     = "Print bridges."
-
-    op_insmod.use      = "Insert the vnet kernel module, optionally with 
parameters."
-
-if __name__ == "__main__":
-    vn = VnMain(sys.argv)
-    vn.main()
-    
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/00README
--- a/tools/vnet/vnet-module/00README   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-Vnet module for network virtualization.
-Mike Wray <mike.wray@xxxxxx>
-
-*) Compiling
-The vnet module can be compiled for 2.4 or 2.6 series kernels.
-The makefiles  use the following variables, which
-can be set in your env or on the make command line:
-
-LINUX_SERIES:   linux release to compile for: 2.4, or 2.6 (default).
-XEN_ROOT:       root of the xen tree containing kernel source.
-KERNEL_VERSION: kernel version, default got from XEN_ROOT.
-KERNEL_SRC:     path to kernel source, default build-linux-<VERSION> 
-                under XEN_ROOT.
-
-*) For 2.4 kernel
-
-To compile from scratch:
-
-make clean
-make LINUX_SERIES=2.4
-
-This will build vnet_module.o in the current directory.
-To install the module use
-
-make LINUX_SERIES=2.4 install
-
-*) For 2.6 kernel
-
-To compile from scratch:
-
-make clean
-make
-
-This will build vnet_module.ko in the current directory.
-To install the module use
-
-make install
-
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/Makefile
--- a/tools/vnet/vnet-module/Makefile   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-# -*- mode: Makefile; -*-
-#============================================================================
-#
-# Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free software Foundation, Inc.,
-# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
-#============================================================================
-
-ifndef VNET_ROOT
-export VNET_ROOT = $(shell cd .. && pwd)
-include $(VNET_ROOT)/Make.env
-endif
-
-#============================================================================
-ifeq ($(src),)
-
-include Makefile-$(LINUX_SERIES)
-
-#============================================================================
-else
-#============================================================================
-# This section is for the 2.6 kbuild.
-
-#$(warning KBUILD_EXTMOD $(KBUILD_EXTMOD))
-#$(warning src $(src))
-#$(warning obj $(obj))
-
-include $(src)/Makefile.vnet
-
-obj-m = vnet_module.o
-vnet_module-objs = $(VNET_OBJ)
-vnet_module-objs += $(VNET_LIB_OBJ)
-
-#----------------------------------------------------------------------------
-# The fancy stuff in the kernel build defeats 'vpath %.c' so we can't
-# use that to get the lib files compiled.
-# Setup explicit rules for them using the kbuild C compile rule.
-
-# File names in the lib dir.
-remote_srcs = $(foreach file,$(VNET_LIB_SRC),$(LIBXUTIL_DIR)/$(file))
-
-# Equivalent file names here.
-local_srcs = $(foreach file,$(VNET_LIB_SRC),$(src)/$(file))
-
-# Objects for the local names.
-local_objs = $(local_srcs:.c=.o)
-
-# Make the local objects depend on compiling the remote sources.
-$(local_objs): $(src)/%.o: $(LIBXUTIL_DIR)/%.c
-       $(call if_changed_rule,cc_o_c)
-#----------------------------------------------------------------------------
-
-vpath %.h $(LIBXUTIL_DIR)
-EXTRA_CFLAGS += -I $(LIBXUTIL_DIR)
-EXTRA_CFLAGS += -I $(src)
-
-endif
-#============================================================================
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/Makefile-2.4
--- a/tools/vnet/vnet-module/Makefile-2.4       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-# -*- mode: Makefile; -*-
-#============================================================================
-#
-# Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free software Foundation, Inc.,
-# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
-#============================================================================
-
-#============================================================================
-# Vnet module makefile for 2.4 series kernels.
-
-LINUX_SERIES =2.4
-include Makefile.ver
-
-KERNEL_MODULE := vnet_module.o
-
-CONFIG_MODVERSIONS := $(shell grep 'CONFIG_MODVERSIONS=y' 
$(KERNEL_SRC)/.config && echo 1 || echo 0)
-
-include Makefile.vnet
-
-VNET_OBJ += $(VNET_LIB_OBJ)
-
-#----------------------------------------------------------------------------
-
-vpath %.h $(KERNEL_SRC)/include
-INCLUDES+= -I $(KERNEL_SRC)/include
-
-vpath %.h $(LIBXUTIL_DIR)
-vpath %.c $(LIBXUTIL_DIR)
-INCLUDES += -I $(LIBXUTIL_DIR)
-
-INCLUDES+= -I .
-
-#----------------------------------------------------------------------------
-
-CPPFLAGS += -D__KERNEL__
-CPPFLAGS += -DMODULE
-
-ifeq ($(CONFIG_MODVERSIONS), 1)
-CPPFLAGS += -DMODVERSIONS
-CPPFLAGS += -include $(KERNEL_SRC)/include/linux/modversions.h
-endif
-
-CPPFLAGS += $(INCLUDES)
-
-CFLAGS += -Wall
-CFLAGS += -Wstrict-prototypes
-CFLAGS += -Wno-trigraphs
-CFLAGS += -Wno-unused-function
-CFLAGS += -Wno-unused-parameter 
-
-CFLAGS += -g
-CFLAGS += -O2
-CFLAGS += -fno-strict-aliasing 
-CFLAGS += -fno-common 
-#CFLAGS += -fomit-frame-pointer
-
-# Dependencies. Gcc generates them for us.
-CFLAGS += -Wp,-MD,.$(@F).d
-VNET_DEP = .*.d
-#----------------------------------------------------------------------------
-
-.PHONY: all
-all: module
-
-.PHONY: module modules
-module modules: $(KERNEL_MODULE)
-
-$(KERNEL_MODULE): $(VNET_OBJ)
-       $(LD) -r -o $@ $^
-
-.PHONY: install install-module modules_install
-install install-module modules_install: module
-       install -m 0755 -d $(DESTDIR)$(KERNEL_MODULE_DIR)
-       install -m 0554 $(KERNEL_MODULE) $(DESTDIR)$(KERNEL_MODULE_DIR)
-
-TAGS:
-       etags *.c *.h
-
-.PHONY: clean
-clean:
-       -@$(RM) *.a *.o *.ko *~
-       -@$(RM) $(VNET_DEP) .*.cmd *.mod.?
-       -@$(RM) -r .tmp_versions
-
--include $(VNET_DEP)
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/Makefile-2.6
--- a/tools/vnet/vnet-module/Makefile-2.6       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-# -*- mode: Makefile; -*-
-#============================================================================
-#
-# Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free software Foundation, Inc.,
-# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
-#============================================================================
-
-#============================================================================
-# Vnet module makefile for 2.6 series kernels.
-
-LINUX_SERIES =2.6
-include Makefile.ver
-
-KERNEL_MODULE = vnet_module.ko
-
-#----------------------------------------------------------------------------
-#export KBUILD_VERBOSE=1
-
-.PHONY: all
-all: module module_version
-
-.PHONY: module
-module modules:
-       $(MAKE) -C $(KERNEL_SRC) M=`pwd` modules
-
-.PHONY: module_version
-module_version:
-       $(warning Module version $(shell strings $(KERNEL_MODULE) | grep 
vermagic))
-
-.PHONY: install install-module modules_install
-install install-module modules_install: module
-       install -m 0755 -d $(DESTDIR)$(KERNEL_MODULE_DIR)
-       install -m 0554 $(KERNEL_MODULE) $(DESTDIR)$(KERNEL_MODULE_DIR)
-
-.PHONY: clean
-clean:
-       -@$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
-       -@$(RM) *.a *.o *.ko *~ .*.d .*.cmd *.mod.?
-       -@$(RM) -r .tmp_versions
-
-.PHONY: TAGS
-TAGS:
-       etags *.c *.h
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/Makefile.ver
--- a/tools/vnet/vnet-module/Makefile.ver       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-# -*- mode: Makefile; -*-
-#============================================================================
-#
-# Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free software Foundation, Inc.,
-# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
-#============================================================================
-
-LINUX_SERIES?=2.6
-
-LINUX_VERSION?=$(shell (/bin/ls -d $(XEN_ROOT)/linux-$(LINUX_SERIES).* 
2>/dev/null) | \
-                      sed -e 's!^.*linux-\(.\+\).hg!\1!' )
-
-ifeq ($(LINUX_VERSION),)
-$(error Kernel source for linux $(LINUX_SERIES) not found)
-endif
-
-KERNEL_VERSION?=$(shell (/bin/ls -d $(XEN_ROOT)/build-linux-$(LINUX_VERSION)* 
2>/dev/null) | \
-                      grep -v -m 1 -e '-xenU' | \
-                      sed -e 's!^.*linux-\(.\+\)!\1!' )
-
-KERNEL_SRC ?= $(XEN_ROOT)/build-linux-$(KERNEL_VERSION)
-
-ifeq ($(KERNEL_SRC),)
-$(error Kernel source for kernel $(KERNEL_VERSION) not found)
-endif
-
-# Get the full kernel release version from its makefile, as the source path
-# may not have the extraversion, e.g. linux-2.6.12-xen0 may contain release 
-# 2.6.12.6-xen0.
-KERNEL_RELEASE=$(shell make -s -C $(KERNEL_SRC) kernelrelease)
-
-KERNEL_MODULE_DIR=/lib/modules/$(KERNEL_RELEASE)/kernel
-
-$(warning KERNEL_SRC           $(KERNEL_SRC))
-$(warning LINUX_VERSION                $(LINUX_VERSION))
-$(warning KERNEL_VERSION       $(KERNEL_VERSION))
-$(warning KERNEL_RELEASE       $(KERNEL_RELEASE))
-$(warning KERNEL_MODULE_DIR    $(KERNEL_MODULE_DIR))
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/Makefile.vnet
--- a/tools/vnet/vnet-module/Makefile.vnet      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-# -*- mode: Makefile; -*-
-#============================================================================
-#
-# Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free software Foundation, Inc.,
-# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
-#============================================================================
-
-ifeq ($(src),)
-SRC_DIR=
-else
-SRC_DIR=$(src)/
-endif
-
-VNET_SRC :=
-VNET_SRC += esp.c
-VNET_SRC += etherip.c
-VNET_SRC += random.c
-VNET_SRC += sa_algorithm.c
-VNET_SRC += sa.c
-VNET_SRC += skb_context.c
-VNET_SRC += skb_util.c
-VNET_SRC += sxpr_util.c
-VNET_SRC += timer_util.c
-VNET_SRC += tunnel.c
-VNET_SRC += varp.c
-VNET_SRC += varp_socket.c
-VNET_SRC += vif.c
-VNET_SRC += vnet.c
-VNET_SRC += vnet_dev.c
-VNET_SRC += vnet_ioctl.c
-VNET_SRC += vnet_eval.c
-VNET_SRC += vnet_forward.c
-
-VNET_LIB_SRC += allocate.c
-VNET_LIB_SRC += enum.c
-VNET_LIB_SRC += hash_table.c
-VNET_LIB_SRC += iostream.c
-VNET_LIB_SRC += kernel_stream.c
-VNET_LIB_SRC += mem_stream.c
-VNET_LIB_SRC += sxpr.c
-VNET_LIB_SRC += sxpr_parser.c
-VNET_LIB_SRC += sys_net.c
-VNET_LIB_SRC += sys_string.c
-
-VNET_OBJ := $(VNET_SRC:.c=.o)
-VNET_LIB_OBJ := $(VNET_LIB_SRC:.c=.o)
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/esp.c
--- a/tools/vnet/vnet-module/esp.c      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,903 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <asm/uaccess.h>
-
-#include <linux/init.h>
-
-#include <linux/version.h>
-
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/net.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/route.h>
-
-#include <linux/if_ether.h>
-#include <linux/icmp.h>
-
-#include <asm/scatterlist.h>
-#include <linux/crypto.h>
-#include <linux/pfkeyv2.h>
-#include <linux/random.h>
-
-#include <esp.h>
-#include <sa.h>
-#include <sa_algorithm.h>
-#include <tunnel.h>
-#include <vnet.h>
-#include <skb_util.h>
-#include <skb_context.h>
-
-static const int DEBUG_ICV = 0;
-
-#define MODULE_NAME "IPSEC"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-#ifndef CONFIG_CRYPTO_HMAC
-#warning No esp transform - CONFIG_CRYPTO_HMAC not defined
-
-int __init esp_module_init(void){
-    return 0;
-}
-
-void __exit esp_module_exit(void){
-}
-
-#else
-
-/* Outgoing packet:                            [ eth | ip | data ]
- * After etherip:        [ eth2 | ip2 |  ethip | eth | ip | data ]
- * After esp   :   [ eth2 | ip2 | esp | {ethip | eth | ip | data} | pad | icv ]
- *                                                        ^     +
- * The curly braces { ... } denote encryption.
- * The esp header includes the fixed esp headers and the iv (variable size).
- * The point marked ^ does not move. To the left is in the header, to the right
- * is in the frag. Remember that all outgoing skbs (from domains) have 1 frag.
- * Data after + is added by esp, using an extra frag.
- *
- * Incoming as above.
- * After decrypt:  [ eth2 | ip2 | esp |  ethip | eth | ip | data  | pad | icv ]
- * Trim tail:      [ eth2 | ip2 | esp |  ethip | eth | ip | data ]
- * Drop hdr:             [ eth2 | ip2 |  ethip | eth | ip | data ]
- *                                    ^
- * The point marked ^ does not move. Incoming skbs are linear (no frags).
- * The tail is trimmed by adjusting skb->tail and len.
- * The esp hdr is dropped by using memmove to move the headers and
- * adjusting the skb pointers.
- *
- * todo: Now this code is in linux we can't assume 1 frag for outbound skbs,
- * or (maybe) that memmove is safe on inbound.
- */
-
-/** Round n up to a multiple of block.
- * If block is less than 2 does nothing.
- * Otherwise assume block is a power of 2.
- *
- * @param n to round up
- * @param block size to round to a multiple of
- * @return rounded value
- */
-static inline int roundupto(int n, int block){
-    if(block <= 1) return n;
-    block--;
-    return (n + block) & ~block;
-}
-
-/** Check if n is a multiple of block.
- * If block is less than 2 returns 1.
- * Otherwise assumes block is a power of 2.
- *
- * @param n to check
- * @param block block size
- * @return 1 if a multiple, 0 otherwise
- */
-static inline int multipleof(int n, int block){
-    if(block <= 1) return 1;
-    block--;
-    return !(n & block);
-}
-
-/** Convert from bits to bytes.
- *
- * @param n number of bits
- * @return number of bytes
- */
-static inline int bits_to_bytes(int n){
-    return n / 8;
-}
-
-
-/** Insert esp padding at the end of an skb.
- * Inserts padding bytes, number of padding bytes, protocol number.
- *
- * @param skb skb
- * @param offset offset from skb end to where padding should end
- * @param extra_n total amount of padding
- * @param protocol protocol number (from original ip hdr)
- * @return 0 on success, error code otherwise
- */
-static int esp_sa_pad(struct sk_buff *skb, int offset, int extra_n,
-                      unsigned char protocol){
-    int err;
-    char *data;
-    int pad_n = extra_n - ESP_PAD_N;
-    int i;
-    char buf[extra_n];
-
-    data = buf;
-    for(i = 1; i <= pad_n; i++){
-        *data++ = i;
-    }
-    *data++ = pad_n;
-    *data++ = protocol;
-    err = skb_put_bits(skb, skb->len - offset - extra_n, buf, extra_n);
-    return err;
-}
-
-/** Encrypt skb. Skips esp header and iv.
- * Assumes skb->data points at esp header.
- *
- * @param esp esp state
- * @parm esph esp header
- * @param skb packet
- * @param head_n size of esp header and iv
- * @param iv_n size of iv
- * @param text_n size of ciphertext
- * @return 0 on success, error code otherwise
- */
-static int esp_sa_encrypt(ESPState *esp, ESPHdr *esph, struct sk_buff *skb,
-                   int head_n, int iv_n, int text_n){
-    int err = 0;
-    int sg_n = skb_shinfo(skb)->nr_frags + 1;
-    struct scatterlist sg[sg_n];
-
-    err = skb_scatterlist(skb, sg, &sg_n, head_n, text_n);
-    if(err) goto exit;
-    if(iv_n){
-        crypto_cipher_set_iv(esp->cipher.tfm, esp->cipher.iv, iv_n);
-    }
-    crypto_cipher_encrypt(esp->cipher.tfm, sg, sg, text_n);
-    if(iv_n){
-        memcpy(esph->data, esp->cipher.iv, iv_n);
-        crypto_cipher_get_iv(esp->cipher.tfm, esp->cipher.iv, iv_n);
-    }
-  exit:
-    return err;
-}
-
-/** Decrypt skb. Skips esp header and iv.
- * Assumes skb->data points at esp header.
- *
- * @param esp esp state
- * @parm esph esp header
- * @param skb packet
- * @param head_n size of esp header and iv
- * @param iv_n size of iv
- * @param text_n size of ciphertext
- * @return 0 on success, error code otherwise
- */
-static int esp_sa_decrypt(ESPState *esp, ESPHdr *esph, struct sk_buff *skb,
-                   int head_n, int iv_n, int text_n){
-    int err = 0;
-    int sg_n = skb_shinfo(skb)->nr_frags + 1;
-    struct scatterlist sg[sg_n];
-
-    err = skb_scatterlist(skb, sg, &sg_n, head_n, text_n);
-    if(err) goto exit;
-    if(iv_n){
-        crypto_cipher_set_iv(esp->cipher.tfm, esph->data, iv_n);
-    }
-    crypto_cipher_decrypt(esp->cipher.tfm, sg, sg, text_n);
-  exit:
-    return err;
-}
-
-/** Compute icv. Includes esp header, iv and ciphertext.
- * Assumes skb->data points at esp header.
- *
- * @param esp esp state
- * @param skb packet
- * @param digest_n number of bytes to digest
- * @param icv_n size of icv
- * @return 0 on success, error code otherwise
- */
-static int esp_sa_digest(ESPState *esp, struct sk_buff *skb, int digest_n, int 
icv_n){
-    int err = 0;
-    u8 icv[icv_n];
-    
-    if(DEBUG_ICV){
-        dprintf("> skb digest_n=%d icv_n=%d\n", digest_n, icv_n);
-        skb_print_bits("esp", skb, 0, digest_n);
-    }
-    memset(icv, 0, icv_n);
-    esp->digest.icv(esp, skb, 0, digest_n, icv);
-    skb_put_bits(skb, digest_n, icv, icv_n);
-    return err;
-}
-
-/** Check the icv and trim it from the skb tail.
- *
- * @param sa sa state
- * @param esp esp state
- * @param esph esp header
- * @param skb packet
- * @return 0 on success, error code otherwise
- */
-static int esp_check_icv(SAState *sa, ESPState *esp, ESPHdr *esph, struct 
sk_buff *skb){
-    int err = 0;
-    int icv_n = esp->digest.icv_n;
-    int digest_n = skb->len - icv_n;
-    u8 icv_skb[icv_n];
-    u8 icv_new[icv_n];
-
-    dprintf(">\n");
-    if(DEBUG_ICV){
-        dprintf("> skb len=%d digest_n=%d icv_n=%d\n",
-                skb->len, digest_n, icv_n);
-        skb_print_bits("esp", skb, 0, skb->len);
-    }
-    if(skb_copy_bits(skb, digest_n, icv_skb, icv_n)){
-        wprintf("> Error getting icv from skb\n");
-        goto exit;
-    }
-    esp->digest.icv(esp, skb, 0, digest_n, icv_new);
-    if(DEBUG_ICV){
-        dprintf("> len=%d icv_n=%d", digest_n, icv_n);
-        printk("\nskb="); buf_print(icv_skb, icv_n);
-        printk("new="); buf_print(icv_new, icv_n);
-    }
-    if(unlikely(memcmp(icv_new, icv_skb, icv_n))){
-        wprintf("> ICV check failed!\n");
-        err = -EINVAL;
-        sa->counts.integrity_failures++;
-        goto exit;
-    }
-    skb_trim_tail(skb, icv_n);
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Send a packet via an ESP SA.
- *
- * @param sa SA state
- * @param skb packet to send
- * @param tunnel underlying tunnel
- * @return 0 on success, negative error code otherwise
- */
-static int esp_sa_send(SAState *sa, struct sk_buff *skb, Tunnel *tunnel){
-    int err = 0;
-    int ip_n;           // Size of ip header.
-    int plaintext_n;   // Size of plaintext.
-    int ciphertext_n;   // Size of ciphertext (including padding).
-    int extra_n;        // Extra bytes needed for ciphertext.
-    int icv_n = 0;      // Size of integrity check value (icv).
-    int iv_n = 0;       // Size of initialization vector (iv).
-    int head_n;         // Size of esp header and iv.
-    int tail_n;         // Size of esp trailer: padding and icv.
-    ESPState  *esp;
-    ESPHdr *esph;
-
-    dprintf(">\n");
-    esp = sa->data;
-    ip_n = (skb->nh.iph->ihl << 2);
-    // Assuming skb->data points at ethernet header, exclude ethernet
-    // header and IP header.
-    plaintext_n = skb->len - ETH_HLEN - ip_n;
-    // Add size of padding fields.
-    ciphertext_n = roundupto(plaintext_n + ESP_PAD_N, esp->cipher.block_n);
-    if(esp->cipher.pad_n > 0){
-        ciphertext_n = roundupto(ciphertext_n, esp->cipher.pad_n);
-    }
-    extra_n = ciphertext_n - plaintext_n;
-    iv_n = esp->cipher.iv_n;
-    icv_n = esp->digest.icv_n;
-    dprintf("> len=%d plaintext=%d ciphertext=%d extra=%d\n",
-            skb->len, plaintext_n, ciphertext_n, extra_n);
-    dprintf("> iv=%d icv=%d\n", iv_n, icv_n);
-    skb_print_bits("iv", skb, 0, skb->len);
-
-    // Add headroom for esp header and iv, tailroom for the ciphertext
-    // and icv.
-    head_n = ESP_HDR_N + iv_n;
-    tail_n = extra_n + icv_n;
-    err = skb_make_room(&skb, skb, head_n, tail_n);
-    if(err) goto exit;
-    dprintf("> skb=%p\n", skb);
-    // Move the headers up to make space for the esp header.  We can
-    // use memmove() since all this data fits in the skb head.
-    // todo: Can't assume this anymore?
-    dprintf("> header push...\n");
-    __skb_push(skb, head_n);
-    if(0 && skb->mac.raw){
-        dprintf("> skb->mac=%p\n", skb->mac.raw);
-        dprintf("> ETH header pull...\n");
-        memmove(skb->data, skb->mac.raw, ETH_HLEN);
-        skb->mac.raw = skb->data; 
-        skb_pull_vn(skb, ETH_HLEN);
-    }
-    dprintf("> IP header pull...\n");
-    memmove(skb->data, skb->nh.raw, ip_n);
-    skb->nh.raw = skb->data;
-    skb_pull_vn(skb, ip_n);
-    esph = (void*)skb->data;
-    // Add spi and sequence number.
-    esph->spi = sa->ident.spi;
-    esph->seq = htonl(++sa->replay.send_seq);
-    // Insert the padding bytes: extra bytes less the pad fields
-    // themselves.
-    dprintf("> esp_sa_pad ...\n");
-    esp_sa_pad(skb, icv_n, extra_n, skb->nh.iph->protocol);
-    if(sa->security & SA_CONF){
-        dprintf("> esp_sa_encrypt...\n");
-        err = esp_sa_encrypt(esp, esph, skb, head_n, iv_n, ciphertext_n);
-        if(err) goto exit;
-    }
-    if(icv_n){
-        dprintf("> esp_sa_digest...\n");
-        err = esp_sa_digest(esp, skb, head_n + ciphertext_n, icv_n);
-        if(err) goto exit;
-    }
-    dprintf("> IP header push...\n");
-    __skb_push(skb, ip_n);
-    if(0 && skb->mac.raw){
-        dprintf("> ETH header push...\n");
-        __skb_push(skb, ETH_HLEN);
-    }
-    // Fix ip header. Adjust length field, set protocol, zero
-    // checksum.
-    {
-        // Total packet length (bytes).
-        int tot_len = ntohs(skb->nh.iph->tot_len);
-        tot_len += head_n;
-        tot_len += tail_n;
-        skb->nh.iph->protocol = IPPROTO_ESP;
-        skb->nh.iph->tot_len  = htons(tot_len);
-        skb->nh.iph->check    = 0;
-    }
-    err = Tunnel_send(tunnel, skb);
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Release an skb context.
- * Drops the refcount on the SA.
- *
- * @param context to free
- */
-static void esp_context_free_fn(SkbContext *context){
-    SAState *sa;
-    if(!context) return;
-    sa = context->data;
-    if(!sa) return;
-    context->data = NULL;
-    SAState_decref(sa);
-}   
-
-/** Receive a packet via an ESP SA.
- * Does ESP receive processing (check icv, decrypt), strips
- * ESP header and re-receives.
- *
- * If return 1 the packet has been freed.
- * If return <= 0 the caller must free.
- *
- * @param sa SA
- * @param skb packet
- * @return >= 0 on success, negative protocol otherwise
- */
-static int esp_sa_recv(SAState *sa, struct sk_buff *skb){
-    int err = -EINVAL;
-    int mine = 0;
-    int vnet = 0; //todo: fixme - need to record skb vnet somewhere
-    ESPState *esp;
-    ESPHdr *esph;
-    ESPPadding *pad;
-    int block_n;       // Cipher blocksize.
-    int icv_n;          // Size of integrity check value (icv).
-    int iv_n;           // Size of initialization vector (iv).
-    int text_n;         // Size of text (ciphertext or plaintext).
-    int head_n;         // Size of esp header and iv.
-
-    dprintf("> skb=%p\n", skb);
-    // Assumes skb->data points at esp hdr.
-    esph = (void*)skb->data;
-    esp = sa->data;
-    block_n = crypto_tfm_alg_blocksize(esp->cipher.tfm);
-    icv_n = esp->digest.icv_n;
-    iv_n = esp->cipher.iv_n;
-    head_n = ESP_HDR_N + iv_n;
-    text_n = skb->len - head_n - icv_n;
-    if(text_n < ESP_PAD_N || !multipleof(text_n, block_n)){
-        wprintf("> Invalid size: text_n=%d tfm:block_n=%d esp:block_n=%d\n",
-                text_n, block_n, esp->cipher.block_n);
-        goto exit;
-    }
-    if(icv_n){
-        err = esp_check_icv(sa, esp, esph, skb);
-        if(err) goto exit;
-    }
-    mine = 1;
-    if(sa->security & SA_CONF){
-        err = esp_sa_decrypt(esp, esph, skb, head_n, iv_n, text_n);
-        if(err) goto exit;
-    }
-    // Strip esp header by moving the other headers down.
-    //todo Maybe not safe to do this anymore.
-    memmove(skb->mac.raw + head_n, skb->mac.raw, (skb->data - skb->mac.raw));
-    skb->mac.raw += head_n;
-    skb->nh.raw  += head_n;
-    // Move skb->data back to ethernet header.
-    // Do in 2 moves to ensure offsets are +ve,
-    // since args to skb_pull/skb_push are unsigned.
-    skb_pull_vn(skb, head_n);
-    __skb_push(skb, skb->data - skb->mac.raw);
-    // After this esph is invalid.
-    esph = NULL;
-    // Trim padding, restore protocol in IP header.
-    pad = skb_trim_tail(skb, ESP_PAD_N);
-    text_n -= ESP_PAD_N;
-    if((pad->pad_n > 255) | (pad->pad_n > text_n)){
-        wprintf("> Invalid padding: pad_n=%d text_n=%d\n", pad->pad_n, text_n);
-        goto exit;
-    }
-    skb_trim_tail(skb, pad->pad_n);
-    skb->nh.iph->protocol = pad->protocol;
-    err = skb_push_context(skb, vnet, sa->ident.addr, IPPROTO_ESP,
-                           sa, esp_context_free_fn);
-    if(err) goto exit;
-    // Increase sa refcount now the skb context refers to it.
-    // Refcount is decreased by esp_context_free_fn.
-    SAState_incref(sa);
-    // Deliver skb to be received by network code.
-    // Not safe to refer to the skb after this.
-    // todo: return -skb->nh.iph->protocol instead?
-    netif_rx(skb);
-  exit:
-    if(mine){
-        if(err < 0){
-            kfree_skb(skb);
-        }
-        err = 1;
-    }
-    dprintf("< skb=%p err=%d\n", skb, err);
-    return err;
-}
-
-/** Estimate the packet size for some data using ESP processing.    
- *
- * @param sa ESP SA
- * @param data_n data size
- * @return size after ESP processing
- */
-static u32 esp_sa_size(SAState *sa, int data_n){
-    // Even in transport mode have to round up to blocksize.
-    // Have to add some padding for alignment even if pad_n is zero.
-    ESPState *esp = sa->data;
-    
-    data_n = roundupto(data_n + ESP_PAD_N, esp->cipher.block_n);
-    if(esp->cipher.pad_n > 0){
-        data_n = roundupto(data_n, esp->cipher.pad_n);
-    }
-    data_n += esp->digest.icv_n;
-    //data_n += esp->cipher.iv_n;
-    data_n += ESP_HDR_N;
-    return data_n;
-}
-
-/** Compute an icv using HMAC digest.
- *
- * @param esp ESP state
- * @param skb packet to digest
- * @param offset offset to start at
- * @param len number of bytes to digest
- * @param icv return parameter for ICV
- * @return 0 on success, negative error code otherwise
- */
-static inline void esp_hmac_digest(ESPState *esp, struct sk_buff *skb,
-                                   int offset, int len, u8 *icv){
-    int err = 0;
-    struct crypto_tfm *digest = esp->digest.tfm;
-    char *icv_tmp = esp->digest.icv_tmp;
-    int sg_n = skb_shinfo(skb)->nr_frags + 1;
-    struct scatterlist sg[sg_n];
-
-    dprintf("> offset=%d len=%d\n", offset, len);
-    memset(icv, 0, esp->digest.icv_n);
-    if(DEBUG_ICV){
-        dprintf("> key len=%d\n", esp->digest.key_n);
-        printk("\nkey=");
-        buf_print(esp->digest.key,esp->digest.key_n); 
-    }
-    crypto_hmac_init(digest, esp->digest.key, &esp->digest.key_n);
-    err = skb_scatterlist(skb, sg, &sg_n, offset, len);
-    crypto_hmac_update(digest, sg, sg_n);
-    crypto_hmac_final(digest, esp->digest.key, &esp->digest.key_n, icv_tmp);
-    if(DEBUG_ICV){
-        dprintf("> digest len=%d ", esp->digest.icv_n);
-        printk("\nval=");
-        buf_print(icv_tmp, esp->digest.icv_n);
-    }
-    memcpy(icv, icv_tmp, esp->digest.icv_n);
-    dprintf("<\n");
-}
-
-/** Finish up an esp state.
- * Releases the digest, cipher, iv and frees the state.
- *
- * @parma esp state
- */
-static void esp_fini(ESPState *esp){
-    if(!esp) return;
-    if(esp->digest.tfm){
-        crypto_free_tfm(esp->digest.tfm);
-        esp->digest.tfm = NULL; 
-    }
-    if(esp->digest.icv_tmp){
-        kfree(esp->digest.icv_tmp);
-        esp->digest.icv_tmp = NULL;
-    }
-    if(esp->cipher.tfm){
-        crypto_free_tfm(esp->cipher.tfm);
-        esp->cipher.tfm = NULL;
-    }
-    if(esp->cipher.iv){
-        kfree(esp->cipher.iv);
-        esp->cipher.iv = NULL;
-    }
-    kfree(esp);
-}
-
-/** Release an ESP SA.
- *
- * @param sa ESO SA
- */
-static void esp_sa_fini(SAState *sa){
-    ESPState *esp;
-    if(!sa) return;
-    esp = sa->data;
-    if(!esp) return;
-    esp_fini(esp);
-    sa->data = NULL;
-}
-
-/** Initialize the cipher for an ESP SA.
- *
- * @param sa ESP SA
- * @param esp ESP state
- * @return 0 on success, negative error code otherwise
- */
-static int esp_cipher_init(SAState *sa, ESPState *esp){
-    int err = 0; 
-    SAAlgorithm *algo = NULL;
-    int cipher_mode = CRYPTO_TFM_MODE_CBC;
-
-    dprintf("> sa=%p esp=%p\n", sa, esp);
-    dprintf("> cipher=%s\n", sa->cipher.name);
-    algo = sa_cipher_by_name(sa->cipher.name);
-    if(!algo){
-        wprintf("> Cipher unavailable: %s\n", sa->cipher.name);
-        err = -EINVAL;
-        goto exit;
-    }
-    esp->cipher.key_n = roundupto(sa->cipher.bits, 8);
-    // If cipher is null must use ECB because CBC algo does not support 
blocksize 1.
-    if(strcmp(sa->cipher.name, "cipher_null")){
-        cipher_mode = CRYPTO_TFM_MODE_ECB;
-    }
-    esp->cipher.tfm = crypto_alloc_tfm(sa->cipher.name, cipher_mode);
-    if(!esp->cipher.tfm){
-        err = -ENOMEM;
-        goto exit;
-    }
-    esp->cipher.block_n = roundupto(crypto_tfm_alg_blocksize(esp->cipher.tfm), 
4);
-    esp->cipher.iv_n = crypto_tfm_alg_ivsize(esp->cipher.tfm);
-    esp->cipher.pad_n = 0;
-    if(esp->cipher.iv_n){
-        esp->cipher.iv = kmalloc(esp->cipher.iv_n, GFP_KERNEL);
-        get_random_bytes(esp->cipher.iv, esp->cipher.iv_n);
-    }
-    crypto_cipher_setkey(esp->cipher.tfm, esp->cipher.key, esp->cipher.key_n);
-    err = 0;
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Initialize the digest for an ESP SA.
- *
- * @param sa ESP SA
- * @param esp ESP state
- * @return 0 on success, negative error code otherwise
- */
-static int esp_digest_init(SAState *sa, ESPState *esp){
-    int err = 0;
-    SAAlgorithm *algo = NULL;
-    
-    dprintf(">\n");
-    esp->digest.key = sa->digest.key;
-    esp->digest.key_n = bits_to_bytes(roundupto(sa->digest.bits, 8));
-    esp->digest.tfm = crypto_alloc_tfm(sa->digest.name, 0);
-    if(!esp->digest.tfm){
-        err = -ENOMEM;
-        goto exit;
-    }
-    algo = sa_digest_by_name(sa->digest.name);
-    if(!algo){
-        wprintf("> Digest unavailable: %s\n", sa->digest.name);
-        err = -EINVAL;
-        goto exit;
-    }
-    esp->digest.icv = esp_hmac_digest;
-    esp->digest.icv_full_n = bits_to_bytes(algo->info.digest.icv_fullbits);
-    esp->digest.icv_n = bits_to_bytes(algo->info.digest.icv_truncbits);
-    
-    if(esp->digest.icv_full_n != crypto_tfm_alg_digestsize(esp->digest.tfm)){
-        err = -EINVAL;
-        wprintf("> digest %s, size %u != %hu\n",
-                sa->digest.name,
-                crypto_tfm_alg_digestsize(esp->digest.tfm),
-                esp->digest.icv_full_n);
-        goto exit;
-    }
-    
-    esp->digest.icv_tmp = kmalloc(esp->digest.icv_full_n, GFP_KERNEL);
-    if(!esp->digest.icv_tmp){
-        err = -ENOMEM;
-        goto exit;
-    }
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Initialize an ESP SA.
- *
- * @param sa ESP SA
- * @param args arguments
- * @return 0 on success, negative error code otherwise
- */
-static int esp_sa_init(SAState *sa, void *args){
-    int err = 0;
-    ESPState *esp = NULL;
-    
-    dprintf("> sa=%p\n", sa);
-    esp = kmalloc(sizeof(*esp), GFP_KERNEL);
-    if(!esp){
-        err = -ENOMEM;
-        goto exit;
-    }
-    *esp = (ESPState){};
-    err = esp_cipher_init(sa, esp);
-    if(err) goto exit;
-    err = esp_digest_init(sa, esp);
-    if(err) goto exit;
-    sa->data = esp;
-  exit:
-    if(err){
-        if(esp) esp_fini(esp);
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** SA type for ESP.
- */
-static SAType esp_sa_type = {
-    .name     = "ESP",
-    .protocol = IPPROTO_ESP,
-    .init     = esp_sa_init,
-    .fini     = esp_sa_fini,
-    .size     = esp_sa_size,
-    .recv     = esp_sa_recv,
-    .send     = esp_sa_send
-};
-
-/** Get the ESP header from a packet.
- *
- * @param skb packet
- * @param esph return parameter for header
- * @return 0 on success, negative error code otherwise
- */
-static int esp_skb_header(struct sk_buff *skb, ESPHdr **esph){
-    int err = 0;
-    if(skb->len < ESP_HDR_N){
-        err = -EINVAL;
-        goto exit;
-    }
-    *esph = (ESPHdr*)skb->data;
-  exit:
-    return err;
-}
-
-/** Handle an incoming skb with ESP protocol.
- *
- * Lookup spi, if state found hand to the state.
- * If no state, check spi, if ok, create state and pass to it.
- * If spi not ok, drop.
- *
- * Return value convention for protocols:
- * >= 0 Protocol took the packet
- * < 0  A -ve protocol id the packet should be re-received as.
- *
- * So always return >=0 if we took the packet, even if we dropped it.
- * 
- * @param skb packet
- * @return 0 on sucess, negative protocol number otherwise
- */
-static int esp_protocol_recv(struct sk_buff *skb){
-    int err = 0;
-    const int eth_n = ETH_HLEN;
-    int ip_n;
-    ESPHdr *esph = NULL;
-    SAState *sa = NULL;
-    u32 addr;
-    
-    dprintf(">\n");
-#ifdef DEBUG
-    dprintf("> recv skb=\n"); 
-    skb_print_bits("", skb, 0, skb->len);
-#endif
-    ip_n = (skb->nh.iph->ihl << 2);
-    if(skb->data == skb->mac.raw){
-        // skb->data points at ethernet header.
-        if (!pskb_may_pull(skb, eth_n + ip_n)){
-            wprintf("> Malformed skb\n");
-            err = -EINVAL;
-            goto exit;
-        }
-        skb_pull_vn(skb, eth_n + ip_n);
-    }
-    addr = skb->nh.iph->daddr;
-    err = esp_skb_header(skb, &esph);
-    if(err) goto exit;
-    dprintf("> spi=%08x protocol=%d addr=" IPFMT "\n",
-            esph->spi, IPPROTO_ESP, NIPQUAD(addr));
-    sa = sa_table_lookup_spi(esph->spi, IPPROTO_ESP, addr);
-    if(!sa){
-        err = vnet_sa_create(esph->spi, IPPROTO_ESP, addr, &sa);
-        if(err) goto exit;
-    }
-    //todo: Return a -ve protocol instead? See esp_sa_recv.
-    err = SAState_recv(sa, skb);
-  exit:
-    if(sa) SAState_decref(sa);
-    if(err <= 0){
-        kfree_skb(skb);
-        err = 0;
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Handle an ICMP error related to ESP.
- *
- * @param skb ICMP error packet
- * @param info
- */
-static void esp_protocol_icmp_err(struct sk_buff *skb, u32 info){
-    struct iphdr *iph = (struct iphdr*)skb->data;
-    ESPHdr *esph;
-    SAState *sa;
-    
-    dprintf("> ICMP error type=%d code=%d\n",
-            skb->h.icmph->type, skb->h.icmph->code);
-    if(skb->h.icmph->type != ICMP_DEST_UNREACH ||
-       skb->h.icmph->code != ICMP_FRAG_NEEDED){
-        return;
-    }
-    
-    //todo: need to check skb has enough len to do this.
-    esph = (ESPHdr*)(skb->data + (iph->ihl << 2));
-    sa = sa_table_lookup_spi(esph->spi, IPPROTO_ESP, iph->daddr);
-    if(!sa) return;
-    wprintf("> ICMP unreachable on SA ESP spi=%08x addr=" IPFMT "\n",
-            ntohl(esph->spi), NIPQUAD(iph->daddr));
-    SAState_decref(sa);
-}
-
-//============================================================================
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-// Code for 2.6 kernel.
-
-/** Protocol handler for ESP.
- */
-static struct net_protocol esp_protocol = {
-    .handler     = esp_protocol_recv,
-    .err_handler = esp_protocol_icmp_err
-};
-
-static int esp_protocol_add(void){
-    return inet_add_protocol(&esp_protocol, IPPROTO_ESP);
-}
-
-static int esp_protocol_del(void){
-    return inet_del_protocol(&esp_protocol, IPPROTO_ESP);
-}
-
-//============================================================================
-#else
-//============================================================================
-// Code for 2.4 kernel.
-
-/** Protocol handler for ESP.
- */
-static struct inet_protocol esp_protocol = {
-    .name        = "ESP",
-    .protocol    = IPPROTO_ESP,
-    .handler     = esp_protocol_recv,
-    .err_handler = esp_protocol_icmp_err
-};
-
-static int esp_protocol_add(void){
-    inet_add_protocol(&esp_protocol);
-    return 0;
-}
-
-static int esp_protocol_del(void){
-    return inet_del_protocol(&esp_protocol);
-}
-
-#endif
-//============================================================================
-
-
-/** Initialize the ESP module.
- * Registers the ESP protocol and SA type.
- *
- * @return 0 on success, negative error code otherwise
- */
-int __init esp_module_init(void){
-    int err = 0;
-    dprintf(">\n");
-    err = SAType_add(&esp_sa_type);
-    if(err < 0){
-        eprintf("> Error adding esp sa type\n");
-        goto exit;
-    }
-    esp_protocol_add();
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Finalize the ESP module.
- * Deregisters the ESP protocol and SA type.
- */
-void __exit esp_module_exit(void){
-    if(esp_protocol_del() < 0){
-        eprintf("> Error removing esp protocol\n");
-    }
-    if(SAType_del(&esp_sa_type) < 0){
-        eprintf("> Error removing esp sa type\n");
-    }
-}
-
-#endif // CONFIG_CRYPTO_HMAC
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/esp.h
--- a/tools/vnet/vnet-module/esp.h      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __VNET_ESP_H__
-#define __VNET_ESP_H__
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/crypto.h>
-
-#else
-
-#include "sys_kernel.h"
-
-struct crypto_tfm;
-
-#endif
-
-/** Header used by IPSEC ESP (Encapsulated Security Payload). */
-typedef struct ESPHdr {
-    /** The spi (security parameters index). */
-    u32 spi;
-    /** Sequence number. */
-    u32 seq;
-    /* Variable length data (depends on crypto suite).
-       Mind the 64 bit alignment! */
-    u8  data[0];
-} ESPHdr;
-
-/** Padding trailer used by IPSEC ESP.
- * Follows the padding itself with the padding length and the
- * protocol being encapsulated.
- */
-typedef struct ESPPadding {
-    u8 pad_n;
-    u8 protocol;
-} ESPPadding;
-
-/** Size of the esp header (spi and seq). */
-static const int ESP_HDR_N = sizeof(ESPHdr);
-
-/** Size of the esp pad and next protocol field. */
-static const int ESP_PAD_N = sizeof(ESPPadding);
-
-enum {
-    SASTATE_VOID,
-    SASTATE_ACQUIRE,
-    SASTATE_VALID,
-    SASTATE_ERROR,
-    SASTATE_EXPIRED,
-    SASTATE_DEAD,
-};
-
-struct ESPState;
-
-/** A cipher instance. */
-typedef struct ESPCipher {
-    /** Cipher key. */
-    u8 *key;
-    /** Key size (bytes). */
-    int key_n;
-    /** Initialization vector (IV). */
-    u8 *iv;
-    /** IV size (bytes). */
-    int iv_n;
-    /** Block size for padding (bytes). */
-    int pad_n;
-    /** Cipher block size (bytes). */
-    int block_n;
-    /** Cipher crypto transform. */
-    struct crypto_tfm *tfm;
-} ESPCipher;
-
-/** A digest instance. */
-typedef struct ESPDigest {
-    /** Digest key. */
-    u8 *key;
-    /** Key size (bytes) */
-    int key_n;
-    /** ICV size used (bytes). */
-    u8 icv_n;
-    /** Full ICV size when computed (bytes). */
-    u8 icv_full_n;
-    /** Working storage for computing ICV. */
-    u8 *icv_tmp;
-    /** Function used to compute ICV (e.g. HMAC). */
-    void (*icv)(struct ESPState *esp,
-                struct sk_buff *skb,
-                int offset,
-                int len,
-                u8 *icv);
-    /** Digest crypto transform (e.g. SHA). */
-    struct crypto_tfm *tfm;
-} ESPDigest;
-
-typedef struct ESPState {
-    struct ESPCipher cipher;
-    struct ESPDigest digest;
-} ESPState;
-
-extern int esp_module_init(void);
-extern void esp_module_exit(void);
-
-#endif /* !__VNET_ESP_H__ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/etherip.c
--- a/tools/vnet/vnet-module/etherip.c  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <linux/version.h>
-
-#include <linux/skbuff.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netfilter_bridge.h>
-#include <linux/netfilter_ipv4.h>
-#include <linux/icmp.h>
-#include <linux/udp.h>
-
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/route.h>
-#include <net/checksum.h>
-
-#else
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "sys_kernel.h"
-#include "spinlock.h"
-#include "skbuff.h"
-#include <linux/ip.h>
-#include <linux/udp.h>
-
-#define IP_DF          0x4000          /* Flag: "Don't Fragment"       */
-
-#endif
-
-#include <etherip.h>
-#include <tunnel.h>
-#include <vnet.h>
-#include <varp.h>
-#include <if_varp.h>
-#include <varp.h>
-#include <skb_util.h>
-#include <skb_context.h>
-
-#define MODULE_NAME "VNET"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** @file Etherip implementation.
- * The etherip protocol is used to transport Ethernet frames in IP packets.
- */
-
-/** Flag controlling whether to use etherip-in-udp encapsulation.
- * If false we send etherip protocol in IP packets.
- * If true we send etherip protocol in UDP packets with a vnet header.
- */
-int etherip_in_udp = 1;
-
-/** Get the vnet label from an etherip header.
- *
- * @param hdr header
- * @@param vnet (in net order)
- */
-void etheriphdr_get_vnet(struct etheriphdr *hdr, VnetId *vnet){
-#ifdef CONFIG_ETHERIP_EXT
-    *vnet = *(VnetId*)hdr->vnet;
-#else
-    *vnet = (VnetId){};
-    vnet->u.vnet16[VNET_SIZE16 - 1] = (unsigned short)hdr->reserved;
-    
-#endif
-}
-
-/** Set the vnet label in an etherip header.
- * Also sets the etherip version.
- *
- * @param hdr header
- * @param vnet vnet label (in net order)
- */
-void etheriphdr_set_vnet(struct etheriphdr *hdr, VnetId *vnet){
-#ifdef CONFIG_ETHERIP_EXT
-    hdr->version = ETHERIP_VERSION;
-    *(VnetId*)hdr->vnet = *vnet;
-#else
-    hdr->version = ETHERIP_VERSION;
-    hdr->reserved = (vnet->u.vnet16[VNET_SIZE16 - 1] & 0x0fff);
-#endif
-}
-
-/** Open an etherip tunnel.
- *
- * @param tunnel to open
- * @return 0 on success, error code otherwise
- */
-static int etherip_tunnel_open(Tunnel *tunnel){
-    return 0;
-}
-
-/** Close an etherip tunnel.
- *
- * @param tunnel to close
- */
-static void etherip_tunnel_close(Tunnel *tunnel){
-}
-
-
-static inline int skb_make_headroom(struct sk_buff **pskb, struct sk_buff 
*skb, int head_n){
-    int err = 0;
-    dprintf("> skb=%p headroom=%d head_n=%d\n", skb, skb_headroom(skb), 
head_n);
-    if(head_n > skb_headroom(skb) || skb_cloned(skb) || skb_shared(skb)){
-        // Expand header the way GRE does.
-        struct sk_buff *new_skb = skb_realloc_headroom(skb, head_n + 16);
-        if(!new_skb){
-            err = -ENOMEM;
-            goto exit;
-        }
-        kfree_skb(skb);
-        *pskb = new_skb;
-    } else {
-        *pskb = skb;
-    }
-  exit:
-    return err;
-}
-    
-/** Send a packet via an etherip tunnel.
- * Adds etherip header and new ip header around ethernet frame.
- *
- * @param tunnel tunnel
- * @param skb packet
- * @return 0 on success, error code otherwise
- */
-static int etherip_tunnel_send(Tunnel *tunnel, struct sk_buff *skb){
-    int err = 0;
-    const int ip_n = sizeof(struct iphdr);
-    const int etherip_n = sizeof(struct etheriphdr);
-    const int udp_n = sizeof(struct udphdr);
-    const int vnet_n = sizeof(struct VnetMsgHdr);
-    int head_n = etherip_n + ip_n /* +  ETH_HLEN */;
-    VnetId *vnet = &tunnel->key.vnet;
-    struct etheriphdr *etheriph;
-    u32 saddr = 0;
-
-    if(etherip_in_udp){
-        head_n += vnet_n + udp_n;
-    }
-    err = skb_make_headroom(&skb, skb, head_n);
-    if(err) goto exit;
-
-    // Null the pointer as we are pushing a new IP header.
-    skb->mac.raw = NULL;
-
-    // Setup the etherip header.
-    etheriph = (void*)skb_push(skb, etherip_n);
-    etheriphdr_set_vnet(etheriph, vnet);
-
-    if(etherip_in_udp){
-        // Vnet header.
-        struct VnetMsgHdr *vhdr = (void*)skb_push(skb, vnet_n);
-        vhdr->id     = htons(VUDP_ID);
-        vhdr->opcode = 0;
-
-        // Setup the UDP header.
-        skb->h.raw = skb_push(skb, udp_n);
-        skb->h.uh->source = varp_port;         // Source port.
-        skb->h.uh->dest   = varp_port;         // Destination port.
-        skb->h.uh->len    = htons(skb->len);   // Total packet length (bytes).
-        skb->h.uh->check  = 0;
-    }
-
-    // Setup the IP header.
-    skb->nh.raw = skb_push(skb, ip_n); 
-    skb->nh.iph->version  = 4;                 // Standard version.
-    skb->nh.iph->ihl      = ip_n / 4;          // IP header length (32-bit 
words).
-    skb->nh.iph->tos      = 0;                 // No special type-of-service.
-    skb->nh.iph->tot_len  = htons(skb->len);    // Total packet length (bytes).
-    skb->nh.iph->id       = 0;                 // No flow id (since no frags).
-    if(etherip_in_udp){
-        skb->nh.iph->protocol = IPPROTO_UDP;    // IP protocol number.
-        skb->nh.iph->frag_off = 0;
-    } else {
-        skb->nh.iph->protocol = IPPROTO_ETHERIP;// IP protocol number.
-        skb->nh.iph->frag_off = htons(IP_DF);  // Don't fragment - can't 
handle frags.
-    }
-    skb->nh.iph->ttl      = 64;                        // Linux default 
time-to-live.
-    skb->nh.iph->saddr    = saddr;             // Source address.
-    skb->nh.iph->daddr    = tunnel->key.addr.u.ip4.s_addr; // Destination 
address.
-    skb->nh.iph->check    = 0;                 // Zero the checksum.
-
-    // Ethernet header will be filled-in by device.
-    err = Tunnel_send(tunnel->base, skb);
-    skb = NULL;
-  exit:
-    if(err && skb){
-        wprintf("< err=%d\n", err);
-        kfree_skb(skb);
-    }
-    return err;
-}
-
-/** Tunnel type for etherip.
- */
-static TunnelType _etherip_tunnel_type = {
-    .name      = "ETHERIP",
-    .open      = etherip_tunnel_open,
-    .close     = etherip_tunnel_close,
-    .send      = etherip_tunnel_send
-};
-
-TunnelType *etherip_tunnel_type = &_etherip_tunnel_type;
-
-int etherip_tunnel_create(VnetId *vnet, VarpAddr *addr, Tunnel *base, Tunnel 
**tunnel){
-    return Tunnel_create(etherip_tunnel_type, vnet, addr, base, tunnel);
-}
-
-#if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER)
-/** We need our own copy of this as it is no longer exported from the bridge 
module.
- */
-static inline void _nf_bridge_save_header(struct sk_buff *skb){
-    int header_size = 16;
-    
-    // Were using this modified to use h_proto instead of skb->protocol.
-    if(skb->protocol == htons(ETH_P_8021Q)){
-        header_size = 18;
-    }
-    memcpy(skb->nf_bridge->data, skb->data - header_size, header_size);
-}
-#endif
-
-/** Do etherip receive processing.
- * Strips the etherip header to extract the ethernet frame, sets
- * the vnet from the header and re-receives the frame.
- *
- * Return code 1 means we now own the packet - the caller must not free it.
- * Return code < 0 means an error - caller still owns the packet.
- *
- * @param skb packet
- * @return 1 on success, error code otherwise
- */
-int etherip_protocol_recv(struct sk_buff *skb){
-    int err = 0;
-    const int etherip_n = sizeof(struct etheriphdr);
-    struct etheriphdr *etheriph;
-    Vnet *vinfo = NULL;
-    VnetId vnet = {};
-    u32 saddr, daddr;
-    char vnetbuf[VNET_ID_BUF];
-    struct ethhdr *eth;
-    struct sk_buff *newskb;
-
-    dprintf(">\n");
-    saddr = skb->nh.iph->saddr;
-    daddr = skb->nh.iph->daddr;
-    if(MULTICAST(daddr) && (daddr != varp_mcast_addr)){
-        // Ignore multicast packets not addressed to us.
-        wprintf("> Ignoring mcast skb: src=%u.%u.%u.%u dst=%u.%u.%u.%u"
-                " varp_mcast_addr=%u.%u.%u.%u\n",
-                NIPQUAD(saddr), NIPQUAD(daddr), NIPQUAD(varp_mcast_addr));
-        goto exit;
-    }
-    if(skb->data == skb->mac.raw){
-        // skb->data points at ethernet header.
-        //FIXME: Does this ever happen?
-        //dprintf("> len=%d\n", skb->len);
-        int ip_n = (skb->nh.iph->ihl << 2);
-        int pull_n = ETH_HLEN + ip_n;
-        if (!pskb_may_pull(skb, pull_n)){
-            wprintf("> Malformed skb (eth+ip) src=%u.%u.%u.%u\n",
-                    NIPQUAD(saddr));
-            err = -EINVAL;
-            goto exit;
-        }
-        skb_pull_vn(skb, pull_n);
-    }
-    // Assume skb->data points at etherip header.
-    etheriph = (void*)skb->data;
-    if(etheriph->version != ETHERIP_VERSION){
-        wprintf("> Bad etherip version=%d src=%u.%u.%u.%u\n",
-                etheriph->version, NIPQUAD(saddr));
-        err = -EINVAL;
-        goto exit;
-    }
-    if(!pskb_may_pull(skb, etherip_n)){
-        wprintf("> Malformed skb (etherip) src=%u.%u.%u.%u\n",
-                NIPQUAD(saddr));
-        err = -EINVAL;
-        goto exit;
-    }
-    etheriphdr_get_vnet(etheriph, &vnet);
-    // If vnet is secure, context must include IPSEC ESP.
-    err = vnet_check_context(&vnet, SKB_CONTEXT(skb), &vinfo);
-    if(err){
-        wprintf("> Failed security check vnet=%s src=%u.%u.%u.%u\n",
-                VnetId_ntoa(&vnet, vnetbuf), NIPQUAD(saddr));
-        goto exit;
-    }
-    // Point at the headers in the contained ethernet frame.
-    skb->mac.raw = skb_pull_vn(skb, etherip_n);
-
-    newskb = alloc_skb(skb->len, GFP_ATOMIC);
-    if (!newskb) {
-        wprintf("> alloc new sk_buff failed \n");
-        goto exit;
-    }
-    newskb->mac.raw = skb_put(newskb, skb->len);
-    skb_copy_bits(skb, 0, newskb->data, skb->len);
-    kfree_skb(skb);
-    skb = newskb;
-
-    eth = eth_hdr(skb);
-
-    // Simulate the logic from eth_type_trans()
-    // to set skb->pkt_type and skb->protocol.
-    if(mac_is_multicast(eth->h_dest)){
-        if(mac_is_broadcast(eth->h_dest)){
-            skb->pkt_type = PACKET_BROADCAST;
-        } else {
-            skb->pkt_type = PACKET_MULTICAST;
-        }
-    } else {
-        skb->pkt_type = PACKET_HOST;
-    }
-    if(ntohs(eth->h_proto) >= 1536){
-        skb->protocol = eth->h_proto;
-    } else {
-        skb->protocol = htons(ETH_P_802_2);
-    }
-    
-    // Assuming a standard Ethernet frame.
-    // Should check for protocol? Support ETH_P_8021Q too.
-    skb->nh.raw = skb_pull_vn(skb, ETH_HLEN);
-    skb->h.raw = newskb->nh.raw + sizeof(struct iphdr);
-
-    dprintf("> Unpacked srcaddr=" IPFMT " dstaddr=" IPFMT " vnet=%s srcmac=" 
MACFMT " dstmac=" MACFMT "\n",
-            NIPQUAD(skb->nh.iph->saddr),
-            NIPQUAD(skb->nh.iph->daddr),
-            VnetId_ntoa(&vnet, vnetbuf),
-            MAC6TUPLE(eth->h_source),
-            MAC6TUPLE(eth->h_dest));
-    //print_skb(__FUNCTION__, 0, skb);
-
-    {
-        // Know source ip, vnet, vmac, so update the varp cache.
-        // For this to work forwarded vnet packets must have the
-        // original source address.
-        VarpAddr addr = { .family = AF_INET };
-        addr.u.ip4.s_addr = saddr;
-        varp_update(&vnet, eth->h_source, &addr);
-    }
-
-    err = vnet_skb_recv(skb, vinfo);
-  exit:
-    if(vinfo) Vnet_decref(vinfo);
-    dprintf("< skb=%p err=%d\n", skb, err);
-    return err;
-}
-
-
-#ifdef __KERNEL__
-
-/** Handle an ICMP error related to etherip.
- *
- * @param skb ICMP error packet
- * @param info
- */
-static void etherip_protocol_icmp_err(struct sk_buff *skb, u32 info){
-    struct iphdr *iph = (struct iphdr*)skb->data;
-    
-    wprintf("> ICMP error type=%d code=%d addr=" IPFMT "\n",
-            skb->h.icmph->type, skb->h.icmph->code, NIPQUAD(iph->daddr));
-
-    if (skb->h.icmph->type != ICMP_DEST_UNREACH ||
-        skb->h.icmph->code != ICMP_FRAG_NEEDED){
-        return;
-    }
-    wprintf("> MTU too big addr= " IPFMT "\n", NIPQUAD(iph->daddr)); 
-}
-
-//============================================================================
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-// Code for 2.6 kernel.
-
-/** Etherip protocol. */
-static struct net_protocol etherip_protocol = {
-    .handler    = etherip_protocol_recv,
-    .err_handler = etherip_protocol_icmp_err,
-};
-
-static int etherip_protocol_add(void){
-    return inet_add_protocol(&etherip_protocol, IPPROTO_ETHERIP);
-}
-
-static int etherip_protocol_del(void){
-    return inet_del_protocol(&etherip_protocol, IPPROTO_ETHERIP);
-}
-
-//============================================================================
-#else
-//============================================================================
-// Code for 2.4 kernel.
-
-/** Etherip protocol. */
-static struct inet_protocol etherip_protocol = {
-    .name        = "ETHERIP",
-    .protocol    = IPPROTO_ETHERIP,
-    .handler    = etherip_protocol_recv,
-    .err_handler = etherip_protocol_icmp_err,
-};
-
-static int etherip_protocol_add(void){
-    inet_add_protocol(&etherip_protocol);
-    return 0;
-}
-
-static int etherip_protocol_del(void){
-    return inet_del_protocol(&etherip_protocol);
-}
-
-#endif
-//============================================================================
-
-
-/** Initialize the etherip module.
- * Registers the etherip protocol.
- *
- * @return 0 on success, error code otherwise
- */
-int __init etherip_module_init(void) {
-    int err = 0;
-    etherip_protocol_add();
-    return err;
-}
-
-/** Finalize the etherip module.
- * Deregisters the etherip protocol.
- */
-void __exit etherip_module_exit(void) {
-    if(etherip_protocol_del() < 0){
-        printk(KERN_INFO "%s: can't remove etherip protocol\n", __FUNCTION__);
-    }
-}
-
-#endif // __KERNEL__
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/etherip.h
--- a/tools/vnet/vnet-module/etherip.h  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _VNET_ETHERIP_H_
-#define _VNET_ETHERIP_H_
-
-#include "if_etherip.h"
-
-#ifdef __KERNEL__
-extern int etherip_module_init(void);
-extern void etherip_module_exit(void);
-#endif
-
-extern int etherip_protocol_recv(struct sk_buff *skb);
-extern int etherip_in_udp;
-
-struct VnetId;
-struct VarpAddr;
-struct Tunnel;
-
-extern int etherip_tunnel_create(struct VnetId *vnet, struct VarpAddr *addr,
-                                 struct Tunnel *base, struct Tunnel **tunnel);
-#endif
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/if_etherip.h
--- a/tools/vnet/vnet-module/if_etherip.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _VNET_IF_ETHERIP_H_
-#define _VNET_IF_ETHERIP_H_
-
-#ifdef __KERNEL__
-#include <asm/byteorder.h>
-#else
-#define __KERNEL__
-/* This include may cause a compile warning, which can be ignored.
- * Can't use <endian.h> because it doesn't define 
- *__LITTLE_ENDIAN_BITFIELD or __BIG_ENDIAN_BITFIELD.
- */
-#include <asm/byteorder.h>
-#undef __KERNEL__
-#endif
-
-#include <if_varp.h>
-
-#define CONFIG_ETHERIP_EXT
-
-#ifdef CONFIG_ETHERIP_EXT
-
-/* Extended header with room for a longer vnet id. */
-
-#define ETHERIP_VERSION 4
-
-struct etheriphdr {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-    __u16    reserved:12,
-             version:4;
-#elif defined (__BIG_ENDIAN_BITFIELD)
-    __u16    version:4,
-            reserved:12;
-#else
-#error  "Adjust your <asm/byteorder.h> defines"
-#endif
-    __u8 vnet[VNETID_SIZE8];
-} __attribute__ ((packed));
-
-#else
-
-/* Original header as in Etherip RFC. */
-
-#define ETHERIP_VERSION 3
-
-struct etheriphdr
-{
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-    __u16    reserved:12,
-             version:4;
-#elif defined (__BIG_ENDIAN_BITFIELD)
-    __u16    version:4,
-            reserved:12;
-#else
-#error  "Adjust your <asm/byteorder.h> defines"
-#endif
-
-};
-#endif
-
-
-#ifndef IPPROTO_ETHERIP
-#define IPPROTO_ETHERIP 97
-#endif
-
-#endif /* ! _VNET_IF_ETHERIP_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/if_varp.h
--- a/tools/vnet/vnet-module/if_varp.h  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef _VNET_IF_VARP_H
-#define _VNET_IF_VARP_H
-
-/* Need struct in_addr, struct in6_addr. */
-#ifdef __KERNEL__
-
-#include <linux/in.h>
-#include <linux/in6.h>
-
-#else
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#endif
-
-#include <linux/if_ether.h>
-
-typedef struct Vmac {
-    unsigned char mac[ETH_ALEN];
-} Vmac;
-
-enum {
-    /* Varp protocol messages.
-     * Format is defined by struct VarpHdr.
-     */
-    VARP_ID          = 1,
-
-    /* Vnet ethernet in udp messages.
-     * Format is uint16_t id (VUDP_ID), then
-     * struct etheriphdr.
-     */
-    VUDP_ID          = 2,
-
-    /* Forwarded messages.
-     */
-    VFWD_ID          = 3,
-
-    /* Varp request. */
-    VARP_OP_REQUEST  = 1,
-    /* Varp announce. */
-    VARP_OP_ANNOUNCE = 2,
-};
-
-#define VNETID_SIZE8  16
-#define VNETID_SIZE16 (VNETID_SIZE8 >> 1)
-#define VNETID_SIZE32 (VNETID_SIZE8 >> 2)
-
-typedef struct VnetId {
-    union {
-        uint8_t  vnet8[VNETID_SIZE8];
-        uint16_t vnet16[VNETID_SIZE16];
-        uint32_t vnet32[VNETID_SIZE32];
-    } u;
-} __attribute__((packed)) VnetId;
-
-typedef struct VarpAddr {
-    uint8_t family; // AF_INET or AF_INET6.
-    union {
-        uint8_t raw[16];
-        struct in_addr ip4;
-        struct in6_addr ip6;
-    } u;
-    //uint16_t port;
-} __attribute__((packed)) VarpAddr;
-
-typedef struct VnetMsgHdr {
-    uint16_t id;
-    uint16_t opcode;
-} __attribute__((packed)) VnetMsgHdr;
-
-typedef struct VarpHdr {
-  VnetMsgHdr hdr;
-  VnetId vnet;
-  Vmac vmac;
-  VarpAddr addr;
-} __attribute__((packed)) VarpHdr;
-
-
-/** Default address for varp/vnet broadcasts: 224.10.0.1 */
-#define VARP_MCAST_ADDR     0xe00a0001
-
-/** UDP port to use for varp protocol. */
-#define VARP_PORT           1798
-
-#endif /* ! _VNET_IF_VARP_H */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/linux/pfkeyv2.h
--- a/tools/vnet/vnet-module/linux/pfkeyv2.h    Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,329 +0,0 @@
-/* PF_KEY user interface, this is defined by rfc2367 so
- * do not make arbitrary modifications or else this header
- * file will not be compliant.
- */
-
-#ifndef _LINUX_PFKEY2_H
-#define _LINUX_PFKEY2_H
-
-#include <linux/types.h>
-
-#define PF_KEY_V2              2
-#define PFKEYV2_REVISION       199806L
-
-struct sadb_msg {
-       uint8_t         sadb_msg_version;
-       uint8_t         sadb_msg_type;
-       uint8_t         sadb_msg_errno;
-       uint8_t         sadb_msg_satype;
-       uint16_t        sadb_msg_len;
-       uint16_t        sadb_msg_reserved;
-       uint32_t        sadb_msg_seq;
-       uint32_t        sadb_msg_pid;
-} __attribute__((packed));
-/* sizeof(struct sadb_msg) == 16 */
-
-struct sadb_ext {
-       uint16_t        sadb_ext_len;
-       uint16_t        sadb_ext_type;
-} __attribute__((packed));
-/* sizeof(struct sadb_ext) == 4 */
-
-struct sadb_sa {
-       uint16_t        sadb_sa_len;
-       uint16_t        sadb_sa_exttype;
-       uint32_t        sadb_sa_spi;
-       uint8_t         sadb_sa_replay;
-       uint8_t         sadb_sa_state;
-       uint8_t         sadb_sa_auth;
-       uint8_t         sadb_sa_encrypt;
-       uint32_t        sadb_sa_flags;
-} __attribute__((packed));
-/* sizeof(struct sadb_sa) == 16 */
-
-struct sadb_lifetime {
-       uint16_t        sadb_lifetime_len;
-       uint16_t        sadb_lifetime_exttype;
-       uint32_t        sadb_lifetime_allocations;
-       uint64_t        sadb_lifetime_bytes;
-       uint64_t        sadb_lifetime_addtime;
-       uint64_t        sadb_lifetime_usetime;
-} __attribute__((packed));
-/* sizeof(struct sadb_lifetime) == 32 */
-
-struct sadb_address {
-       uint16_t        sadb_address_len;
-       uint16_t        sadb_address_exttype;
-       uint8_t         sadb_address_proto;
-       uint8_t         sadb_address_prefixlen;
-       uint16_t        sadb_address_reserved;
-} __attribute__((packed));
-/* sizeof(struct sadb_address) == 8 */
-
-struct sadb_key {
-       uint16_t        sadb_key_len;
-       uint16_t        sadb_key_exttype;
-       uint16_t        sadb_key_bits;
-       uint16_t        sadb_key_reserved;
-} __attribute__((packed));
-/* sizeof(struct sadb_key) == 8 */
-
-struct sadb_ident {
-       uint16_t        sadb_ident_len;
-       uint16_t        sadb_ident_exttype;
-       uint16_t        sadb_ident_type;
-       uint16_t        sadb_ident_reserved;
-       uint64_t        sadb_ident_id;
-} __attribute__((packed));
-/* sizeof(struct sadb_ident) == 16 */
-
-struct sadb_sens {
-       uint16_t        sadb_sens_len;
-       uint16_t        sadb_sens_exttype;
-       uint32_t        sadb_sens_dpd;
-       uint8_t         sadb_sens_sens_level;
-       uint8_t         sadb_sens_sens_len;
-       uint8_t         sadb_sens_integ_level;
-       uint8_t         sadb_sens_integ_len;
-       uint32_t        sadb_sens_reserved;
-} __attribute__((packed));
-/* sizeof(struct sadb_sens) == 16 */
-
-/* followed by:
-       uint64_t        sadb_sens_bitmap[sens_len];
-       uint64_t        sadb_integ_bitmap[integ_len];  */
-
-struct sadb_prop {
-       uint16_t        sadb_prop_len;
-       uint16_t        sadb_prop_exttype;
-       uint8_t         sadb_prop_replay;
-       uint8_t         sadb_prop_reserved[3];
-} __attribute__((packed));
-/* sizeof(struct sadb_prop) == 8 */
-
-/* followed by:
-       struct sadb_comb sadb_combs[(sadb_prop_len +
-               sizeof(uint64_t) - sizeof(struct sadb_prop)) /
-               sizeof(strut sadb_comb)]; */
-
-struct sadb_comb {
-       uint8_t         sadb_comb_auth;
-       uint8_t         sadb_comb_encrypt;
-       uint16_t        sadb_comb_flags;
-       uint16_t        sadb_comb_auth_minbits;
-       uint16_t        sadb_comb_auth_maxbits;
-       uint16_t        sadb_comb_encrypt_minbits;
-       uint16_t        sadb_comb_encrypt_maxbits;
-       uint32_t        sadb_comb_reserved;
-       uint32_t        sadb_comb_soft_allocations;
-       uint32_t        sadb_comb_hard_allocations;
-       uint64_t        sadb_comb_soft_bytes;
-       uint64_t        sadb_comb_hard_bytes;
-       uint64_t        sadb_comb_soft_addtime;
-       uint64_t        sadb_comb_hard_addtime;
-       uint64_t        sadb_comb_soft_usetime;
-       uint64_t        sadb_comb_hard_usetime;
-} __attribute__((packed));
-/* sizeof(struct sadb_comb) == 72 */
-
-struct sadb_supported {
-       uint16_t        sadb_supported_len;
-       uint16_t        sadb_supported_exttype;
-       uint32_t        sadb_supported_reserved;
-} __attribute__((packed));
-/* sizeof(struct sadb_supported) == 8 */
-
-/* followed by:
-       struct sadb_alg sadb_algs[(sadb_supported_len +
-               sizeof(uint64_t) - sizeof(struct sadb_supported)) /
-               sizeof(struct sadb_alg)]; */
-
-struct sadb_alg {
-       uint8_t         sadb_alg_id;
-       uint8_t         sadb_alg_ivlen;
-       uint16_t        sadb_alg_minbits;
-       uint16_t        sadb_alg_maxbits;
-       uint16_t        sadb_alg_reserved;
-} __attribute__((packed));
-/* sizeof(struct sadb_alg) == 8 */
-
-struct sadb_spirange {
-       uint16_t        sadb_spirange_len;
-       uint16_t        sadb_spirange_exttype;
-       uint32_t        sadb_spirange_min;
-       uint32_t        sadb_spirange_max;
-       uint32_t        sadb_spirange_reserved;
-} __attribute__((packed));
-/* sizeof(struct sadb_spirange) == 16 */
-
-struct sadb_x_kmprivate {
-       uint16_t        sadb_x_kmprivate_len;
-       uint16_t        sadb_x_kmprivate_exttype;
-       u_int32_t       sadb_x_kmprivate_reserved;
-} __attribute__((packed));
-/* sizeof(struct sadb_x_kmprivate) == 8 */
-
-struct sadb_x_sa2 {
-       uint16_t        sadb_x_sa2_len;
-       uint16_t        sadb_x_sa2_exttype;
-       uint8_t         sadb_x_sa2_mode;
-       uint8_t         sadb_x_sa2_reserved1;
-       uint16_t        sadb_x_sa2_reserved2;
-       uint32_t        sadb_x_sa2_sequence;
-       uint32_t        sadb_x_sa2_reqid;
-} __attribute__((packed));
-/* sizeof(struct sadb_x_sa2) == 16 */
-
-struct sadb_x_policy {
-       uint16_t        sadb_x_policy_len;
-       uint16_t        sadb_x_policy_exttype;
-       uint16_t        sadb_x_policy_type;
-       uint8_t         sadb_x_policy_dir;
-       uint8_t         sadb_x_policy_reserved;
-       uint32_t        sadb_x_policy_id;
-       uint32_t        sadb_x_policy_reserved2;
-} __attribute__((packed));
-/* sizeof(struct sadb_x_policy) == 16 */
-
-struct sadb_x_ipsecrequest {
-       uint16_t        sadb_x_ipsecrequest_len;
-       uint16_t        sadb_x_ipsecrequest_proto;
-       uint8_t         sadb_x_ipsecrequest_mode;
-       uint8_t         sadb_x_ipsecrequest_level;
-       uint16_t        sadb_x_ipsecrequest_reqid;
-} __attribute__((packed));
-/* sizeof(struct sadb_x_ipsecrequest) == 16 */
-
-/* This defines the TYPE of Nat Traversal in use.  Currently only one
- * type of NAT-T is supported, draft-ietf-ipsec-udp-encaps-06
- */
-struct sadb_x_nat_t_type {
-       uint16_t        sadb_x_nat_t_type_len;
-       uint16_t        sadb_x_nat_t_type_exttype;
-       uint8_t         sadb_x_nat_t_type_type;
-       uint8_t         sadb_x_nat_t_type_reserved[3];
-} __attribute__((packed));
-/* sizeof(struct sadb_x_nat_t_type) == 8 */
-
-/* Pass a NAT Traversal port (Source or Dest port) */
-struct sadb_x_nat_t_port {
-       uint16_t        sadb_x_nat_t_port_len;
-       uint16_t        sadb_x_nat_t_port_exttype;
-       uint16_t        sadb_x_nat_t_port_port;
-       uint16_t        sadb_x_nat_t_port_reserved;
-} __attribute__((packed));
-/* sizeof(struct sadb_x_nat_t_port) == 8 */
-
-/* Message types */
-#define SADB_RESERVED          0
-#define SADB_GETSPI            1
-#define SADB_UPDATE            2
-#define SADB_ADD               3
-#define SADB_DELETE            4
-#define SADB_GET               5
-#define SADB_ACQUIRE           6
-#define SADB_REGISTER          7
-#define SADB_EXPIRE            8
-#define SADB_FLUSH             9
-#define SADB_DUMP              10
-#define SADB_X_PROMISC         11
-#define SADB_X_PCHANGE         12
-#define SADB_X_SPDUPDATE       13
-#define SADB_X_SPDADD          14
-#define SADB_X_SPDDELETE       15
-#define SADB_X_SPDGET          16
-#define SADB_X_SPDACQUIRE      17
-#define SADB_X_SPDDUMP         18
-#define SADB_X_SPDFLUSH                19
-#define SADB_X_SPDSETIDX       20
-#define SADB_X_SPDEXPIRE       21
-#define SADB_X_SPDDELETE2      22
-#define SADB_X_NAT_T_NEW_MAPPING       23
-#define SADB_MAX               23
-
-/* Security Association flags */
-#define SADB_SAFLAGS_PFS       1
-
-/* Security Association states */
-#define SADB_SASTATE_LARVAL    0
-#define SADB_SASTATE_MATURE    1
-#define SADB_SASTATE_DYING     2
-#define SADB_SASTATE_DEAD      3
-#define SADB_SASTATE_MAX       3
-
-/* Security Association types */
-#define SADB_SATYPE_UNSPEC     0
-#define SADB_SATYPE_AH         2
-#define SADB_SATYPE_ESP                3
-#define SADB_SATYPE_RSVP       5
-#define SADB_SATYPE_OSPFV2     6
-#define SADB_SATYPE_RIPV2      7
-#define SADB_SATYPE_MIP                8
-#define SADB_X_SATYPE_IPCOMP   9
-#define SADB_SATYPE_MAX                9
-
-/* Authentication algorithms */
-#define SADB_AALG_NONE                 0
-#define SADB_AALG_MD5HMAC              2
-#define SADB_AALG_SHA1HMAC             3
-#define SADB_X_AALG_SHA2_256HMAC       5
-#define SADB_X_AALG_SHA2_384HMAC       6
-#define SADB_X_AALG_SHA2_512HMAC       7
-#define SADB_X_AALG_RIPEMD160HMAC      8
-#define SADB_X_AALG_NULL               251     /* kame */
-#define SADB_AALG_MAX                  251
-
-/* Encryption algorithms */
-#define SADB_EALG_NONE                 0
-#define SADB_EALG_DESCBC               2
-#define SADB_EALG_3DESCBC              3
-#define SADB_X_EALG_CASTCBC            6
-#define SADB_X_EALG_BLOWFISHCBC                7
-#define SADB_EALG_NULL                 11
-#define SADB_X_EALG_AESCBC             12
-#define SADB_EALG_MAX                  12
-
-/* Compression algorithms */
-#define SADB_X_CALG_NONE               0
-#define SADB_X_CALG_OUI                        1
-#define SADB_X_CALG_DEFLATE            2
-#define SADB_X_CALG_LZS                        3
-#define SADB_X_CALG_LZJH               4
-#define SADB_X_CALG_MAX                        4
-
-/* Extension Header values */
-#define SADB_EXT_RESERVED              0
-#define SADB_EXT_SA                    1
-#define SADB_EXT_LIFETIME_CURRENT      2
-#define SADB_EXT_LIFETIME_HARD         3
-#define SADB_EXT_LIFETIME_SOFT         4
-#define SADB_EXT_ADDRESS_SRC           5
-#define SADB_EXT_ADDRESS_DST           6
-#define SADB_EXT_ADDRESS_PROXY         7
-#define SADB_EXT_KEY_AUTH              8
-#define SADB_EXT_KEY_ENCRYPT           9
-#define SADB_EXT_IDENTITY_SRC          10
-#define SADB_EXT_IDENTITY_DST          11
-#define SADB_EXT_SENSITIVITY           12
-#define SADB_EXT_PROPOSAL              13
-#define SADB_EXT_SUPPORTED_AUTH                14
-#define SADB_EXT_SUPPORTED_ENCRYPT     15
-#define SADB_EXT_SPIRANGE              16
-#define SADB_X_EXT_KMPRIVATE           17
-#define SADB_X_EXT_POLICY              18
-#define SADB_X_EXT_SA2                 19
-/* The next four entries are for setting up NAT Traversal */
-#define SADB_X_EXT_NAT_T_TYPE          20
-#define SADB_X_EXT_NAT_T_SPORT         21
-#define SADB_X_EXT_NAT_T_DPORT         22
-#define SADB_X_EXT_NAT_T_OA            23
-#define SADB_EXT_MAX                   23
-
-/* Identity Extension values */
-#define SADB_IDENTTYPE_RESERVED        0
-#define SADB_IDENTTYPE_PREFIX  1
-#define SADB_IDENTTYPE_FQDN    2
-#define SADB_IDENTTYPE_USERFQDN        3
-#define SADB_IDENTTYPE_MAX     3
-
-#endif /* !(_LINUX_PFKEY2_H) */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/random.c
--- a/tools/vnet/vnet-module/random.c   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/random.h>
-
-#include "hash_table.h"
-
-#define MODULE_NAME "RANDOM"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** @file
- * Source of randomness.
- * Current implementation is not enough.
- * Needs to be cryptographically strong.
- */
-
-static unsigned long seed = 0;
-static unsigned long count = 0;
-
-/** Contribute some random bytes.
- *
- * @param src bytes to contribute
- * @param src_n number of bytes
- */
-void add_random_bytes(const void *src, int src_n){
-    ++count;
-    seed = hash_hvoid(seed, &count, sizeof(count));
-    seed = hash_hvoid(seed, src, src_n);
-}
-
-/** Get one random byte.
- *
- * @return random byte
- */
-int get_random_byte(void){
-    int tmp = jiffies;
-    add_random_bytes(&tmp, sizeof(tmp));
-    return seed;
-}
-
-#ifndef __KERNEL__
-/* Get some random bytes.
- *
- * @param dst destination for the bytes
- * @param dst_n number of bytes to get
- */
-void get_random_bytes(void *dst, int dst_n){
-    int i;
-    char *p = (char *)dst;
-    for(i = 0; i < dst_n; i++){
-        *p++ = get_random_byte();
-    }
-}
-#endif
-
-int __init random_module_init(void){
-    int dummy;
-    int tmp = jiffies;
-    seed = (unsigned long)&dummy;
-    add_random_bytes(&tmp, sizeof(tmp));
-    return 0;
-}
-
-void __exit random_module_exit(void){
-}
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/random.h
--- a/tools/vnet/vnet-module/random.h   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __VNET_RANDOM_H__
-#define __VNET_RANDOM_H__
-
-extern void get_random_bytes(void *dst, int dst_n);
-extern void add_random_bytes(const void *src, int src_n);
-
-extern int random_module_init(void);
-extern void random_module_exit(void);
-
-#endif /* ! __VNET_RANDOM_H__ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/sa.c
--- a/tools/vnet/vnet-module/sa.c       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,756 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/kernel.h>
-
-#include <tunnel.h>
-#include <vnet.h>
-#include <sa.h>
-#include <sa_algorithm.h>
-
-#include "hash_table.h"
-#include "allocate.h"
-
-#define MODULE_NAME "IPSEC"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** @file IPSEC Security Association (SA).
- */
-
-/** Maximum number of protocols.*/
-#define INET_PROTOCOL_MAX 256
-
-/** Table of SA types indexed by protocol. */
-static SAType *sa_type[INET_PROTOCOL_MAX] = {};
-
-/** Hash a protocol number.
- *
- * @param protocol protocol number
- * @return hashcode
- */
-static inline unsigned char InetProtocol_hash(int protocol){
-    return (protocol) & (INET_PROTOCOL_MAX - 1);
-}
-
-/** Register an SA type.
- * It is an error if an SA type is already registered for the protocol.
- *
- * @param type SA type
- * @return 0 on success, error code otherwise
- */
-int SAType_add(SAType *type){
-    int err = -EINVAL;
-    int hash;
-    if(!type) goto exit;
-    hash = InetProtocol_hash(type->protocol);
-    if(sa_type[hash]) goto exit;
-    err = 0;
-    sa_type[hash] = type;
-  exit:
-    return err;
-}
-
-/** Deregister an SA type.
- * It is an error if no SA type is registered for the protocol.
- *
- * @param type SA type
- * @return 0 on success, error code otherwise
- */
-int SAType_del(SAType *type){
-    int err = -EINVAL;
-    int hash;
-    if(!type) goto exit;
-    hash = InetProtocol_hash(type->protocol);
-    if(!sa_type[hash]) goto exit;
-    err = 0;
-    sa_type[hash] = NULL;
-  exit:
-    return err;
-}
-
-int SAType_get(int protocol, SAType **type){
-   int err = -ENOENT;
-   int hash;
-   hash = InetProtocol_hash(protocol);
-   *type = sa_type[hash];
-   if(!*type) goto exit;
-   err = 0;
-  exit:
-   return err;
-}
-
-/* Defeat compiler warnings about unused functions. */
-static int sa_key_check(SAKey *key, enum sa_alg_type type) 
__attribute__((unused));
-static u32 random_spi(void) __attribute__((unused));
-static u32 generate_key(u32 key, u32 offset, u32 spi) __attribute__((unused));
-
-/** Check a key has an acceptable length for an algorithm.
- *
- * @param key key
- * @param type algorithm
- * @return 0 on success, error code otherwise
- */
-static int sa_key_check(SAKey *key, enum sa_alg_type type){
-    return 0;
-}
-
-static unsigned long sa_spi_counter = 0;
-
-/** Mangle some input to generate output.
- * This is used to derive spis and keying material from secrets,
- * so it probably ought to be cryptographically strong.
- * Probably ought to use a good hash (sha1) or cipher (aes).
- *
- * @param input input bytes
- * @param n number of bytes
- * @return mangled value
- */
-static u32 mangle(void *input, int n){
-    return hash_hvoid(0, input, n);
-}
-
-/** Generate a random spi.
- * Uses a hashed counter.
- *
- * @return spi
- */
-static u32 random_spi(void){
-    u32 spi;
-    do{
-        spi = sa_spi_counter++;
-        spi = mangle(&spi, sizeof(spi));
-    } while(!spi);
-    return spi;
-}
-
- /** Generate a spi for a given protocol and address, using a secret key.
-  * The offset is used when it is necessary to generate more than one spi
-  * for the same protocol and address.
-  *
-  * @param key key
-  * @param offset offset
-  * @param protocol protocol
-  * @param addr IP address
-  * @return spi
-  */
-static u32 generate_spi(u32 key, u32 offset, u32 protocol, u32 addr){
-    u32 input[] = { key, offset, protocol, addr };
-    return mangle(input, sizeof(input));
-}
-
-/** Generate keying material for a given spi, based on a
- * secret.
- *
- * @param key secret
- * @param offset offset
- * @param spi spi
- * @return keying material
- */
-static u32 generate_key(u32 key, u32 offset, u32 spi){
-    u32 input[] = { key, offset, spi };
-    return mangle(input, sizeof(input));
-}    
-
-/** Allocate a spi.
- * Want to use random ones.
- * So check for ones not in use.
- *
- * When using static keying, both ends need to agree on key.
- * How does that work? Also, will suddenly get traffic using a spi,
- * and will have to create SA then. Or need to create in advance.
- * But can't do that because don't know peers.
- * When get message on a spi that doesn't exist - do what?
- * Use a spi related to the destination addr and a secret.
- * Then receiver can check if spi is ok and create SA on demand.
- * Use hash of key, protocol, addr to generate. Then have to check
- * for in-use because of potential collisions. Receiver can do the
- * same hash and check spi is in usable range. Then derive keys from
- * the spi (using another secret).
- *
- * @param key spi generation key
- * @param protocol protocol
- * @param addr IP address
- * @param spip return parameter for spi
- * @return 0 on success, error code otherwise
- */
-int sa_spi_alloc(u32 key, u32 protocol, u32 addr, u32 *spip){
-    int err = 0;
-    int i = 0, n = 100;
-    u32 spi;
-    for(i = 0; i < n; i++, spi++){
-        spi = generate_spi(key, i, protocol, addr);
-        if(!spi) continue;
-        if(!sa_table_lookup_spi(spi, protocol, addr)){
-            *spip = spi;
-            goto exit;
-        }
-    }
-    err = -ENOMEM;
-  exit:
-    return err;
-}
-
-/** Table of SAs. Indexed by unique id and spi/protocol/addr triple.
- */
-static HashTable *sa_table = NULL;
-
-static u32 sa_id = 1;
-
-/** Hash an SA id.
- *
- * @param id SA id
- * @return hashcode
- */
-static inline Hashcode sa_table_hash_id(u32 id){
-    return hash_hvoid(0, &id, sizeof(id));
-}
-
-/** Hash SA spi/protocol/addr.
- *
- * @param spi spi
- * @param protocol protocol
- * @param addr IP address
- * @return hashcode
- */
-static inline Hashcode sa_table_hash_spi(u32 spi, u32 protocol, u32 addr){
-    u32 a[] = { spi, protocol, addr };
-    return hash_hvoid(0, a, sizeof(a));
-}
-
-/** Test if an SA entry has a given value.
- *
- * @param arg contains SA pointer
- * @param table hashtable
- * @param entry entry containing SA
- * @return 1 if it does, 0 otherwise
- */
-static int sa_table_state_fn(TableArg arg, HashTable *table, HTEntry *entry){
-    return entry->value == arg.ptr;
-}
-
-/** Test if an SA entry has a given id.
- *
- * @param arg contains SA id
- * @param table hashtable
- * @param entry entry containing SA
- * @return 1 if it does, 0 otherwise
- */
-static int sa_table_id_fn(TableArg arg, HashTable *table, HTEntry *entry){
-    SAState *state = entry->value;
-    u32 id = arg.ul;
-    return state->ident.id == id;
-}
-
-/** Test if an SA entry has a given spi/protocol/addr.
- *
- * @param arg contains SAIdent pointer
- * @param table hashtable
- * @param entry entry containing SA
- * @return 1 if it does, 0 otherwise
- */
-static int sa_table_spi_fn(TableArg arg, HashTable *table, HTEntry *entry){
-    SAState *state = entry->value;
-    SAIdent *ident = arg.ptr;
-    return state->ident.spi      == ident->spi
-        && state->ident.protocol == ident->protocol
-        && state->ident.addr     == ident->addr;
-}
-
-/** Free an SA entry. Decrements the SA refcount and frees the entry.
- *
- * @param table containing table
- * @param entry to free
- */
-static void sa_table_free_fn(HashTable *table, HTEntry *entry){
-    if(!entry) return;
-    if(entry->value){
-        SAState *state = entry->value;
-        SAState_decref(state);
-    }
-    deallocate(entry);
-}
-
-/** Initialize the SA table.
- *
- * @return 0 on success, error code otherwise
- */
-int sa_table_init(void){
-    int err = 0;
-    sa_table = HashTable_new(0);
-    if(!sa_table){
-        err = -ENOMEM;
-        goto exit;
-    }
-    sa_table->entry_free_fn = sa_table_free_fn;
-
-  exit:
-    return err;
-}
-
-void sa_table_exit(void){
-    HashTable_free(sa_table);
-}
-
-/** Remove an SA from the table.
- *
- * @param state SA
- */
-int sa_table_delete(SAState *state){
-    int count = 0;
-    Hashcode h1, h2;
-    TableArg arg = { .ptr = state };
-    // Remove by id.
-    h1 = sa_table_hash_id(state->ident.id);
-    count += HashTable_remove_entry(sa_table, h1, sa_table_state_fn, arg);
-    // Remove by spi/protocol/addr if spi nonzero.
-    if(!state->ident.spi) goto exit;
-    h2 = sa_table_hash_spi(state->ident.spi, state->ident.protocol, 
state->ident.addr);
-    if(h1 == h2) goto exit;
-    count += HashTable_remove_entry(sa_table, h2, sa_table_state_fn, arg);
-  exit:
-    return count;
-}
-
-/** Add an SA to the table.
- * The SA is indexed by id and spi/protocol/addr (if the spi is non-zero).
- *
- * @param state SA
- * @return 0 on success, error code otherwise
- */
-int sa_table_add(SAState *state){
-    int err = 0;
-    Hashcode h1, h2;
-    int entries = 0;
-
-    dprintf(">\n");
-    // Index by id.
-    h1 = sa_table_hash_id(state->ident.id);
-    if(!HashTable_add_entry(sa_table, h1, HKEY(state->ident.id), state)){
-        err = -ENOMEM;
-        goto exit;
-    }
-    entries++;
-    SAState_incref(state);
-    // Index by spi/protocol/addr if spi non-zero.
-    if(state->ident.spi){
-        h2 = sa_table_hash_spi(state->ident.spi, state->ident.protocol, 
state->ident.addr);
-        if(h1 != h2){
-            if(!HashTable_add_entry(sa_table, h2, HKEY(state->ident.id), 
state)){
-                err = -ENOMEM;
-                goto exit;
-            }
-            entries++;
-            SAState_incref(state);
-        }
-    }
-  exit:
-    if(err && entries){
-        sa_table_delete(state);
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-
-/** Find an SA by spi/protocol/addr.
- * Increments the SA refcount on success.
- *
- * @param spi spi
- * @param protocol protocol
- * @param addr IP address
- * @return SA or NULL
- */
-SAState * sa_table_lookup_spi(u32 spi, u32 protocol, u32 addr){
-    SAState *state = NULL;
-    Hashcode h;
-    SAIdent id = {
-        .spi      = spi,
-        .protocol = protocol,
-        .addr     = addr };
-    TableArg arg = { .ptr = &id };
-    HTEntry *entry = NULL;
-
-    h = sa_table_hash_spi(spi, protocol, addr);
-    entry = HashTable_find_entry(sa_table, h, sa_table_spi_fn, arg);
-    if(entry){
-        state = entry->value;
-        SAState_incref(state);
-    }
-    return state;
-}
-
-/** Find an SA by unique id.
- * Increments the SA refcount on success.
- *
- * @param id id
- * @return SA or NULL
- */
-SAState * sa_table_lookup_id(u32 id){
-    Hashcode h;
-    TableArg arg = { .ul = id };
-    HTEntry *entry = NULL;
-    SAState *state = NULL;
-
-    dprintf("> id=%u\n", id);
-    h = sa_table_hash_id(id);
-    entry = HashTable_find_entry(sa_table, h, sa_table_id_fn, arg);
-    if(entry){
-        state = entry->value;
-        SAState_incref(state);
-    }
-    dprintf("< state=%p\n", state);
-    return state;
-}
-
-/** Replace an existing SA by another in the table.
- * The existing SA is not removed if the new one cannot be added.
- *
- * @param existing SA to replace
- * @param state new SA
- * @return 0 on success, error code otherwise
- */
-static int sa_table_replace(SAState *existing, SAState *state){
-    int err = 0;
-    // Need check for in-use?
-    
-    dprintf(">\n");
-    if(existing->keying.state != SA_STATE_ACQUIRE){
-        err = -EINVAL;
-        goto exit;
-    }
-    // replace it.
-    err = sa_table_add(state);
-    if(err) goto exit;
-    sa_table_delete(existing);
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Allocate an SA.
- *
- * @return SA or NULL
- */
-SAState *SAState_alloc(void){
-    SAState *state;
-    
-    dprintf(">\n");
-    state = kmalloc(sizeof(SAState), GFP_ATOMIC);
-    if(!state) goto exit;
-    *state = (SAState){};
-    atomic_set(&state->refcount, 1);
-    state->lock = SPIN_LOCK_UNLOCKED;
-  exit:
-    dprintf("< state=%p\n", state);
-    return state;
-}
-
-/** Create an SA in initial state.
- * It has no spi and its keying state is acquire.
- * It must have a unique id, protocol and address.
- * At some point it should get updated with a complete SA.
- *
- * @param ident SA identifier
- * @param statep return parameter for new SA
- * @return 0 on success, error code otherwise
- */
-int SAState_init(SAIdent *ident, SAState **statep){
-    int err = 0;
-    SAState *state = NULL;
-   
-    if(ident->spi || !ident->id){
-        err = -EINVAL;
-        goto exit;
-    }
-    state = SAState_alloc();
-    if (!state){
-        err = -ENOMEM;
-        goto exit;
-    }
-    state->ident = *ident;
-    state->keying.state = SA_STATE_ACQUIRE;
-  exit:
-    return err;
-}
-
-/** Create a complete SA, with spi and cipher suite.
- *
- * @param info SA parameters
- * @param statep return parameter for new SA
- * @return 0 on success, error code otherwise
- */
-int SAState_create(SAInfo *info, SAState **statep){
-    int err = 0;
-    SAState *state = NULL;
-
-    dprintf(">\n");
-    state = SAState_alloc();
-    if (!state){
-        err = -ENOMEM;
-        goto exit;
-    }
-    state->ident = info->ident;
-    state->limits = info->limits;
-    state->digest = info->digest;
-    state->cipher = info->cipher;
-    state->compress = info->compress;
-    state->security = info->security;
-    err = SAType_get(state->ident.protocol, &state->type);
-    if (err) goto exit;
-    err = state->type->init(state, NULL);
-    if (err) goto exit;
-    state->keying.state = SA_STATE_VALID;
-  exit:
-    if(err){
-        SAState_decref(state);
-        state = NULL;
-    }
-    *statep = state;
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Create an SA for the given spi etc.
- * For now we fix the cipher suite and the keys.
- * Digest is SHA1 HMAC with a 128-bit key.
- * Cipher is AES (Rijndael) in CBC mode with a 128-bit key.
- *
- * The cipher suite and keys should really come from policy, with the
- * possibility of negotiating them with the peer (using IKE).
- * Negotiation creates difficulties though - because the SA cannot
- * be created immediately we have to be able to queue packets
- * while the SA is being negotiated.
- *
- * @param spi spi
- * @param protocol protocol
- * @param addr address
- * @param sa return parameter for SA
- * @return 0 on success, error code otherwise
- */
-int sa_create(int security, u32 spi, u32 protocol, u32 addr, SAState **sa){
-    int err = 0;
-    SAInfo info = {};
-    char *digest_name = "sha1";
-    char *digest_key = "0123456789abcdef";
-    int digest_key_n = strlen(digest_key);
-    char *cipher_name= "aes";
-    char *cipher_key = "0123456789ABCDEF";
-    int cipher_key_n = strlen(cipher_key);
-
-    dprintf("> security=%d spi=%u protocol=%u addr=" IPFMT "\n",
-            security, spi, protocol, NIPQUAD(addr));
-    if(!spi){
-        spi = generate_spi(0, 0, protocol, addr);
-    }
-    dprintf("> info...\n");
-    info.ident.id = sa_id++;
-    info.ident.spi = spi;
-    info.ident.protocol = protocol;
-    info.ident.addr = addr;
-    info.security = security;
-
-    //sa_algorithm_probe_all();
-
-    dprintf("> digest name=%s key_n=%d\n", digest_name, digest_key_n);
-    strcpy(info.digest.name, digest_name);
-    info.digest.bits = digest_key_n * 8;
-    memcpy(info.digest.key, digest_key, digest_key_n);
-
-    if(security & SA_CONF){
-        dprintf("> cipher name=%s key_n=%d\n", cipher_name, cipher_key_n);
-        strcpy(info.cipher.name, cipher_name);
-        info.cipher.bits = cipher_key_n * 8;
-        memcpy(info.cipher.key, cipher_key, cipher_key_n);
-    } else {
-        dprintf("> cipher name=%s key_n=%d\n", "cipher_null", 0);
-        strcpy(info.cipher.name, "cipher_null");
-        info.cipher.bits = 0;
-        memset(info.cipher.key, 0, sizeof(info.cipher.key));
-    }
-
-    err = sa_set(&info, 0, sa);
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Create or update an SA.
- * The SA is added to the table.
- *
- * @param info SA parameters
- * @param update create if zero, update otherwise
- * @return 0 on success, error code otherwise
- */
-int sa_set(SAInfo *info, int update, SAState **val){
-    int err = 0;
-    SAState *state = NULL;
-    SAState *existing = NULL;
-
-    dprintf("> info=%p update=%d val=%p\n", info, update, val);
-    existing = sa_table_lookup_id(info->ident.id);
-    if(update && !existing){
-        err = -ENOENT;
-    } else if(!update && existing){
-        err = -EINVAL;
-    }
-    if(err) goto exit;
-    err = SAState_create(info, &state);
-    if (err) goto exit;
-    if(existing){
-        err = sa_table_replace(existing, state);
-    } else {
-        err = sa_table_add(state);
-    }
-  exit:
-    if(existing) SAState_decref(existing);
-    if(val && !err){
-        *val = state;
-    } else {
-        SAState_decref(state);
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Delete an SA. Removes it from the SA table.
- * It is an error if no SA with the given id exists.
- *
- * @param id SA id
- * @return 0 on success, error code otherwise
- */
-int sa_delete(int id){
-    int err = 0;
-    SAState *state;
-    state = sa_table_lookup_id(id);
-    if (!state){
-        err = -ENOENT;
-        goto exit;
-    }
-    sa_table_delete(state);
-    SAState_decref(state);
-  exit:
-    return err;
-}
-/** Determine ESP security mode for a new SA.
- *
- * @param spi incoming spi
- * @param protocol incoming protocol
- * @param addr source address
- * @return security level or negative error code
- *
- * @todo Need to check spi, and do some lookup for security params.
- */
-int vnet_sa_security(u32 spi, int protocol, u32 addr){
-    extern int vnet_security_default;
-    int security = vnet_security_default;
-    dprintf("< security=%x\n", security);
-    return security;
-}
-
-/** Create a new SA for incoming traffic.
- *
- * @param spi incoming spi
- * @param protocol incoming protocol
- * @param addr source address
- * @param sa return parameter for SA
- * @return 0 on success, error code otherwise
- */
-int vnet_sa_create(u32 spi, int protocol, u32 addr, SAState **sa){
-    int err = 0;
-    int security = vnet_sa_security(spi, protocol, addr);
-    if(security < 0){
-        err = security;
-        goto exit;
-    }
-    err = sa_create(security, spi, protocol, addr, sa);
-  exit:
-    return err;
-}
-/** Open function for SA tunnels.
- *
- * @param tunnel to open
- * @return 0 on success, error code otherwise
- */
-static int sa_tunnel_open(Tunnel *tunnel){
-    int err = 0;
-    //dprintf(">\n");
-    //dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Close function for SA tunnels.
- *
- * @param tunnel to close (OK if null)
- */
-static void sa_tunnel_close(Tunnel *tunnel){
-    SAState *sa;
-    if(!tunnel) return;
-    sa = tunnel->data;
-    if(!sa) return;
-    SAState_decref(sa);
-    tunnel->data = NULL;
-}
-
-/** Packet send function for SA tunnels.
- *
- * @param tunnel to send on
- * @param skb packet to send
- * @return 0 on success, negative error code on error
- */
-static int sa_tunnel_send(Tunnel *tunnel, struct sk_buff *skb){
-    int err = -EINVAL;
-    SAState *sa;
-    if(!tunnel){
-        wprintf("> Null tunnel!\n");
-        goto exit;
-    }
-    sa = tunnel->data;
-    if(!sa){
-        wprintf("> Null SA!\n");
-        goto exit;
-    }
-    err = SAState_send(sa, skb, tunnel->base);
-  exit:
-    return err;
-}
-
-/** Functions used by SA tunnels. */
-static TunnelType _sa_tunnel_type = {
-    .name      = "SA",
-    .open      = sa_tunnel_open,
-    .close     = sa_tunnel_close,
-    .send      = sa_tunnel_send
-};
-
-/** Functions used by SA tunnels. */
-TunnelType *sa_tunnel_type = &_sa_tunnel_type;
-
-int sa_tunnel_create(Vnet *info, VarpAddr *addr, Tunnel *base, Tunnel 
**tunnel){
-    int err = 0;
-    SAState *sa = NULL;
-    //FIXME: Assuming IPv4 for now.
-    u32 ipaddr = addr->u.ip4.s_addr;
-    err = Tunnel_create(sa_tunnel_type, &info->vnet, addr, base, tunnel);
-    if(err) goto exit;
-    err = sa_create(info->security, 0, IPPROTO_ESP, ipaddr, &sa);
-    if(err) goto exit;
-    (*tunnel)->data = sa;
-  exit:
-    return err;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/sa.h
--- a/tools/vnet/vnet-module/sa.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __VNET_SA_H__
-#define __VNET_SA_H__
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#include <linux/crypto.h>
-
-#else
-
-#include "sys_kernel.h"
-
-#endif
-
-struct Vnet;
-struct VarpAddr;
-struct Tunnel;
-
-#ifndef CRYPTO_MAX_KEY_BYTES
-#define CRYPTO_MAX_KEY_BYTES            64
-#define CRYPTO_MAX_KEY_BITS             (CRYPTO_MAX_KEY_BYTES * 8)
-#endif
-
-#ifndef CRYPTO_MAX_ALG_NAME
-#define CRYPTO_MAX_ALG_NAME            64
-#endif
-
-typedef struct SALimits {
-    u64 bytes_soft;
-    u64 bytes_hard;
-    u64 packets_soft;
-    u64 packets_hard;
-} SALimits;
-
-typedef struct SACounts {
-    u64 bytes;
-    u64 packets;
-    u32 integrity_failures;
-} SACounts;
-
-typedef struct SAReplay {
-    int replay;
-    u32 send_seq;
-    u32 recv_seq;
-    u32 bitmap;
-    u32 replay_window;
-} SAReplay;
-
-typedef struct SAKey {
-    char name[CRYPTO_MAX_ALG_NAME];
-    int bits;
-    char key[CRYPTO_MAX_KEY_BYTES];
-} SAKey;
-
-typedef struct SAKeying {
-    u8 state;
-    u8 dying;
-} SAKeying;
-
-typedef struct SAIdent {
-    u32 id;
-    u32 spi;
-    u32 addr;
-    u32 protocol;
-} SAIdent;
-
-struct SAType;
-
-/** Security assocation (SA). */
-typedef struct SAState {
-    atomic_t refcount;
-    spinlock_t lock;
-    /** Identifier. */
-    struct SAIdent ident;
-    /** Security flags. */
-    int security;
-    /** Keying state. */
-    struct SAKeying keying;
-    /** Byte counts etc. */
-    struct SACounts counts;
-    /** Byte limits etc. */
-    struct SALimits limits;
-    /** Replay protection. */
-    struct SAReplay replay;
-    /** Digest algorithm. */
-    struct SAKey digest;
-    /** Cipher algorithm. */
-    struct SAKey cipher;
-    /** Compress algorith. */
-    struct SAKey compress;
-    /** SA type (ESP, AH). */
-    struct SAType *type;
-    /** Data for the SA type to use. */
-    void *data;
-} SAState;
-    
-typedef struct SAType {
-    char *name;
-    int protocol;
-    int (*init)(SAState *state, void *args);
-    void (*fini)(SAState *state);
-    int (*recv)(SAState *state, struct sk_buff *skb);
-    int (*send)(SAState *state, struct sk_buff *skb, struct Tunnel *tunnel);
-    u32 (*size)(SAState *state, int size);
-} SAType;
-
-/** Information needed to create an SA.
- * Unused algorithms have zero key size.
- */
-typedef struct SAInfo {
-    /** Identifier. */
-    SAIdent ident;
-    /** Security flags. */
-    int security;
-    /** Digest algorithm and key. */
-    SAKey digest;
-    /** Cipher algorithm and key. */
-    SAKey cipher;
-    /** Compress algorithm and key. */
-    SAKey compress;
-    /** SA lifetime limits. */
-    SALimits limits;
-    /** Replay protection window. */
-    int replay_window;
-} SAInfo;
-
-enum sa_alg_type {
-    SA_ALG_DIGEST = 1,
-    SA_ALG_CIPHER = 2,
-    SA_ALG_COMPRESS = 3,
-};
-
-extern int SAType_add(SAType *type);
-extern int SAType_del(SAType *type);
-extern int SAType_get(int protocol, SAType **type);
-
-extern int sa_table_init(void);
-extern void sa_table_exit(void);
-extern int sa_table_delete(SAState *state);
-extern int sa_table_add(SAState *state);
-extern SAState * sa_table_lookup_spi(u32 spi, u32 protocol, u32 addr);
-extern SAState * sa_table_lookup_id(u32 id);
-
-/** Increment reference count.
- *
- * @param sa security association (may be null)
- */
-static inline void SAState_incref(SAState *sa){
-    if(!sa) return;
-    atomic_inc(&sa->refcount);
-}
-
-/** Decrement reference count, freeing if zero.
- *
- * @param sa security association (may be null)
- */
-static inline void SAState_decref(SAState *sa){
-    if(!sa) return;
-    if(atomic_dec_and_test(&sa->refcount)){
-        sa->type->fini(sa);
-        kfree(sa);
-    }
-}
-
-extern SAState *SAState_alloc(void);
-extern int SAState_init(SAIdent *id, SAState **statep);
-extern int SAState_create(SAInfo *info, SAState **statep);
-
-static inline int SAState_send(SAState *sa, struct sk_buff *skb, struct Tunnel 
*tunnel){
-    return sa->type->send(sa, skb, tunnel);
-}
-
-static inline int SAState_recv(SAState *sa, struct sk_buff *skb){
-    return sa->type->recv(sa, skb);
-}
-
-static inline int SAState_size(SAState *sa, int n){
-    return sa->type->size(sa, n);
-}
-
-extern int sa_create(int security, u32 spi, u32 protocol, u32 addr, SAState 
**sa);
-extern int sa_set(SAInfo *info, int update, SAState **val);
-extern int sa_delete(int id);
-
-enum {
-    SA_AUTH = 1,
-    SA_CONF = 2
-};
-
-enum {
-    SA_STATE_ACQUIRE = 1,
-    SA_STATE_VALID   = 2,
-};
-
-extern int sa_tunnel_create(struct Vnet *info, struct VarpAddr *addr,
-                            struct Tunnel *base, struct Tunnel **tunnel);
-
-#endif /* !__VNET_SA_H__ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/sa_algorithm.c
--- a/tools/vnet/vnet-module/sa_algorithm.c     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,367 +0,0 @@
-/* 
- * Copyright (c) 2002 James Morris <jmorris@xxxxxxxxxxxxxxxx>
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/crypto.h>
-#include <linux/sched.h>
-//#include <asm/softirq.h>
-
-#include <sa_algorithm.h>
-
-#define MODULE_NAME "IPSEC"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** @file Tables of supported IPSEC algorithms.
- * Has tables for digests, ciphers and compression algorithms.
- */
-
-/*
- * Algorithms supported by IPsec.  These entries contain properties which
- * are used in key negotiation and sa processing, and are used to verify
- * that instantiated crypto transforms have correct parameters for IPsec
- * purposes.
- */
-
-/** Digests. */
-static SAAlgorithm digest_alg[] = {
-    {
-        .name = "digest_null",
-        .info = {
-            .digest = {
-                .icv_truncbits = 0,
-                .icv_fullbits = 0,
-            }
-        },
-        .alg = {
-            .sadb_alg_id = SADB_X_AALG_NULL,
-            .sadb_alg_ivlen = 0,
-            .sadb_alg_minbits = 0,
-            .sadb_alg_maxbits = 0
-        }
-    },
-    {
-       .name = "md5",
-       .info = { .digest = {
-            .icv_truncbits = 96,
-            .icv_fullbits = 128,
-        } },
-        .alg = {
-            .sadb_alg_id = SADB_AALG_MD5HMAC,
-            .sadb_alg_ivlen = 0,
-            .sadb_alg_minbits = 128,
-            .sadb_alg_maxbits = 128
-       }
-    },
-    {
-       .name = "sha1",
-       .info = {
-            .digest = {
-                .icv_truncbits = 96,
-                .icv_fullbits = 160,
-            }
-       },
-       .alg = {
-            .sadb_alg_id = SADB_AALG_SHA1HMAC,
-            .sadb_alg_ivlen = 0,
-            .sadb_alg_minbits = 160,
-            .sadb_alg_maxbits = 160
-       }
-    },
-    {
-       .name = "sha256",
-       .info = {
-            .digest = {
-                .icv_truncbits = 128,
-                .icv_fullbits = 256,
-            }
-       },
-       .alg = {
-            .sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
-            .sadb_alg_ivlen = 0,
-            .sadb_alg_minbits = 256,
-            .sadb_alg_maxbits = 256
-       }
-    },
-/*     { */
-/*         .name = "ripemd160", */
-/*         .info = { */
-/*             .digest = { */
-/*                 .icv_truncbits = 96, */
-/*                 .icv_fullbits = 160, */
-/*             } */
-/*     }, */
-/*         .alg = { */
-/*             .sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC, */
-/*             .sadb_alg_ivlen = 0, */
-/*             .sadb_alg_minbits = 160, */
-/*             .sadb_alg_maxbits = 160 */
-/*     } */
-/*     }, */
-    { /* Terminator */ }
-};
-
-/** Ciphers. */
-static SAAlgorithm cipher_alg[] = {
-    {
-       .name = "cipher_null",
-        .info = {
-            .cipher = {
-                .blockbits = 8,
-                .defkeybits = 0,
-            }
-       },
-        .alg = {
-            .sadb_alg_id =     SADB_EALG_NULL,
-            .sadb_alg_ivlen = 0,
-            .sadb_alg_minbits = 0,
-            .sadb_alg_maxbits = 0
-       }
-    },
-    {
-        .name = "des",
-        .info = {
-            .cipher = {
-                .blockbits = 64,
-                .defkeybits = 64,
-            }
-       },
-        .alg = {
-            .sadb_alg_id = SADB_EALG_DESCBC,
-            .sadb_alg_ivlen = 8,
-            .sadb_alg_minbits = 64,
-            .sadb_alg_maxbits = 64
-       }
-    },
-    {
-       .name = "des3_ede",
-       .info = {
-            .cipher = {
-                .blockbits = 64,
-                .defkeybits = 192,
-            }
-       },
-        .alg = {
-            .sadb_alg_id = SADB_EALG_3DESCBC,
-            .sadb_alg_ivlen = 8,
-            .sadb_alg_minbits = 192,
-            .sadb_alg_maxbits = 192
-       }
-    },
-/*     { */
-/*     .name = "cast128", */ //cast5?
-/*     .info = { */
-/*             .cipher = { */
-/*                 .blockbits = 64, */
-/*                 .defkeybits = 128, */
-/*             } */
-/*     }, */
-/*     .alg = { */
-/*             .sadb_alg_id = SADB_X_EALG_CASTCBC, */
-/*             .sadb_alg_ivlen = 8, */
-/*             .sadb_alg_minbits = 40, */
-/*             .sadb_alg_maxbits = 128 */
-/*     } */
-/*     }, */
-    {
-       .name = "blowfish",
-        .info = {
-            .cipher = {
-                .blockbits = 64,
-                .defkeybits = 128,
-            }
-       },
-       .alg = {
-            .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
-            .sadb_alg_ivlen = 8,
-            .sadb_alg_minbits = 40,
-            .sadb_alg_maxbits = 448
-       }
-    },
-    {
-       .name = "aes",
-       .info = {
-            .cipher = {
-                .blockbits = 128,
-                .defkeybits = 128,
-            }
-       },
-       .alg = {
-            .sadb_alg_id = SADB_X_EALG_AESCBC,
-            .sadb_alg_ivlen = 8,
-            .sadb_alg_minbits = 128,
-            .sadb_alg_maxbits = 256
-       }
-    },
-    { /* Terminator */ }
-};
-
-/** Compressors. */
-static SAAlgorithm compress_alg[] = {
-    {
-       .name = "deflate",
-       .info = {
-            .compress = {
-                .threshold = 90,
-            }
-       },
-       .alg = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
-    },
-/*     { */
-/*     .name = "lzs", */
-/*     .info = { */
-/*             .compress = { */
-/*                 .threshold = 90, */
-/*             } */
-/*     }, */
-/*     .alg = { .sadb_alg_id = SADB_X_CALG_LZS } */
-/*     }, */
-/*     { */
-/*     .name = "lzjh", */
-/*     .info = { */
-/*             .compress = { */
-/*                 .threshold = 50, */
-/*             } */
-/*     }, */
-/*     .alg = { .sadb_alg_id = SADB_X_CALG_LZJH } */
-/*     }, */
-    { /* Terminator */ }
-};
-
-static SAAlgorithm *sa_algorithm_by_id(SAAlgorithm *algo, int alg_id) {
-    for( ; algo && algo->name; algo++){
-        if (algo->alg.sadb_alg_id == alg_id) {
-            return (algo->available ? algo : NULL);
-        }
-    }
-    return NULL;
-}
-
-
-static SAAlgorithm *sa_algorithm_by_name(SAAlgorithm *algo, char *name) {
-       if (!name) return NULL;
-       for( ; algo && algo->name; algo++){
-               if (strcmp(name, algo->name) == 0) {
-                    return (algo->available ? algo : NULL);
-                }
-       }
-       return NULL;
-}
-
-SAAlgorithm *sa_digest_by_id(int alg_id) {
-    return sa_algorithm_by_id(digest_alg, alg_id);
-}
-
-SAAlgorithm *sa_cipher_by_id(int alg_id) {
-    return sa_algorithm_by_id(cipher_alg, alg_id);
-}
-
-SAAlgorithm *sa_compress_by_id(int alg_id) {
-    return sa_algorithm_by_id(compress_alg, alg_id);
-}
-
-SAAlgorithm *sa_digest_by_name(char *name) {
-    return sa_algorithm_by_name(digest_alg, name);
-}
-
-SAAlgorithm *sa_cipher_by_name(char *name) {
-    return sa_algorithm_by_name(cipher_alg, name);
-}
-
-SAAlgorithm *sa_compress_by_name(char *name) {
-    return sa_algorithm_by_name(compress_alg, name);
-}
-
-SAAlgorithm *sa_digest_by_index(unsigned int idx) {
-    return digest_alg + idx;
-}
-
-SAAlgorithm *sa_cipher_by_index(unsigned int idx) {
-    return cipher_alg + idx;
-}
-
-SAAlgorithm *sa_compress_by_index(unsigned int idx) {
-    return compress_alg + idx;
-}
-
-static void sa_algorithm_probe(SAAlgorithm *algo){
-    int status;
-    dprintf("> algo=%p\n", algo); 
-    for( ; algo && algo->name; algo++){
-        dprintf("> algorithm %s...\n", algo->name);
-        status = crypto_alg_available(algo->name, 0);
-        dprintf("> algorithm %s status=%d\n",algo->name, status); 
-        if (algo->available != status){
-            algo->available = status;
-        }
-    }
-    dprintf("<\n"); 
-}
-
-/** Crypto api is broken. When an unregistered algorithm is requested it
- * tries to load a module of the same name. But not all algorithms are
- * defined by modules of the same name.
- */
-static char *crypto_modules[] = {
-    "aes",
-    //"arc4",
-    "blowfish",
-    //"cast5",
-    //"cast6",
-    "crypto_null",
-    "des",
-    //"md4",
-    "md5",
-    //"serpent",
-    "sha1",
-    "sha256",
-    //"sha512",
-    //"twofish",
-    NULL
-};
-
-#include <linux/kmod.h>
-
-static void sa_module_probe(char **modules){
-    char **p;
-    dprintf(">\n");
-    for(p = modules; *p; p++){
-        dprintf("> %s\n", *p);
-       request_module(*p);
-    }
-    dprintf("<\n");
-}
-
-/**
- * Probe for the availability of crypto algorithms, and set the available
- * flag for any algorithms found on the system.  This is typically called by
- * pfkey during userspace SA add, update or register.
- */
-void sa_algorithm_probe_all(void){
-    dprintf("> \n"); 
-    //BUG_ON(in_softirq());
-    sa_module_probe(crypto_modules);
-    sa_algorithm_probe(digest_alg);
-    sa_algorithm_probe(cipher_alg);
-    sa_algorithm_probe(compress_alg);
-    dprintf("<\n"); 
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/sa_algorithm.h
--- a/tools/vnet/vnet-module/sa_algorithm.h     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __VNET_SA_ALGORITHM_H__
-#define __VNET_SA_ALGORITHM_H__
-
-#include <linux/types.h>
-#include <linux/pfkeyv2.h>
-
-typedef struct SADigestInfo {
-    u16 icv_truncbits;
-    u16 icv_fullbits;
-} SADigestInfo;
-
-typedef struct SACipherInfo {
-    u16 blockbits;
-    u16 defkeybits;
-} SACipherInfo;
-
-typedef struct SACompressInfo {
-    u16 threshold;
-} SACompressInfo;
-
-typedef struct SAAlgorithm {
-    char *name;
-    u8 available;
-    union {
-        SADigestInfo digest;
-        SACipherInfo cipher;
-        SACompressInfo compress;
-    } info;
-    struct sadb_alg alg;
-} SAAlgorithm;
-
-extern SAAlgorithm *sa_digest_by_id(int alg_id);
-extern SAAlgorithm *sa_cipher_by_id(int alg_id);
-extern SAAlgorithm *sa_compress_by_id(int alg_id);
-extern SAAlgorithm *sa_digest_by_name(char *name);
-extern SAAlgorithm *sa_cipher_by_name(char *name);
-extern SAAlgorithm *sa_compress_by_name(char *name);
-extern SAAlgorithm *sa_digest_by_index(unsigned int idx);
-extern SAAlgorithm *sa_cipher_by_index(unsigned int idx);
-extern SAAlgorithm *sa_compress_by_index(unsigned int idx);
-extern void sa_algorithm_probe_all(void);
-
-#define MAX_KEY_BITS 512
-
-#endif /* ! __VNET_SA_ALGORITHM_H__ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/skb_context.c
--- a/tools/vnet/vnet-module/skb_context.c      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-
-#include <skb_context.h>
-
-#define MODULE_NAME "VNET"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-SkbContext *SkbContext_create(u32 vnet, u32 addr, int protocol, void *data,
-                              void (*free_fn)(SkbContext *)){
-    SkbContext *context = NULL;
-
-    context = kmalloc(sizeof(SkbContext), GFP_ATOMIC);
-    if(!context) goto exit;
-    context->vnet = vnet;
-    context->addr = addr;
-    context->protocol = protocol;
-    context->data = data;
-    context->free_fn = free_fn;
-    context->next = NULL;
-    atomic_set(&context ->refcount, 1);
-  exit:
-    return context;
-}
-                                       
-void SkbContext_free(SkbContext *context){
-    if(!context) return;
-    if(context->next) SkbContext_decref(context->next);
-    if(context->free_fn) context->free_fn(context);
-    context->vnet = 0;
-    context->addr = 0;
-    context->protocol = 0;
-    context->free_fn = NULL;
-    context->data = NULL;
-    context->next = NULL;
-    kfree(context);
-}
-
-int SkbContext_push(SkbContext **val, u32 vnet, u32 addr, int protocol,
-                    void *data, void (*free_fn)(SkbContext *)){
-    int err = 0;
-    SkbContext *context = NULL;
-
-    dprintf("> vnet=%u addr=%u.%u.%u.%u protocol=%d\n",
-            vnet, NIPQUAD(addr), protocol);
-    context = SkbContext_create(vnet, addr, protocol, data, free_fn);
-    if(!context){
-        err = -ENOMEM;
-        goto exit;
-    }
-    context->next = *val;
-    *val = context;
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-int skb_push_context(struct sk_buff *skb, u32 vnet, u32 addr, int protocol,
-                     void *data, void (*free_fn)(SkbContext *)){
-    int err = 0;
-    //SkbContext *ctxt = SKB_CONTEXT(skb);
-    dprintf("> skb=%p\n", skb);
-
-    //err = SkbContext_push(&ctxt, vnet, addr, protocol, data, free_fn); 
//todo fixme
-    //SKB_CONTEXT(skb) = ctxt;//todo fixme
-    dprintf("< err=%d\n", err);
-    return err;
-}
-                                       
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/skb_context.h
--- a/tools/vnet/vnet-module/skb_context.h      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __VNET_SKB_CONTEXT_H__
-#define __VNET_SKB_CONTEXT_H__
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <asm/atomic.h>
-#include <linux/types.h>
-
-//todo: fixme
-#define SKB_CONTEXT(_skb) ((SkbContext *)(&(_skb)->cb[0]))
-
-#else
-
-#include "sys_kernel.h"
-#include "spinlock.h"
-
-//todo: fixme
-#define SKB_CONTEXT(_skb) ((SkbContext *)NULL)
-
-#endif
-
-/** Structure used to record inbound processing path for skbs.
- * For example, the ETHERIP protocol handler can use this to
- * tell whether an inbound packet came through IPSEC ESP or not.
- */
-typedef struct SkbContext {
-    u32 vnet;
-    u32 addr;
-    int protocol;
-    void *data;
-    void (*free_fn)(struct SkbContext *);
-    atomic_t refcount;
-    struct SkbContext *next;
-} SkbContext;
-
-/** Decrement the reference count, freeing if zero.
- *
- * @param context context (may be null)
- */
-static inline void SkbContext_decref(SkbContext *context){
-    extern void SkbContext_free(SkbContext *context);
-    if(!context) return;
-    if(atomic_dec_and_test(&context->refcount)){
-        SkbContext_free(context);
-    }
-}
-
-/** Increment the reference count.
- *
- * @param context context (may be null)
- */
-static inline void SkbContext_incref(SkbContext *context){
-    if(!context) return;
-    atomic_inc(&context->refcount);
-}
-
-extern SkbContext *SkbContext_create(u32 vnet, u32 addr, int protocol, void 
*data,
-                                     void (*free_fn)(SkbContext *));
-
-extern int SkbContext_push(SkbContext **val, u32 vnet, u32 addr, int protocol,
-                           void *data, void (*free_fn)(SkbContext *));
-
-struct sk_buff;
-extern int skb_push_context(struct sk_buff *skb, u32 vnet, u32 addr, int 
protocol,
-                            void *data, void (*free_fn)(SkbContext *));
-
-#endif /* !__VNET_SKB_CONTEXT_H__ */ 
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/skb_util.c
--- a/tools/vnet/vnet-module/skb_util.c Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,556 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/version.h>
-
-#include <asm/scatterlist.h>
-#include <linux/crypto.h>
-#include <linux/pfkeyv2.h>
-#include <linux/random.h>
-
-#include <linux/net.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/route.h>
-#include <linux/skbuff.h>
-
-#else
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-
-#include "sys_kernel.h"
-#include "skbuff.h"
-
-#if defined(__LITTLE_ENDIAN)
-#define HIPQUAD(addr) \
-       ((unsigned char *)&addr)[3], \
-       ((unsigned char *)&addr)[2], \
-       ((unsigned char *)&addr)[1], \
-       ((unsigned char *)&addr)[0]
-#elif defined(__BIG_ENDIAN)
-#define HIPQUAD        NIPQUAD
-#else
-#error "Please fix asm/byteorder.h"
-#endif /* __LITTLE_ENDIAN */
-
-#endif
-
-#include <varp.h>
-#include <skb_util.h>
-
-#define MODULE_NAME "VNET"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-//============================================================================
-/** Make enough room in an skb for extra header and trailer.
- *
- * @param pskb return parameter for expanded skb
- * @param skb skb
- * @param head_n required headroom
- * @param tail_n required tailroom
- * @return 0 on success, error code otherwise
- */
-int skb_make_room(struct sk_buff **pskb, struct sk_buff *skb, int head_n, int 
tail_n){
-    int err = 0;
-    int has_headroom = (head_n <= skb_headroom(skb));
-    int has_tailroom = (tail_n <= skb_tailroom(skb));
-    int writeable = !skb_cloned(skb) && !skb_shared(skb);
-
-    dprintf("> skb=%p headroom=%d head_n=%d tailroom=%d tail_n=%d\n",
-            skb,
-            skb_headroom(skb), head_n,
-            skb_tailroom(skb), tail_n);
-    if(writeable && has_headroom && has_tailroom){
-        // There's room! Reuse it.
-        *pskb = skb;
-    } else if(writeable && has_tailroom){
-        // Tailroom, no headroom. Expand header the way GRE does.
-        struct sk_buff *new_skb = skb_realloc_headroom(skb, head_n + 16);
-        if(!new_skb){
-            err = -ENOMEM;
-            goto exit;
-        }
-        kfree_skb(skb);
-        *pskb = new_skb;
-    } else {
-        // No room. Expand. There may be more efficient ways to do
-        // this, but this is simple and correct.
-        struct sk_buff *new_skb = skb_copy_expand(skb, head_n + 16, tail_n, 
GFP_ATOMIC);
-        if(!new_skb){
-            err = -ENOMEM;
-            goto exit;
-        }
-        kfree_skb(skb);
-        *pskb = new_skb;
-    }
-    dprintf("> skb=%p headroom=%d head_n=%d tailroom=%d tail_n=%d\n",
-            *pskb,
-            skb_headroom(*pskb), head_n,
-            skb_tailroom(*pskb), tail_n);
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Copy some data bits from a kernel buffer to an skb.
- * Derived in the obvious way from skb_copy_bits().
- */
-int skb_put_bits(const struct sk_buff *skb, int offset, void *src, int len)
-{
-    int i, copy;
-    int start = skb->len - skb->data_len;
-
-    if (offset > (int)skb->len-len)
-        goto fault;
-
-    /* Copy header. */
-    if ((copy = start-offset) > 0) {
-        if (copy > len)
-            copy = len;
-        memcpy(skb->data + offset, src, copy);
-        if ((len -= copy) == 0)
-            return 0;
-        offset += copy;
-        src += copy;
-    }
-
-#ifdef __KERNEL__
-    for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-        int end;
-
-        BUG_TRAP(start <= offset+len);
-
-        end = start + skb_shinfo(skb)->frags[i].size;
-        if ((copy = end-offset) > 0) {
-            u8 *vaddr;
-
-            if (copy > len)
-                copy = len;
-
-            vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
-            memcpy(vaddr + skb_shinfo(skb)->frags[i].page_offset + offset - 
start,
-                   src,
-                   copy);
-            kunmap_skb_frag(vaddr);
-
-            if ((len -= copy) == 0)
-                return 0;
-            offset += copy;
-            src += copy;
-        }
-        start = end;
-    }
-
-    if (skb_shinfo(skb)->frag_list) {
-        struct sk_buff *list;
-        
-        for (list = skb_shinfo(skb)->frag_list; list; list=list->next) {
-            int end;
-            
-            BUG_TRAP(start <= offset+len);
-            
-            end = start + list->len;
-            if ((copy = end-offset) > 0) {
-                if (copy > len)
-                    copy = len;
-                if (skb_put_bits(list, offset-start, src, copy))
-                    goto fault;
-                if ((len -= copy) == 0)
-                    return 0;
-                offset += copy;
-                src += copy;
-            }
-            start = end;
-        }
-    }
-#else
-    i=0;
-#endif
-
-    if (len == 0)
-        return 0;
-
- fault:
-    return -EFAULT;
-}
-
-int skboffset(struct sk_buff *skb, unsigned char *ptr){
-    if(!ptr || ptr < skb->head || ptr > skb->tail){
-        return -1;
-    }
-    return (ptr - skb->head);
-}
-
-/** Print some bits of an skb.
- *
- * @param skb to print
- * @param offset byte offset to start printing at
- * @param n number of bytes to print
- */
-void skb_print_bits(const char *msg, struct sk_buff *skb, int offset, int n){
-    int chunk = 16;
-    int i, k;
-    u8 buff[chunk];
-    if(!skb) return;
-    printk("%s> tot=%d len=%d data=%d mac=%d nh=%d h=%d\n",
-           msg,
-           skb->tail - skb->head,
-           skb->len,
-           skboffset(skb, skb->data),
-           skboffset(skb, skb->mac.raw),
-           skboffset(skb, skb->nh.raw),
-           skboffset(skb, skb->h.raw));
-    printk("%s> head=%p data=%p mac=%p nh=%p h=%p tail=%p\n",
-           msg, skb->head, skb->data,
-           skb->mac.raw, skb->nh.raw, skb->h.raw,
-           skb->tail);
-    while(n){
-        k = (n > chunk ? chunk : n);
-        skb_copy_bits(skb, offset, buff, k);
-        printk("%03d ", offset);
-        for(i=0; i<k; i++){
-            if(i == 8)printk(" "); 
-            printk(":%02x", buff[i] & 0xff);
-        }
-        printk(" \n");
-        n -= k;
-        offset += k;
-    }
-}
-
-/** Print a buffer.
- *
- * @param buf to print
- * @param n number of bytes to print
- */
-void buf_print(char *buf, int n){
-    int i;
-    for(i=0; i<n; i++){
-        if( i % 16 == 0) printk("\n%04d ", i);
-        else if(i % 8 == 0) printk(" ");
-        printk(":%02x", buf[i] & 0xff);
-    }
-    printk(" %04d\n", n);
-}
-
-/** Remove some space from the tail of an skb.
- *
- * @todo fixme: Do we need to handle frags?
- */
-void *skb_trim_tail(struct sk_buff *skb, int n){
-    skb->tail -= n;
-    skb->len -= n;
-    return skb->tail;
-}
-
-#ifdef __KERNEL__
-
-static const int DEBUG_SCATTERLIST = 0;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#define SET_SCATTER_ADDR(sg, addr) do{} while(0)
-#else
-#define SET_SCATTER_ADDR(sg, addr) (sg).address = (addr)
-#endif
-
-/** Convert a (possibly fragmented) skb into a scatter list.
- *
- * @param skb skb to convert
- * @param sg scatterlist to set up
- * @param sg_n size of sg on input, number of elements set on output
- * @param offset offset into data to start at
- * @param len number of bytes
- * @return 0 on success, error code otherwise
- */
-int skb_scatterlist(struct sk_buff *skb, struct scatterlist *sg, int *sg_n,
-                    int offset, int len){
-    int err = 0;
-    int start;         // No. of bytes copied so far (where next copy starts).
-    int size;          // Size of the next chunk.
-    int end;           // Where the next chunk ends (start + size).
-    int copy;          // Number of bytes to copy in one operation.
-    int sg_i = 0;      // Index into sg.
-    int i;
-    
-    if(DEBUG_SCATTERLIST){
-        dprintf("> offset=%d len=%d (end=%d), skb len=%d,\n",
-                offset, len, offset+len, skb->len);
-    }
-    start = 0;
-    size = skb_headlen(skb);
-    end = start + size;
-    copy = end - offset;
-    if(copy > 0){
-        char *p;
-        if(copy > len) copy = len;
-        if(sg_i >= *sg_n){
-            err = -EINVAL;
-            goto exit;
-        }
-        p = skb->data + offset;
-        SET_SCATTER_ADDR(sg[sg_i], NULL);
-        sg[sg_i].page = virt_to_page(p);
-        sg[sg_i].offset = ((unsigned long)p & ~PAGE_MASK);
-        sg[sg_i].length = copy;
-        if(DEBUG_SCATTERLIST){
-            dprintf("> sg_i=%d .page=%p .offset=%u .length=%d\n",
-                    sg_i, sg[sg_i].page, sg[sg_i].offset, sg[sg_i].length);
-        }
-        sg_i++;
-        if((len -= copy) == 0) goto exit;
-        offset += copy;
-    }
-    start = end;
-    for (i = 0; i < skb_shinfo(skb)->nr_frags; i++){
-        BUG_TRAP(start <= offset + len);
-        size = skb_shinfo(skb)->frags[i].size;
-        end = start + size;
-        copy = end - offset;
-        if(copy > 0){
-            skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-            if(copy > len) copy = len;
-            if(sg_i >= *sg_n){
-                err = -EINVAL;
-                goto exit;
-            }
-            SET_SCATTER_ADDR(sg[sg_i], NULL);
-            sg[sg_i].page = frag->page;
-            sg[sg_i].offset = frag->page_offset + offset - start;
-            sg[sg_i].length = copy;
-            if(DEBUG_SCATTERLIST){
-                dprintf("> sg_i=%d .page=%p .offset=%u .length=%d\n",
-                        sg_i, sg[sg_i].page, sg[sg_i].offset, sg[sg_i].length);
-            }
-            sg_i++;
-            if((len -= copy) == 0) goto exit;
-            offset += copy;
-        }
-        start = end;
-    }
-  exit:
-    if(!err) *sg_n = sg_i;
-    if(len) wprintf("> len=%d\n", len);
-    if(len) BUG();
-    if(err) dprintf("< err=%d sg_n=%d\n", err, *sg_n);
-    return err;
-}
-
-#endif
-
-void print_skb_data(const char *msg, int count, struct sk_buff *skb, u8 *data, 
int len)
-{
-    static int skb_count = 1000000;
-    u8 *ptr, *end;
-    u32 src_addr, dst_addr;
-    // Transport layer header.
-    union {
-        struct tcphdr  *th;
-        struct udphdr  *uh;
-        struct icmphdr *icmph;
-        struct igmphdr *igmph;
-        struct iphdr   *ipiph;
-        unsigned char  *raw;
-    } h;
-    // Network layer header.
-    union {
-        struct iphdr   *iph;
-        struct ipv6hdr *ipv6h;
-        struct arpheader  *arph;
-        struct ipxhdr  *ipxh;
-        unsigned char  *raw;
-    } nh;
-    // Link layer header.
-    union {
-        struct ethhdr  *ethernet;
-        unsigned char  *raw;
-    } mac;
-    int protocol;
-    if(!count) count = ++skb_count;
-    if(!msg) msg = (char *)__FUNCTION__;
-    if(!data){
-        printk("%s.%d> null data\n", msg, count);
-        return;
-    }
-    ptr = data;
-    end = data + len;
-    mac.raw = ptr;
-    ptr += sizeof(struct ethhdr);
-    if(ptr > end){ printk("***MAC:");  goto exit; }
-    protocol = ntohs(mac.ethernet->h_proto);
-    nh.raw = ptr;
-
-    printk("%s.%d> type=%d protocol=0x%x\n",
-           msg, count, skb->pkt_type, htons(skb->protocol));
-    if(1){
-        printk("%s.%d> %p mac src=" MACFMT " dst=" MACFMT "\n",
-               msg, count, data,
-               MAC6TUPLE(mac.ethernet->h_source),
-               MAC6TUPLE(mac.ethernet->h_dest));
-    }
-
-    switch(protocol){
-    case ETH_P_ARP:
-        ptr += sizeof(struct arpheader);
-        if(ptr > end){ printk("***ARP:");  goto exit; }
-        if(0){
-            printk("%s.%d> ARP hrd=%d, pro=%d, hln=%d, pln=%d, op=%d\n",
-                   msg, count,
-                   nh.arph->ar_hrd, nh.arph->ar_pro, nh.arph->ar_hln,
-                   nh.arph->ar_pln, nh.arph->ar_op);
-        }
-        memcpy(&src_addr, nh.arph->ar_sip, 4);
-        src_addr = ntohl(src_addr);
-        memcpy(&dst_addr, nh.arph->ar_tip, 4);
-        dst_addr = ntohl(dst_addr);
-        printk("%s.%d> ARP HW src=" MACFMT " dst=" MACFMT "\n",
-               msg, count, MAC6TUPLE(nh.arph->ar_sha), 
MAC6TUPLE(nh.arph->ar_tha));
-        printk("%s.%d> ARP IP src=" IPFMT " dst=" IPFMT "\n",
-               msg, count, HIPQUAD(src_addr), HIPQUAD(dst_addr));
-        break;
-    case ETH_P_IP: {
-        u16 src_port, dst_port;
-        if(ptr + sizeof(struct iphdr) > end){ printk("***IP:");  goto exit; }
-        src_addr = ntohl(nh.iph->saddr);
-        dst_addr = ntohl(nh.iph->daddr);
-        if(1){
-            printk("%s.%d> IP proto=%d src=" IPFMT " dst=" IPFMT "\n",
-                   msg, count, nh.iph->protocol,
-                   HIPQUAD(src_addr), HIPQUAD(dst_addr));
-            printk("%s.%d> IP tot_len=%u len=%d\n",
-                   msg, count, ntohs(nh.iph->tot_len), len - ETH_HLEN);
-        }
-        ptr += (nh.iph->ihl * 4);
-        if(ptr > end){ printk ("***IP: len"); goto exit; }
-        h.raw = ptr;
-        switch(nh.iph->protocol){
-        case IPPROTO_TCP:
-            ptr += sizeof(struct tcphdr);
-            if(ptr > end){ printk("***TCP:"); goto exit; }
-            src_port = ntohs(h.th->source);
-            dst_port = ntohs(h.th->dest);
-            printk("%s.%d> TCP src=" IPFMT ":%u dst=" IPFMT ":%u\n",
-                   msg, count,
-                   HIPQUAD(src_addr), src_port,
-                   HIPQUAD(dst_addr), dst_port);
-            break;
-        case IPPROTO_UDP:
-            ptr += sizeof(struct udphdr);
-            if(ptr > end){ printk("***UDP:"); goto exit; }
-            src_port = ntohs(h.uh->source);
-            dst_port = ntohs(h.uh->dest);
-            printk("%s.%d> UDP src=" IPFMT ":%u dst=" IPFMT ":%u\n",
-                   msg, count,
-                   HIPQUAD(src_addr), src_port,
-                   HIPQUAD(dst_addr), dst_port);
-            break;
-        default:
-            printk("%s.%d> IP %d src=" IPFMT " dst=" IPFMT "\n",
-                   msg, count,
-                   nh.iph->protocol, HIPQUAD(src_addr), HIPQUAD(dst_addr));
-            break;
-        }
-        break; }
-    case ETH_P_IPV6:
-        printk("%s.%d> IPv6\n", msg, count);
-        break;
-    case ETH_P_IPX:
-        printk("%s.%d> IPX\n", msg, count);
-        break;
-    default:
-        printk("%s.%d> protocol=%d\n", msg, count, protocol);
-        break;
-    }
-    return;
-  exit:
-    printk("%s.%d> %s: skb problem\n", msg, count, __FUNCTION__);
-    printk("%s.%d> %s: data=%p end=%p(%d) ptr=%p(%d) eth=%d ip=%d\n",
-           msg, count, __FUNCTION__,
-           data, end, end - data, ptr, ptr - data,
-           sizeof(struct ethhdr),
-           sizeof(struct iphdr));
-    return;
-}
-
-void print_skb(const char *msg, int count, struct sk_buff *skb){
-    print_skb_data(msg, count, skb, skb->mac.raw, skb->tail - skb->mac.raw);
-}
-
-void print_ethhdr(const char *msg, struct sk_buff *skb){
-    struct ethhdr *eth;
-
-    if(!skb || skboffset(skb, skb->mac.raw) < 0) return;
-    eth = eth_hdr(skb);
-    printk("%s> ETH proto=%d src=" MACFMT " dst=" MACFMT "\n",
-           msg,
-           ntohs(eth->h_proto),
-           MAC6TUPLE(eth->h_source),
-           MAC6TUPLE(eth->h_dest));
-}
-
-void print_iphdr(const char *msg, struct sk_buff *skb){
-    u32 src_addr, dst_addr;
-    
-    if(!skb || skboffset(skb, skb->nh.raw) < 0) return;
-    src_addr = ntohl(skb->nh.iph->saddr);
-    dst_addr = ntohl(skb->nh.iph->daddr);
-    printk("%s> IP proto=%d src=" IPFMT " dst=" IPFMT " tot_len=%u\n",
-           msg,
-           skb->nh.iph->protocol,
-           HIPQUAD(src_addr),
-           HIPQUAD(dst_addr),
-           ntohs(skb->nh.iph->tot_len));
-}
-
-void print_udphdr(const char *msg, struct sk_buff *skb){
-    if(!skb || skboffset(skb, skb->h.raw) < 0) return;
-    printk("%s> UDP src=%u dst=%u len=%u\n",
-           msg,
-           ntohs(skb->h.uh->source),
-           ntohs(skb->h.uh->dest),
-           ntohs(skb->h.uh->len));
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/skb_util.h
--- a/tools/vnet/vnet-module/skb_util.h Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _VNET_SKB_UTIL_H_
-#define _VNET_SKB_UTIL_H_
-
-#ifdef __KERNEL__
-#include <net/route.h>
-#include <linux/skbuff.h>
-
-#else
-
-#include "skbuff.h"
-
-#endif
-
-struct sk_buff;
-
-extern int skb_make_room(struct sk_buff **pskb, struct sk_buff *skb, int 
head_n, int tail_n);
-
-extern int skb_put_bits(const struct sk_buff *skb, int offset, void *src, int 
len);
-
-extern void skb_print_bits(const char *msg, struct sk_buff *skb, int offset, 
int n);
-
-extern void buf_print(char *buf, int n);
-
-extern void *skb_trim_tail(struct sk_buff *skb, int n);
-
-extern void print_skb_data(const char *msg, int count, struct sk_buff *skb, u8 
*data, int len);
-extern void print_skb(const char *msg, int count, struct sk_buff *skb);
-
-extern void print_ethhdr(const char *msg, struct sk_buff *skb);
-extern void print_iphdr(const char *msg, struct sk_buff *skb);
-extern void print_udphdr(const char *msg, struct sk_buff *skb);
-
-/* The mac.ethernet field went away in 2.6 in favour of eth_hdr().
- */
-#ifdef __KERNEL__
-#  if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#    define NEED_ETH_HDR
-#  endif
-#else
-#  define NEED_ETH_HDR
-#endif
-
-#ifdef NEED_ETH_HDR
-
-static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
-{
-       return (struct ethhdr *)skb->mac.raw;
-}
-
-#endif
-
-/*
- * It's a copy from {kernel}/include/linux/skbuff.h func '__skb_pull' and 
'skb_pull'
- * to aviodthe BUG_ON when pulling into the data (getting forwarded ip-frames)
- */
-static inline unsigned char *__skb_pull_vn(struct sk_buff *skb, unsigned int 
len)
-{
-        skb->len -= len;
-        //BUG_ON(skb->len < skb->data_len);
-        return skb->data += len;
-}
-static inline unsigned char *skb_pull_vn(struct sk_buff *skb, unsigned int len)
-{
-        return unlikely(len > skb->len) ? NULL : __skb_pull_vn(skb, len);
-}
-
-
-#ifdef __KERNEL__
-
-struct scatterlist;
-
-extern int skb_scatterlist(struct sk_buff *skb, struct scatterlist *sg,
-                           int *sg_n, int offset, int len);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-
-static inline int skb_route(struct sk_buff *skb, struct rtable **prt){
-    int err = 0;
-    struct flowi fl = {
-        .nl_u = {
-            .ip4_u = {
-                .daddr = skb->nh.iph->daddr,
-                .saddr = skb->nh.iph->saddr,
-                .tos   = skb->nh.iph->tos,
-            }
-        }
-    };
-    
-    if(skb->dev){
-        fl.oif = skb->dev->ifindex;
-    }
-    err = ip_route_output_key(prt, &fl);
-    return err;
-}
-
-#else
-
-static inline int skb_route(struct sk_buff *skb, struct rtable **prt){
-    int err = 0;
-    struct rt_key key = { };
-    key.dst = skb->nh.iph->daddr;
-    key.src = skb->nh.iph->saddr;
-    key.tos = skb->nh.iph->tos;
-    if(skb->dev){
-        key.oif = skb->dev->ifindex;
-    }
-    err = ip_route_output_key(prt, &key);
-    return err;
-}
-
-#endif
-
-#endif /* __KERNEL__ */
-
-/** Arp header struct with all the fields so we can access them. */
-struct arpheader
-{
-       unsigned short  ar_hrd;         /* format of hardware address   */
-       unsigned short  ar_pro;         /* format of protocol address   */
-       unsigned char   ar_hln;         /* length of hardware address   */
-       unsigned char   ar_pln;         /* length of protocol address   */
-       unsigned short  ar_op;          /* ARP opcode (command)         */
-
-#if 1
-        /*
-         *      Ethernet looks like this : This bit is variable sized 
however...
-         */
-       unsigned char           ar_sha[ETH_ALEN];       /* sender hardware 
address      */
-       unsigned char           ar_sip[4];              /* sender IP address    
        */
-       unsigned char           ar_tha[ETH_ALEN];       /* target hardware 
address      */
-       unsigned char           ar_tip[4];              /* target IP address    
        */
-#endif
-
-};
-
-#endif /* ! _VNET_SKB_UTIL_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/sxpr_util.c
--- a/tools/vnet/vnet-module/sxpr_util.c        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include "sys_net.h"
-#include "if_varp.h"
-#include "varp_util.h"
-#include "sxpr_util.h"
-
-int stringof(Sxpr exp, char **s){
-    int err = 0;
-    if(ATOMP(exp)){
-        *s = atom_name(exp);
-    } else if(STRINGP(exp)){
-        *s = string_string(exp);
-    } else {
-        err = -EINVAL;
-        *s = NULL;
-    }
-    return err;
-}
-
-int child_string(Sxpr exp, Sxpr key, char **s){
-    int err = 0;
-    Sxpr val = sxpr_child_value(exp, key, ONONE);
-    err = stringof(val, s);
-    return err;
-}
-
-int intof(Sxpr exp, int *v){
-    int err = 0;
-    char *s;
-    unsigned long l;
-    if(INTP(exp)){
-        *v = OBJ_INT(exp);
-    } else {
-        err = stringof(exp, &s);
-        if(err) goto exit;
-        err = convert_atoul(s, &l);
-        *v = (int)l;
-    }
- exit:
-    return err;
-}
-
-int child_int(Sxpr exp, Sxpr key, int *v){
-    int err = 0;
-    Sxpr val = sxpr_child_value(exp, key, ONONE);
-    err = intof(val, v);
-    return err;
-}
-
-int vnetof(Sxpr exp, VnetId *v){
-    int err = 0;
-    char *s;
-    err = stringof(exp, &s);
-    if(err) goto exit;
-    err = VnetId_aton(s, v);
-  exit:
-    return err;
-}
-
-int child_vnet(Sxpr exp, Sxpr key, VnetId *v){
-    int err = 0;
-    Sxpr val = sxpr_child_value(exp, key, ONONE);
-    err = vnetof(val, v);
-    return err;
-}
-
-int macof(Sxpr exp, unsigned char *v){
-    int err = 0;
-    char *s;
-    err = stringof(exp, &s);
-    if(err) goto exit;
-    err = mac_aton(s, v);
-  exit:
-    return err;
-}
-
-int child_mac(Sxpr exp, Sxpr key, unsigned char *v){
-    int err = 0;
-    Sxpr val = sxpr_child_value(exp, key, ONONE);
-    err = macof(val, v);
-    return err;
-}
-
-int addrof(Sxpr exp, uint32_t *v){
-    int err = 0;
-    char *s;
-    unsigned long w;
-    err = stringof(exp, &s);
-    if(err) goto exit;
-    err = get_inet_addr(s, &w);
-    if(err) goto exit;
-    *v = (uint32_t)w;
-  exit:
-    return err;
-}
-
-int child_addr(Sxpr exp, Sxpr key, uint32_t *v){
-    int err = 0;
-    Sxpr val = sxpr_child_value(exp, key, ONONE);
-    err = addrof(val, v);
-    return err;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/sxpr_util.h
--- a/tools/vnet/vnet-module/sxpr_util.h        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _SXPR_UTIL_H_
-#define _SXPR_UTIL__H_
-
-#include "sxpr.h"
-struct VnetId;
-
-int stringof(Sxpr exp, char **s);
-int child_string(Sxpr exp, Sxpr key, char **s);
-int intof(Sxpr exp, int *v);
-int child_int(Sxpr exp, Sxpr key, int *v);
-int vnetof(Sxpr exp, struct VnetId *v);
-int child_vnet(Sxpr exp, Sxpr key, struct VnetId *v);
-int macof(Sxpr exp, unsigned char *v);
-int child_mac(Sxpr exp, Sxpr key, unsigned char *v);
-int addrof(Sxpr exp, uint32_t *v);
-int child_addr(Sxpr exp, Sxpr key, uint32_t *v);
-
-#endif /* ! _SXPR_UTIL_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/timer_util.c
--- a/tools/vnet/vnet-module/timer_util.c       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/version.h>
-
-#include <linux/spinlock.h>
-#include <asm/semaphore.h>
-
-#else
-
-#include "sys_kernel.h"
-#include "spinlock.h"
-
-#endif
-
-#include "timer_util.h"
-
-#define MODULE_NAME "TIMER"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-#ifdef __KERNEL__
-
-void timer_init(struct timer_list *timer, void (*fn)(unsigned long), void 
*data){
-    init_timer(timer);
-    timer->data = (unsigned long)data;
-    timer->function = fn;
-}
-
-void timer_set(struct timer_list *timer, unsigned long ttl){
-    unsigned long now = jiffies;
-    timer->expires = now + ttl;
-    add_timer(timer);
-}
-
-#else
-
-void timer_init(struct Timer *timer, void (*fn)(unsigned long), void *data){
-    *timer = (struct Timer){};
-    timer->data = (unsigned long)data;
-    timer->fn = fn;
-}
-
-void timer_set(struct Timer *timer, unsigned long ttl){
-    double now = time_now();
-    timer->expiry = now + (double)ttl/(double)HZ;
-    Timer_cancel(timer);
-    Timer_add(timer);
-}
-
-#endif
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/timer_util.h
--- a/tools/vnet/vnet-module/timer_util.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef _VNET_TIMER_UTIL_H_
-#define _VNET_TIMER_UTIL_H_
-
-#ifdef __KERNEL__
-
-struct timer_list;
-#define timer_cancel del_timer
-
-#else /* __KERNEL__ */
-
-#include "timer.h"
-#define timer_list   Timer
-#define HZ           1000
-#define jiffies      (unsigned long)(time_now() * HZ)
-#define timer_cancel Timer_cancel
-
-#endif /* __KERNEL__ */
-
-void timer_init(struct timer_list *timer, void (*fn)(unsigned long), void 
*data);
-void timer_set(struct timer_list *timer, unsigned long ttl);
-
-#endif /*! _VNET_TIMER_UTIL_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/tunnel.c
--- a/tools/vnet/vnet-module/tunnel.c   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-
-#else
-
-#include "sys_kernel.h"
-#include "spinlock.h"
-#include "skbuff.h"
-
-#endif
-
-#include <tunnel.h>
-#include <vnet.h>
-#include <varp.h>
-#include "hash_table.h"
-
-#define MODULE_NAME "VNET"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** Table of tunnels, indexed by vnet and addr. */
-HashTable *tunnel_table = NULL;
-rwlock_t tunnel_table_lock = RW_LOCK_UNLOCKED;
-
-#define tunnel_read_lock(flags)    read_lock_irqsave(&tunnel_table_lock, 
(flags))
-#define tunnel_read_unlock(flags)  read_unlock_irqrestore(&tunnel_table_lock, 
(flags))
-#define tunnel_write_lock(flags)   write_lock_irqsave(&tunnel_table_lock, 
(flags))
-#define tunnel_write_unlock(flags) write_unlock_irqrestore(&tunnel_table_lock, 
(flags))
-
-void Tunnel_free(Tunnel *tunnel){
-    tunnel->type->close(tunnel);
-    Tunnel_decref(tunnel->base);
-    kfree(tunnel);
-}
-
-void Tunnel_print(Tunnel *tunnel){
-    if(tunnel){
-        iprintf("Tunnel<%p base=%p ref=%02d type=%s>\n",
-               tunnel,
-               tunnel->base,
-               atomic_read(&tunnel->refcount),
-               tunnel->type->name);
-        if(tunnel->base){
-            Tunnel_print(tunnel->base);
-        }
-    } else {
-        iprintf("Tunnel<%p base=%p ref=%02d type=%s>\n",
-               NULL, NULL, 0, "ip");
-    }
-}
-
-int Tunnel_create(TunnelType *type, VnetId *vnet, VarpAddr *addr,
-                  Tunnel *base, Tunnel **val){
-    int err = 0;
-    Tunnel *tunnel = NULL;
-    if(!type || !type->open || !type->send || !type->close){
-        err = -EINVAL;
-        goto exit;
-    }
-    tunnel = kmalloc(sizeof(Tunnel), GFP_ATOMIC);
-    if(!tunnel){
-        err = -ENOMEM;
-        goto exit;
-    }
-    atomic_set(&tunnel->refcount, 1);
-    tunnel->key.vnet = *vnet;
-    tunnel->key.addr = *addr;
-    tunnel->type = type;
-    tunnel->data = NULL;
-    tunnel->send_stats = (TunnelStats){};
-    Tunnel_incref(base);
-    tunnel->base = base;
-    err = type->open(tunnel);
-  exit:
-    if(err && tunnel){
-        Tunnel_decref(tunnel);
-        tunnel = NULL;
-    }
-    *val = tunnel;
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-void TunnelStats_update(TunnelStats *stats, int len, int err){
-    dprintf(">len=%d  err=%d\n", len, err);
-    if(err){
-        stats->dropped_bytes += len;
-        stats->dropped_packets++;
-    } else {
-        stats->bytes += len;
-        stats->packets++;
-    }
-    dprintf("<\n");
-}
-
-static inline Hashcode tunnel_table_key_hash_fn(void *k){
-    return hash_hvoid(0, k, sizeof(TunnelKey));
-}
-
-static int tunnel_table_key_equal_fn(void *k1, void *k2){
-    return memcmp(k1, k2, sizeof(TunnelKey)) == 0;
-}
-
-static void tunnel_table_entry_free_fn(HashTable *table, HTEntry *entry){
-    Tunnel *tunnel;
-    if(!entry) return;
-    tunnel = entry->value;
-    Tunnel_decref(tunnel);
-    HTEntry_free(entry);
-}
-
-int Tunnel_init(void){
-    int err = 0;
-    dprintf(">\n");
-    tunnel_table = HashTable_new(0);
-    if(!tunnel_table){
-        err = -ENOMEM;
-        goto exit;
-    }
-    tunnel_table->entry_free_fn = tunnel_table_entry_free_fn;
-    tunnel_table->key_size = sizeof(TunnelKey);
-    tunnel_table->key_hash_fn = tunnel_table_key_hash_fn;
-    tunnel_table->key_equal_fn = tunnel_table_key_equal_fn;
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-    
-/** Lookup tunnel state by vnet and destination.
- * The caller must drop the tunnel reference when done.
- *
- * @param vnet vnet
- * @param addr destination address
- * @return 0 on success
- */
-int Tunnel_lookup(VnetId *vnet, VarpAddr *addr, Tunnel **tunnel){
-    unsigned long flags;
-    TunnelKey key = { .vnet = *vnet, .addr = *addr };
-    dprintf(">\n");
-    tunnel_read_lock(flags);
-    *tunnel = HashTable_get(tunnel_table, &key);
-    tunnel_read_unlock(flags);
-    Tunnel_incref(*tunnel);
-    dprintf("< tunnel=%p\n", *tunnel);
-    return (*tunnel ? 0 : -ENOENT);
-}
-
-/** Get a tunnel to a given vnet and destination, creating
- * a tunnel if necessary.
- * The caller must drop the tunnel reference when done.
- *
- * @param vnet vnet
- * @param addr destination address
- * @param ctor tunnel constructor
- * @parma ptunnel return parameter for the tunnel
- * @return 0 on success
- */
-int Tunnel_open(VnetId *vnet, VarpAddr *addr,
-                int (*ctor)(VnetId *vnet, VarpAddr *addr, Tunnel **ptunnel),
-                Tunnel **ptunnel){
-    int err = 0;
-    Tunnel *tunnel = NULL;
-    unsigned long flags;
-    TunnelKey key = { .vnet = *vnet, .addr = *addr };
-
-    tunnel_write_lock(flags);
-    tunnel = HashTable_get(tunnel_table, &key);
-    if(!tunnel){
-        err = ctor(vnet, addr, &tunnel);
-        if(err) goto exit;
-        if(!HashTable_add(tunnel_table, tunnel, tunnel)){
-            err = -ENOMEM;
-            goto exit;
-        }
-    }
-  exit:
-    tunnel_write_unlock(flags);
-    if(err){
-        Tunnel_decref(tunnel);
-        *ptunnel = NULL;
-    } else {
-        Tunnel_incref(tunnel);
-        *ptunnel = tunnel;
-    }
-    return err;
-}
-
-int Tunnel_add(Tunnel *tunnel){
-    int err = 0;
-    unsigned long flags;
-    dprintf(">\n");
-    tunnel_write_lock(flags);
-    if(HashTable_add(tunnel_table, tunnel, tunnel)){
-        Tunnel_incref(tunnel);   
-    } else {
-        err = -ENOMEM;
-    }
-    tunnel_write_unlock(flags);
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-int Tunnel_del(Tunnel *tunnel){
-    int err;
-    unsigned long flags;
-    tunnel_write_lock(flags);
-    err = HashTable_remove(tunnel_table, tunnel);
-    tunnel_write_unlock(flags);
-    return err;
-}
-
-/** Do tunnel send processing on a packet.
- *
- * @param tunnel tunnel state
- * @param skb packet
- * @return 0 on success, error code otherwise
- */
-int Tunnel_send(Tunnel *tunnel, struct sk_buff *skb){
-    int err = 0;
-    dprintf("> tunnel=%p skb=%p\n", tunnel, skb);
-    if(tunnel){
-        int len = skb->len;
-        dprintf("> type=%s type->send...\n", tunnel->type->name);
-        // Must not refer to skb after sending - might have been freed.
-        err = tunnel->type->send(tunnel, skb);
-        TunnelStats_update(&tunnel->send_stats, len, err);
-    } else {
-        err = skb_xmit(skb);
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-int __init tunnel_module_init(void){
-    return Tunnel_init();
-}
-
-void __exit tunnel_module_exit(void){
-    unsigned long flags;
-    tunnel_write_lock(flags);
-    if(tunnel_table){
-        HashTable_free(tunnel_table);
-        tunnel_table = NULL;
-    }
-    tunnel_write_unlock(flags);
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/tunnel.h
--- a/tools/vnet/vnet-module/tunnel.h   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __VNET_TUNNEL_H__
-#define __VNET_TUNNEL_H__
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#include <asm/atomic.h>
-
-#else
-
-//#include <linux/types.h>
-#include "sys_kernel.h"
-#include "spinlock.h"
-
-#endif
-
-#include <if_varp.h>
-
-struct sk_buff;
-struct Tunnel;
-
-typedef struct TunnelType {
-    const char *name;
-    int (*open)(struct Tunnel *tunnel);
-    int (*send)(struct Tunnel *tunnel, struct sk_buff *skb);
-    void (*close)(struct Tunnel *tunnel);
-} TunnelType;
-
-typedef struct TunnelStats {
-    int bytes;
-    int packets;
-    int dropped_bytes;
-    int dropped_packets;
-} TunnelStats;
-
-typedef struct TunnelKey {
-    struct VnetId vnet;
-    struct VarpAddr addr;
-} TunnelKey;
-
-typedef struct Tunnel {
-    /** Key identifying the tunnel. Must be first. */
-    struct TunnelKey key;
-    /** Reference count. */
-    atomic_t refcount;
-    /** Tunnel type. */
-    struct TunnelType *type;
-    /** Statistics. */
-    struct TunnelStats send_stats;
-    /** Type-dependent state. */
-    void *data;
-    /** Underlying tunnel (may be null). */
-    struct Tunnel *base;
-} Tunnel;
-
-extern void Tunnel_free(struct Tunnel *tunnel);
-
-/** Decrement the reference count, freeing if zero.
- *
- * @param tunnel tunnel (may be null)
- */
-static inline void Tunnel_decref(struct Tunnel *tunnel){
-    if(!tunnel) return;
-    if(atomic_dec_and_test(&tunnel->refcount)){
-        Tunnel_free(tunnel);
-    }
-}
-
-/** Increment the reference count.
- *
- * @param tunnel tunnel (may be null)
- */
-static inline void Tunnel_incref(struct Tunnel *tunnel){
-    if(!tunnel) return;
-    atomic_inc(&tunnel->refcount);
-}
-
-extern int Tunnel_init(void);
-extern int Tunnel_lookup(struct VnetId *vnet, struct VarpAddr *addr, struct 
Tunnel **tunnel);
-extern int Tunnel_open(struct VnetId *vnet, struct VarpAddr *addr,
-                       int (*ctor)(struct VnetId *vnet,
-                                   struct VarpAddr *addr,
-                                   struct Tunnel **ptunnel),
-                       struct Tunnel **ptunnel);
-extern int Tunnel_add(struct Tunnel *tunnel);
-extern int Tunnel_del(struct Tunnel *tunnel);
-extern void Tunnel_print(struct Tunnel *tunnel);
-extern int Tunnel_send(struct Tunnel *tunnel, struct sk_buff *skb);
-
-extern int Tunnel_create(struct TunnelType *type, struct VnetId *vnet, struct 
VarpAddr *addr,
-                         struct Tunnel *base, struct Tunnel **tunnelp);
-
-extern int tunnel_module_init(void);
-extern void tunnel_module_exit(void);
-
-#endif /* !__VNET_TUNNEL_H__ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/varp.c
--- a/tools/vnet/vnet-module/varp.c     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1536 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/version.h>
-
-#include <linux/net.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/udp.h>
-
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/route.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <asm/semaphore.h>
-
-#else
-
-#include "sys_kernel.h"
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <linux/ip.h>
-#include <linux/udp.h>
-#include "spinlock.h"
-#include "skbuff.h"
-
-#endif
-
-#include <tunnel.h>
-#include <vnet.h>
-#include <vif.h>
-#include <if_varp.h>
-#include <varp.h>
-#include <varp_util.h>
-#include <vnet.h>
-#include <etherip.h>
-#include <vnet_forward.h>
-
-#include "allocate.h"
-#include "iostream.h"
-#include "hash_table.h"
-#include "sys_net.h"
-#include "sys_string.h"
-#include "skb_util.h"
-#include "timer_util.h"
-
-#define MODULE_NAME "VARP"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** @file VARP: Virtual ARP.
- *
- * Handles virtual ARP requests for vnet/vmac.
- */
-
-/*
-
-Varp uses UDP on port 1798.
-
-on domain up: ?
-  send varp.announce { id, vmac, vnet, coa } for each vif
-  that haven't announced before, or has changed.
-  install vif entries in local table.
-
-on varp.announce{ id, vmac, vnet, coa }:
-  update VARP entry for vmac x vnet if have one, reset ttl.
-
-on varp.request { id, vmac, vnet }:
-  if have a vif for the requested vmac/vnet,
-  reply with varp.announce{ id, vmac, vnet, coa }
-
-on timer:
-  traverse VARP table, flush old entries.
-
-on probe timer:
-  probe again if not out of tries.
-  if out of tries invalidate entry.
-
-*/
-
-/** Time-to-live of varp entries (in jiffies).*/
-#define VARP_ENTRY_TTL      (60*HZ)
-
-/** Maximum number of varp probes to make. */
-#define VARP_PROBE_MAX      5
-
-/** Interval between varp probes (in jiffies). */
-#define VARP_PROBE_INTERVAL (3*HZ)
-
-/** Maximum number of queued skbs for a varp entry. */
-#define VARP_QUEUE_MAX      16
-
-/** Number of buckets in the varp table (must be prime). */
-#define VARP_TABLE_BUCKETS  3001
-
-/** Varp entry states. */
-enum {
-    VARP_STATE_INCOMPLETE = 1,
-    VARP_STATE_REACHABLE = 2,
-    VARP_STATE_FAILED = 3,
-};
-
-/** Varp entry flags. */
-enum {
-    VARP_FLAG_PROBING = 1,
-    VARP_FLAG_PERMANENT = 2,
-};
-
-/** Key for varp entries. */
-typedef struct VarpKey {
-    /** Vnet id (network order). */
-    VnetId vnet;
-    /** Virtual MAC address. */
-    Vmac vmac;
-} VarpKey;
-
-/** An entry in the varp cache. */
-typedef struct VarpEntry {
-    /** Key for the entry. */
-    VarpKey key;
-    /** Care-of address for the key. */
-    VarpAddr addr;
-    /** Last-updated timestamp. */
-    unsigned long timestamp;
-    /** State. */
-    short state;
-    /** Flags. */
-    short flags;
-    /** Reference count. */
-    atomic_t refcount;
-    /** Lock. */
-    rwlock_t lock;
-    unsigned long lflags;
-
-    /** How many probes have been made. */
-    atomic_t probes;
-    /** Probe timer. */
-    struct timer_list timer;
-    void (*error)(struct VarpEntry *ventry, struct sk_buff *skb);
-    /** Outbound skb queue. */
-    struct sk_buff_head queue;
-    /** Maximum size of the queue. */
-    int queue_max;
-    atomic_t deleted;
-} VarpEntry;
-
-/** The varp cache. Varp entries indexed by VarpKey. */
-typedef struct VarpTable {
-
-    HashTable *table;
-
-    /** Sweep timer. */
-    struct timer_list timer;
-
-    rwlock_t lock;
-    struct semaphore mutex;
-
-    int entry_ttl;
-    int probe_max;
-    int probe_interval;
-    int queue_max;
-
-} VarpTable;
-
-/** The varp cache. */
-static VarpTable *varp_table = NULL;
-
-/** Module parameter for the multicast address. */
-static char *varp_mcaddr = NULL;
-
-/** Multicast address (network order). */
-u32 varp_mcast_addr = 0;
-
-/** UDP port (network order). */
-u16 varp_port = 0;
-
-char *varp_device = "xen-br0";
-
-#define VarpTable_read_lock(vtable, flags)    \
-  do{ read_lock_irqsave(&(vtable)->lock, (flags)); } while(0)
-
-#define VarpTable_read_unlock(vtable, flags)  \
-  do{ read_unlock_irqrestore(&(vtable)->lock, (flags)); } while(0)
-
-#define VarpTable_write_lock(vtable, flags)    \
-  do{ write_lock_irqsave(&(vtable)->lock, (flags)); } while(0)
-
-#define VarpTable_write_unlock(vtable, flags)  \
-  do{ write_unlock_irqrestore(&(vtable)->lock, (flags)); } while(0)
-
-#define VarpEntry_lock(ventry, flags)    \
-  do{ write_lock_irqsave(&(ventry)->lock, (flags)); (ventry)->lflags = 
(flags); } while(0)
-
-#define VarpEntry_unlock(ventry, flags)  \
-  do{ (flags) = (ventry)->lflags; write_unlock_irqrestore(&(ventry)->lock, 
(flags)); } while(0)
-
-void VarpTable_sweep(VarpTable *vtable);
-void VarpTable_flush(VarpTable *vtable);
-void VarpTable_print(VarpTable *vtable, IOStream *io);
-int VarpEntry_output(VarpEntry *ventry, struct sk_buff *skb);
-
-#include "./varp_util.c"
-
-/** Print the varp cache (if debug on).
- */
-void varp_dprint(void){
-#ifdef DEBUG
-    VarpTable_print(varp_table, iostdout);
-#endif
-} 
-
-/** Flush the varp cache.
- */
-void varp_flush(void){
-    VarpTable_flush(varp_table);
-}
-
-#ifdef __KERNEL__
-static int device_ucast_addr(const char *device, uint32_t *addr)
-{
-    int err;
-    struct net_device *dev = NULL;
-
-    err = vnet_get_device(device, &dev);
-    if(err) goto exit;
-    err = vnet_get_device_address(dev, addr);
-  exit:
-    if(err){
-        *addr = 0;
-    }
-    return err;
-}
-
-/** Get the unicast address of the varp device.
- */
-int varp_ucast_addr(uint32_t *addr)
-{
-    int err = -ENODEV;
-    const char *devices[] = { varp_device, "eth0", "eth1", "eth2", NULL };
-    const char **p;
-    for(p = devices; err && *p; p++){
-        err = device_ucast_addr(*p, addr);
-    }
-    return err;
-}
-
-/** Lookup a network device by name.
- *
- * @param name device name
- * @param dev return parameter for the device
- * @return 0 on success, error code otherwise
- */
-int vnet_get_device(const char *name, struct net_device **dev){
-    int err = 0;
-    *dev = dev_get_by_name(name);
-    if(!*dev){
-        err = -ENETDOWN;
-    }
-    return err;
-}
-
-/** Get the source address from a device.
- *
- * @param dev device
- * @param addr return parameter for address
- * @return 0 on success, error code otherwise
- */
-int vnet_get_device_address(struct net_device *dev, u32 *addr){
-    int err = 0;
-    struct in_device *in_dev;
-
-    in_dev = in_dev_get(dev);
-    if(!in_dev){
-        err = -ENODEV;
-        goto exit;
-    }
-    *addr = in_dev->ifa_list->ifa_address;
-    in_dev_put(in_dev);
-  exit:
-    return err;
-}
-
-#else
-
-int varp_ucast_addr(uint32_t *addr)
-{
-    return 0;
-}
-
-#endif
-
-/** Print varp info and the varp cache.
- */
-void varp_print(IOStream *io){
-    uint32_t addr = 0;
-    varp_ucast_addr(&addr);
-
-    IOStream_print(io, "(varp \n");
-    IOStream_print(io, " (device %s)\n", varp_device);
-    IOStream_print(io, " (mcast_addr " IPFMT ")\n", NIPQUAD(varp_mcast_addr));
-    IOStream_print(io, " (ucast_addr " IPFMT ")\n", NIPQUAD(addr));
-    IOStream_print(io, " (port %d)\n", ntohs(varp_port));
-    IOStream_print(io, " (encapsulation %s)\n",
-                   (etherip_in_udp ? "etherip_in_udp" : "etherip"));
-    IOStream_print(io, " (entry_ttl %lu)\n", varp_table->entry_ttl);
-    IOStream_print(io, ")\n");
-    VarpTable_print(varp_table, io);
-}
-
-#ifdef __KERNEL__
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-
-static inline int addr_route(u32 daddr, struct rtable **prt){
-    int err = 0;
-    struct flowi fl = {
-        .nl_u = {
-            .ip4_u = {
-                .daddr = daddr,
-            }
-        }
-    };
-    
-    err = ip_route_output_key(prt, &fl);
-    return err;
-}
-
-#else
-
-static inline int addr_route(u32 daddr, struct rtable **prt){
-    int err = 0;
-    struct rt_key key = { .dst = daddr };
-    err = ip_route_output_key(prt, &key);
-    return err;
-}
-
-#endif // LINUX_VERSION_CODE
-
-#ifndef LL_RESERVED_SPACE
-#define HH_DATA_MOD    16
-#define LL_RESERVED_SPACE(dev) \
-        ((dev->hard_header_len & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
-
-#endif // LL_RESERVED_SPACE
-
-#else // __KERNEL__
-
-#define ip_eth_mc_map(daddr, dmac) do{ }while(0)
-
-#endif // __KERNEL__
-
-/** Send a varp protocol message.
- *
- * @param opcode varp opcode (host order)
- * @param dev device (may be null)
- * @param skb skb being replied to (may be null)
- * @param vnet vnet id (in network order)
- * @param vmac vmac (in network order)
- * @return 0 on success, error code otherwise
- */
-int varp_send(u16 opcode, struct net_device *dev, struct sk_buff *skbin,
-              VnetId *vnet, Vmac *vmac){
-    int err = 0;
-    int link_n = 0;
-    int ip_n = sizeof(struct iphdr);
-    int udp_n = sizeof(struct udphdr);
-    int varp_n = sizeof(VarpHdr);
-    struct sk_buff *skbout = NULL;
-    VarpHdr *varph = NULL;
-    u8 smacbuf[6] = {}, dmacbuf[6] = {};
-    u8 *smac = smacbuf, *dmac = dmacbuf;
-    u32 saddr = 0, daddr = 0;
-    u16 sport = 0, dport = 0;
-#if defined(DEBUG)
-    char vnetbuf[VNET_ID_BUF];
-#endif
-
-    dprintf("> opcode=%d vnet= %s vmac=" MACFMT "\n",
-            opcode, VnetId_ntoa(vnet, vnetbuf), MAC6TUPLE(vmac->mac));
-
-    dport = varp_port;
-    if(skbin){
-        daddr = skbin->nh.iph->saddr;
-        dmac = eth_hdr(skbin)->h_source;
-        sport = skbin->h.uh->dest;
-    } else {
-        if(MULTICAST(varp_mcast_addr)){
-            daddr = varp_mcast_addr;
-            ip_eth_mc_map(daddr, dmac);
-        } else {
-            daddr = INADDR_BROADCAST;
-        }
-        sport = varp_port;
-    }
-
-#ifdef __KERNEL__
-    {
-        struct in_device *in_dev = NULL;
-        if(!dev){
-            struct rtable *rt = NULL;
-            err = addr_route(daddr, &rt);
-            if(err) goto exit;
-            dev = rt->u.dst.dev;
-        }
-        
-        in_dev = in_dev_get(dev);
-        if(!in_dev){
-            err = -ENODEV;
-            goto exit;
-        }
-        link_n = LL_RESERVED_SPACE(dev);
-        saddr = in_dev->ifa_list->ifa_address;
-        smac = dev->dev_addr;
-        if(daddr == INADDR_BROADCAST){
-            daddr = in_dev->ifa_list->ifa_broadcast;
-            dmac = dev->broadcast;
-        }
-        in_dev_put(in_dev);
-    }
-#else
-    {
-        extern uint32_t vnetd_addr(void); 
-        saddr = vnetd_addr();
-    }
-#endif // __KERNEL__
-
-    dprintf("> dev=%s\n", (dev ? dev->name : "<none>"));
-    dprintf("> smac=" MACFMT " dmac=" MACFMT "\n", MAC6TUPLE(smac), 
MAC6TUPLE(dmac));
-    dprintf("> saddr=" IPFMT " daddr=" IPFMT "\n", NIPQUAD(saddr), 
NIPQUAD(daddr));
-    dprintf("> sport=%u dport=%u\n", ntohs(sport), ntohs(dport));
-
-    skbout = alloc_skb(link_n + ip_n + udp_n + varp_n, GFP_ATOMIC);
-    if (!skbout){
-        err = -ENOMEM;
-        goto exit;
-    }
-    skbout->dev = dev;
-    skb_reserve(skbout, link_n);
-    skbout->protocol = htons(ETH_P_IP);
-
-#ifdef __KERNEL__
-    // Device header. Pushes device header on front of skb.
-    if (dev->hard_header){
-        err = dev->hard_header(skbout, dev, ETH_P_IP, dmac, smac, skbout->len);
-        if(err < 0) goto exit;
-        skbout->mac.raw = skbout->data;
-    }
-#else
-    smac = smac; // Defeat unused variable warning.
-#endif // __KERNEL__
-
-    // IP header.
-    skbout->nh.raw = skb_put(skbout, ip_n);
-    skbout->nh.iph->version  = 4;
-    skbout->nh.iph->ihl      = ip_n / 4;
-    skbout->nh.iph->tos      = 0;
-    skbout->nh.iph->tot_len  = htons(ip_n + udp_n + varp_n);
-    skbout->nh.iph->id       = 0;
-    skbout->nh.iph->frag_off = 0;
-    skbout->nh.iph->ttl      = 64;
-    skbout->nh.iph->protocol = IPPROTO_UDP;
-    skbout->nh.iph->saddr    = saddr;
-    skbout->nh.iph->daddr    = daddr;  
-    skbout->nh.iph->check    = 0;
-
-    // UDP header.
-    skbout->h.raw = skb_put(skbout, udp_n);
-    skbout->h.uh->source     = sport;
-    skbout->h.uh->dest       = dport;
-    skbout->h.uh->len        = htons(udp_n + varp_n);
-    skbout->h.uh->check      = 0;
-
-    // Varp header.
-    varph = (void*)skb_put(skbout, varp_n);
-    *varph = (VarpHdr){};
-    varph->hdr.id            = htons(VARP_ID);
-    varph->hdr.opcode        = htons(opcode);
-    varph->vnet              = *vnet;
-    varph->vmac              = *vmac;
-    varph->addr.family       = AF_INET;
-    varph->addr.u.ip4.s_addr = saddr;
-
-    err = skb_xmit(skbout);
-
-  exit:
-    if(err && skbout) kfree_skb(skbout);
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-
-/** Send a varp request for the vnet and destination mac of a packet.
- * Assumes the ventry is locked.
- *
- * @param skb packet
- * @param vnet vnet (in network order)
- * @return 0 on success, error code otherwise
- */
-int varp_solicit(VnetId *vnet, Vmac *vmac){
-    return varp_send(VARP_OP_REQUEST, NULL, NULL, vnet, vmac);
-}
-
-/* Test some flags.
- *
- * @param ventry varp entry
- * @param flags to test
- * @return nonzero if flags set
- */
-int VarpEntry_get_flags(VarpEntry *ventry, int flags){
-    return ventry->flags & flags;
-}
-
-/** Set some flags.
- *
- * @param ventry varp entry
- * @param flags to set
- * @param set set flags on if nonzero, off if zero
- * @return new flags value
- */
-int VarpEntry_set_flags(VarpEntry *ventry, int flags, int set){
-    if(set){
-        ventry->flags |= flags;
-    } else {
-        ventry->flags &= ~flags;
-    }
-    return ventry->flags;
-}
-
-/** Print a varp entry.
- *
- * @param ventry varp entry
- */
-void VarpEntry_print(VarpEntry *ventry, IOStream *io){
-    IOStream_print(io, "(ventry \n");
-    if(ventry){
-        unsigned long now = jiffies;
-        char *state, *flags;
-        char vnetbuf[VNET_ID_BUF];
-        char addrbuf[VARP_ADDR_BUF];
-
-        switch(ventry->state){
-        case VARP_STATE_INCOMPLETE: state = "incomplete"; break;
-        case VARP_STATE_REACHABLE:  state = "reachable"; break;
-        case VARP_STATE_FAILED:     state = "failed"; break;
-        default:                    state = "unknown"; break;
-        }
-        flags = (VarpEntry_get_flags(ventry, VARP_FLAG_PROBING) ? "P" : "-");
-
-        IOStream_print(io, " (ref %d)\n", atomic_read(&ventry->refcount));
-        IOStream_print(io, " (state %s)\n", state);
-        IOStream_print(io, " (flags %s)\n", flags);
-        IOStream_print(io, " (addr %s)\n", VarpAddr_ntoa(&ventry->addr, 
addrbuf));
-        IOStream_print(io, " (queue %d)\n", skb_queue_len(&ventry->queue));
-        IOStream_print(io, " (age %lu)\n", now - ventry->timestamp);
-        IOStream_print(io, " (vmac " MACFMT ")\n", 
MAC6TUPLE(ventry->key.vmac.mac));
-        IOStream_print(io, " (vnet %s)\n", VnetId_ntoa(&ventry->key.vnet, 
vnetbuf));
-    }
-    IOStream_print(io, ")\n");
-}
-
-/** Free a varp entry.
- *
- * @param ventry varp entry
- */
-static void VarpEntry_free(VarpEntry *ventry){
-    if(!ventry) return;
-    deallocate(ventry);
-}
-
-/** Increment reference count.
- *
- * @param ventry varp entry (may be null)
- */
-void VarpEntry_incref(VarpEntry *ventry){
-    if(!ventry) return;
-    atomic_inc(&ventry->refcount);
-}
-
-/** Decrement reference count, freeing if zero.
- *
- * @param ventry varp entry (may be null)
- */
-void VarpEntry_decref(VarpEntry *ventry){
-    if(!ventry) return;
-    if(atomic_dec_and_test(&ventry->refcount)){
-        VarpEntry_free(ventry);
-    }
-}
-
-/** Call the error handler.
- *
- * @param ventry varp entry
- */
-void VarpEntry_error(VarpEntry *ventry){
-    struct sk_buff *skb;
-    skb = skb_peek(&ventry->queue);
-    if(!skb) return;
-    if(ventry->error) ventry->error(ventry, skb);
-    skb_queue_purge(&ventry->queue);
-}
-
-/** Schedule the varp entry timer.
- * Must increment the reference count before doing
- * this the first time, so the ventry won't be freed
- * before the timer goes off.
- *
- * @param ventry varp entry
- */
-void VarpEntry_schedule(VarpEntry *ventry){
-    timer_set(&ventry->timer, VARP_PROBE_INTERVAL);
-}
-
-/** Function called when a varp entry timer goes off.
- * If the entry is still incomplete, carries on probing.
- * Otherwise stops probing.
- *
- * @param arg ventry
- */
-static void varp_timer_fn(unsigned long arg){
-    unsigned long flags;
-    VarpEntry *ventry = (VarpEntry *)arg;
-    struct sk_buff *skb = NULL;
-    int probing = 0;
-
-    dprintf(">\n");
-    VarpEntry_lock(ventry, flags);
-    if(!atomic_read(&ventry->deleted)){
-        switch(ventry->state){
-        case VARP_STATE_REACHABLE:
-        case VARP_STATE_FAILED:
-            break;
-        case VARP_STATE_INCOMPLETE:
-            // Probe if haven't run out of tries, otherwise fail.
-            if(atomic_read(&ventry->probes) < VARP_PROBE_MAX){
-                unsigned long qflags;
-                VnetId vnet;
-                Vmac vmac;
-
-                probing = 1;
-                spin_lock_irqsave(&ventry->queue.lock, qflags);
-                skb = skb_peek(&ventry->queue);
-                if(skb){
-                    vmac = *(Vmac*)eth_hdr(skb)->h_dest;
-                }
-                spin_unlock_irqrestore(&ventry->queue.lock, qflags);
-                if(skb){
-                    dprintf("> skbs in queue - solicit\n");
-                    vnet = ventry->key.vnet;
-                    atomic_inc(&ventry->probes);
-                    VarpEntry_unlock(ventry, flags);
-                    varp_solicit(&vnet, &vmac);
-                    VarpEntry_lock(ventry, flags);        
-                } else {
-                    dprintf("> empty queue.\n");
-                }
-                VarpEntry_schedule(ventry);
-            } else {
-                VarpEntry_error(ventry);
-                ventry->state = VARP_STATE_FAILED;
-            }
-            break;
-        }
-    }
-    VarpEntry_set_flags(ventry, VARP_FLAG_PROBING, probing);
-    VarpEntry_unlock(ventry, flags);
-    if(!probing) VarpEntry_decref(ventry);
-    dprintf("<\n");
-}
-
-/** Default error function for varp entries.
- *
- * @param ventry varp entry
- * @param skb packet dropped because of error
- */
-static void varp_error_fn(VarpEntry *ventry, struct sk_buff *skb){
-}
-
-/** Create a varp entry. Initializes the internal state.
- *
- * @param vnet vnet id
- * @param vmac virtual MAC address (copied)
- * @return ventry or null
- */
-VarpEntry * VarpEntry_new(VnetId *vnet, Vmac *vmac){
-    VarpEntry *ventry = ALLOCATE(VarpEntry);
-    if(ventry){
-        unsigned long now = jiffies;
-
-        atomic_set(&ventry->refcount, 1);
-        atomic_set(&ventry->probes, 0);
-        atomic_set(&ventry->deleted, 0);
-        ventry->lock = RW_LOCK_UNLOCKED;
-        ventry->state = VARP_STATE_INCOMPLETE;
-        ventry->queue_max = VARP_QUEUE_MAX;
-        skb_queue_head_init(&ventry->queue);
-        timer_init(&ventry->timer, varp_timer_fn, ventry);
-        ventry->timestamp = now;
-        ventry->error = varp_error_fn;
-
-        ventry->key.vnet = *vnet;
-        ventry->key.vmac = *vmac;
-    }
-    return ventry;
-}
-
-/** Hash function for keys in the varp cache.
- * Hashes the vnet id and mac.
- *
- * @param k key (VarpKey)
- * @return hashcode
- */
-static Hashcode varp_key_hash_fn(void *k){
-    return hash_hvoid(0, k, sizeof(VarpKey));
-}
-
-/** Test equality for keys in the varp cache.
- * Compares vnet and mac.
- *
- * @param k1 key to compare (VarpKey)
- * @param k2 key to compare (VarpKey)
- * @return 1 if equal, 0 otherwise
- */
-static int varp_key_equal_fn(void *k1, void *k2){
-    return memcmp(k1, k2, sizeof(VarpKey)) == 0;
-}
-
-/** Free an entry in the varp cache.
- *
- * @param table containing table
- * @param entry entry to free
- */
-static void varp_entry_free_fn(HashTable *table, HTEntry *entry){
-    VarpEntry *ventry;
-    if(!entry) return;
-    ventry = entry->value;
-    if(ventry) VarpEntry_decref(ventry);
-    HTEntry_free(entry);
-}
-
-/** Free the whole varp cache.
- * Dangerous.
- *
- * @param vtable varp cache
- */
-void VarpTable_free(VarpTable *vtable){
-    unsigned long vtflags;
-    if(!vtable) return;
-    VarpTable_write_lock(vtable, vtflags);
-    timer_cancel(&vtable->timer);
-    vtable->timer.data = 0;
-    if(vtable->table){
-        HashTable *table = vtable->table;
-        HashTable_for_decl(entry);
-
-        vtable->table = NULL;
-        HashTable_for_each(entry, table){
-            VarpEntry *ventry = entry->value;
-            unsigned long flags;
-            VarpEntry_lock(ventry, flags);
-            atomic_set(&ventry->deleted, 1);
-            if(VarpEntry_get_flags(ventry, VARP_FLAG_PROBING)){
-                timer_cancel(&ventry->timer);
-                ventry->timer.data = 0;
-                VarpEntry_decref(ventry);
-            }
-            VarpEntry_unlock(ventry, flags);
-        }
-        HashTable_free(table); 
-    }
-    VarpTable_write_unlock(vtable, vtflags);
-    deallocate(vtable);
-}
-
-/** Schedule the varp table timer.
- *
- * @param vtable varp table
- */
-void VarpTable_schedule(VarpTable *vtable){
-    timer_set(&vtable->timer, vtable->entry_ttl);
-}
-
-/** Function called when the varp table timer goes off.
- * Sweeps old varp cache entries and reschedules itself.
- *
- * @param arg varp table
- */
-static void varp_table_timer_fn(unsigned long arg){
-    VarpTable *vtable = (VarpTable *)arg;
-    if(vtable){
-        VarpTable_sweep(vtable);
-        VarpTable_schedule(vtable);
-    }
-}
-
-/** Print a varp table.
- *
- * @param vtable table
- */
-void VarpTable_print(VarpTable *vtable, IOStream *io){
-    HashTable_for_decl(entry);
-    VarpEntry *ventry;
-    unsigned long vtflags, flags;
-
-    VarpTable_read_lock(vtable, vtflags);
-    HashTable_for_each(entry, vtable->table){
-        ventry = entry->value;
-        VarpEntry_lock(ventry, flags);
-        VarpEntry_print(ventry, io);
-        VarpEntry_unlock(ventry, flags);
-    }
-    VarpTable_read_unlock(vtable, vtflags);
-}
-
-/** Create a varp table.
- *
- * @return new table or null
- */
-VarpTable * VarpTable_new(void){
-    int err = -ENOMEM;
-    VarpTable *vtable = NULL;
-
-    vtable = ALLOCATE(VarpTable);
-    if(!vtable) goto exit;
-    vtable->table = HashTable_new(VARP_TABLE_BUCKETS);
-    if(!vtable->table) goto exit;
-    vtable->table->key_size = sizeof(VarpKey);
-    vtable->table->key_equal_fn = varp_key_equal_fn;
-    vtable->table->key_hash_fn = varp_key_hash_fn;
-    vtable->table->entry_free_fn = varp_entry_free_fn;
-
-    vtable->entry_ttl = VARP_ENTRY_TTL;
-    vtable->probe_max = VARP_PROBE_MAX;
-    vtable->probe_interval = VARP_PROBE_INTERVAL;
-    vtable->queue_max = VARP_QUEUE_MAX;
-
-    init_MUTEX(&vtable->mutex);
-    vtable->lock = RW_LOCK_UNLOCKED;
-    timer_init(&vtable->timer, varp_table_timer_fn, vtable);
-    err = 0;
-  exit:
-    if(err){
-        VarpTable_free(vtable);
-        vtable = NULL;
-    }
-    return vtable;
-}
-
-/** Add a new entry to the varp table.
- *
- * @param vtable table
- * @param vnet vnet id
- * @param vmac virtual MAC address (copied)
- * @return new entry or null
- */
-VarpEntry * VarpTable_add(VarpTable *vtable, VnetId *vnet, Vmac *vmac){
-    int err = 0;
-    VarpKey key = { .vnet = *vnet, .vmac = *vmac};
-    VarpEntry *ventry = NULL;
-    HTEntry *entry = NULL;
-    unsigned long vtflags;
-
-    VarpTable_write_lock(vtable, vtflags);
-    ventry = HashTable_get(vtable->table, &key);
-    if(ventry){
-        VarpEntry_incref(ventry);
-        goto exit;
-    }
-    err = -ENOMEM;
-    ventry = VarpEntry_new(vnet, vmac);
-    if(!ventry) goto exit;
-    entry = HashTable_add(vtable->table, ventry, ventry);
-    if(!entry){
-        VarpEntry_decref(ventry);
-        ventry = NULL;
-        goto exit;
-    }
-    err = 0;
-    VarpEntry_incref(ventry);
-  exit:
-    VarpTable_write_unlock(vtable, vtflags);
-    return ventry;
-}
-
-/** Remove an entry from the varp table.
- *
- * @param vtable table
- * @param ventry entry to remove
- * @return removed count
- */
-int VarpTable_remove(VarpTable *vtable, VarpEntry *ventry){
-    //TODO: Could send a varp announce with null addr for the entry
-    // vnet and vmac to notify others, so they will resolve the addr
-    // instead of sending traffic to us.
-    atomic_set(&ventry->deleted, 1);
-    skb_queue_purge(&ventry->queue);
-    return HashTable_remove(vtable->table, ventry);
-}
-
-/** Remove all entries using a vnet.
- * Caller must hold the table lock.
- *
- * @param vtable table
- * @param vnet vnet
- * @return removed count
- */
-int VarpTable_remove_vnet(VarpTable *vtable, VnetId *vnet){
-    int count = 0;
-    HashTable_for_decl(entry);
-
-    HashTable_for_each(entry, vtable->table){
-        VarpEntry *ventry = entry->value;
-        if(VnetId_eq(&ventry->key.vnet, vnet)){
-            count += VarpTable_remove(vtable, ventry);
-        }
-    }
-    return count;
-}
-
-/** Remove all entries using a vnet from the varp table.
- *
- * @param vnet vnet
- * @return removed count
- */
-int varp_remove_vnet(VnetId *vnet){
-    int count = 0;
-    unsigned long vtflags;
-
-    VarpTable_write_lock(varp_table, vtflags);
-    count = VarpTable_remove_vnet(varp_table, vnet);
-    VarpTable_write_unlock(varp_table, vtflags);
-    return count;
-}
-
-/** Lookup an entry in the varp table.
- *
- * @param vtable table
- * @param vnet vnet id
- * @param vmac virtual MAC address
- * @param create create a new entry if needed if true
- * @return entry found or null
- */
-VarpEntry * VarpTable_lookup(VarpTable *vtable, VnetId *vnet, Vmac *vmac, int 
create){
-    VarpKey key = { .vnet = *vnet, .vmac = *vmac };
-    VarpEntry *ventry = NULL;
-    unsigned long vtflags;
-
-    VarpTable_read_lock(vtable, vtflags);
-    ventry = HashTable_get(vtable->table, &key);
-    if(ventry) VarpEntry_incref(ventry);
-    VarpTable_read_unlock(vtable, vtflags);
-
-    if(!ventry && create){
-        ventry = VarpTable_add(vtable, vnet, vmac);
-    }
-    return ventry;
-}
-
-/** Handle output for a reachable ventry.
- * Send the skb using the tunnel to the care-of address.
- * Assumes the ventry lock is held.
- *
- * @param ventry varp entry
- * @param skb skb to send
- * @return 0 on success, error code otherwise
- */
-int VarpEntry_send(VarpEntry *ventry, struct sk_buff *skb){
-    int err = 0;
-    unsigned long flags = 0;
-    VarpAddr addr;
-    VnetId vnet;
-
-    dprintf("> skb=%p\n", skb);
-    vnet = ventry->key.vnet;
-    addr = ventry->addr;
-    VarpEntry_unlock(ventry, flags);
-    err = vnet_tunnel_send(&vnet, &addr, skb);
-    VarpEntry_lock(ventry, flags);
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Handle output for a non-reachable ventry. Send messages to complete it.
- * If the entry is still incomplete, queue the skb, otherwise
- * send it. If the queue is full, dequeue and free an old skb to
- * make room for the new one.
- * Assumes the ventry lock is held.
- *
- * @param ventry varp entry
- * @param skb skb to send
- * @return 0 on success, error code otherwise
- */
-int VarpEntry_resolve(VarpEntry *ventry, struct sk_buff *skb){
-    int err = 0;
-    unsigned long flags = 0;
-    VnetId vnet;
-    Vmac vmac;
-
-    dprintf("> skb=%p\n", skb);
-    ventry->state = VARP_STATE_INCOMPLETE;
-    atomic_set(&ventry->probes, 1);
-    if(!VarpEntry_get_flags(ventry, VARP_FLAG_PROBING)){
-        VarpEntry_set_flags(ventry, VARP_FLAG_PROBING, 1);
-        VarpEntry_incref(ventry);
-        VarpEntry_schedule(ventry);
-    }
-    vnet = ventry->key.vnet;
-    vmac = *(Vmac*)eth_hdr(skb)->h_dest;
-    VarpEntry_unlock(ventry, flags);
-    varp_solicit(&vnet, &vmac);
-    VarpEntry_lock(ventry, flags);
-
-    if(ventry->state == VARP_STATE_INCOMPLETE){
-        while(skb_queue_len(&ventry->queue) >= ventry->queue_max){
-            struct sk_buff *oldskb;
-            oldskb = skb_dequeue(&ventry->queue);
-            //oldskb = ventry->queue.next;
-            //__skb_unlink(oldskb, &ventry->queue);
-            if(!oldskb) break;
-            dprintf("> dropping skb=%p\n", oldskb);
-            kfree_skb(oldskb);
-        }
-        skb_queue_tail(&ventry->queue, skb);
-    } else {
-        err = VarpEntry_send(ventry, skb);
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Process the output queue for a ventry.  Sends the queued skbs if
- * the ventry is reachable, otherwise drops them.
- *
- * @param ventry varp entry
- */
-void VarpEntry_process_queue(VarpEntry *ventry){
-    struct sk_buff *skb;
-    for( ; ; ){
-        if(ventry->state != VARP_STATE_REACHABLE) break;
-        skb = skb_dequeue(&ventry->queue);
-        if(!skb) break;
-        VarpEntry_send(ventry, skb);
-    }
-    skb_queue_purge(&ventry->queue);
-}
-
-/** Multicast an skb on a vnet.
- *
- * @param vnet vnet id
- * @param skb skb to send
- * @return 0 on success, error code otherwise
- */
-static int varp_multicast(VnetId *vnet, struct sk_buff *skb){
-    VarpAddr addr = { .family = AF_INET };
-    addr.u.ip4.s_addr = varp_mcast_addr;
-    return vnet_tunnel_send(vnet, &addr, skb);
-}
-
-/** Handle output for a ventry. Resolves the ventry
- * if necessary.
- *
- * @param ventry varp entry
- * @param skb skb to send
- * @return 0 on success, error code otherwise
- */
-int VarpEntry_output(VarpEntry *ventry, struct sk_buff *skb){
-    int err = 0;
-    unsigned long flags;
-
-    VarpEntry_lock(ventry, flags);
-    switch(ventry->state){
-    case VARP_STATE_REACHABLE:
-        if(skb_queue_len(&ventry->queue) > 0){
-            VarpEntry_process_queue(ventry);
-        }
-        err = VarpEntry_send(ventry, skb);
-        break;
-    default: 
-        if(0){
-            err = VarpEntry_resolve(ventry, skb);
-        } else {     
-            // Multicast the skb if the entry is not reachable.
-            VnetId vnet = ventry->key.vnet;
-            VarpEntry_unlock(ventry, flags);
-            err = varp_multicast(&vnet, skb);
-            VarpEntry_lock(ventry, flags);
-        }
-        break;
-    }
-    VarpEntry_unlock(ventry, flags);
-    return err;
-}
-
-/** Update a ventry. Sets the address and state to those given
- * and sets the timestamp to 'now'.
- *
- * @param ventry varp entry
- * @param addr care-of address
- * @param state state
- * @return 0 on success, error code otherwise
- */
-int VarpEntry_update(VarpEntry *ventry, VarpAddr *addr, int state, int vflags){
-    int err = 0;
-    unsigned long now = jiffies;
-    unsigned long flags;
-
-    VarpEntry_lock(ventry, flags);
-    //if(atomic_read(&ventry->deleted)) goto exit;
-    if(VarpEntry_get_flags(ventry, VARP_FLAG_PERMANENT)) goto exit;
-    ventry->addr = *addr;
-    ventry->timestamp = now;
-    ventry->state = state;
-    // Can't process the queue while atomic as it calls schedule(),
-    // and that's bad.
-    //if(0 && (vflags & VARP_UPDATE_QUEUE) && !in_atomic()){
-    //    VarpEntry_process_queue(ventry);
-    //}
-  exit:
-    VarpEntry_unlock(ventry, flags);
-    dprintf("< err=%d\n", err);
-    return err;
-}
-    
-/** Update the entry for a vnet.
- *
- * @param vtable varp table
- * @param vnet vnet id
- * @param vmac mac address
- * @param addr care-of-address
- * @param state state
- * @param flags update flags
- * @return 0 on success, error code otherwise
- */
-int VarpTable_update(VarpTable *vtable, VnetId *vnet, Vmac *vmac, VarpAddr 
*addr,
-                     int state, int flags){
-    int err = 0;
-    VarpEntry *ventry;
-#ifdef DEBUG
-    char vnetbuf[VNET_ID_BUF];
-    char addrbuf[VARP_ADDR_BUF];
-    
-    dprintf("> vnet=%s mac=" MACFMT " addr=%s state=%d flags=%x\n",
-            VnetId_ntoa(vnet, vnetbuf),
-            MAC6TUPLE(vmac->mac),
-            VarpAddr_ntoa(addr, addrbuf),
-            state,
-            flags);
-#endif
-    ventry = VarpTable_lookup(vtable, vnet, vmac, (flags & 
VARP_UPDATE_CREATE));
-    if(!ventry){
-        err = -ENOENT;
-        goto exit;
-    }
-    err = VarpEntry_update(ventry, addr, state, flags);
-    VarpEntry_decref(ventry);
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Update the entry for a vnet: make it reachable and create an entry
- * if needed.
- *
- * @param vnet vnet id
- * @param vmac mac address
- * @param addr care-of-address
- * @return 0 on success, error code otherwise
- */
-int varp_update(VnetId *vnet, unsigned char *vmac, VarpAddr *addr){
-    int err = 0;
-    if(!varp_table){
-        err = -ENOSYS;
-    } else {
-        err = VarpTable_update(varp_table, vnet, (Vmac*)vmac, addr,
-                               VARP_STATE_REACHABLE, VARP_UPDATE_CREATE);
-    }
-    return err;
-}
-
-static inline int VarpEntry_sweepable(VarpEntry *ventry){
-    return !VarpEntry_get_flags(ventry, (VARP_FLAG_PERMANENT | 
VARP_FLAG_PROBING));
-}
-
-static inline int VarpTable_old(VarpTable *vtable, VarpEntry *ventry, unsigned 
long now){
-    return now - ventry->timestamp > vtable->entry_ttl;
-}
-
-/** Sweep old varp entries.
- * Doesn't affect entries that are probing or permanent.
- *
- * @param vtable table
- */
-void VarpTable_sweep(VarpTable *vtable){
-    HashTable_for_decl(entry);
-    VarpEntry *ventry;
-    unsigned long now = jiffies;
-    unsigned long vtflags, flags;
-    int sweep, swept = 0;
-
-    if(!vtable) return;
-    VarpTable_write_lock(vtable, vtflags);
-    HashTable_for_each(entry, vtable->table){
-        ventry = entry->value;
-        VarpEntry_lock(ventry, flags);
-        sweep = VarpEntry_sweepable(ventry) && VarpTable_old(vtable, ventry, 
now);
-        if(sweep){
-            swept++;
-            iprintf("> Sweeping:\n");
-            VarpEntry_print(ventry, iostdout);
-            //VarpEntry_process_queue(ventry);
-            ventry->state = VARP_STATE_INCOMPLETE;
-        }
-        VarpEntry_unlock(ventry, flags);
-        if(sweep){
-            VarpTable_remove(vtable, ventry);
-        }
-    }
-    VarpTable_write_unlock(vtable, vtflags);
-    if(swept){
-        iprintf(">\n");
-        varp_print(iostdout);
-    }
-}
-
-/** Flush the varp table.
- *
- * @param vtable table
- */
-void VarpTable_flush(VarpTable *vtable){
-    HashTable_for_decl(entry);
-    VarpEntry *ventry;
-    unsigned long vtflags, flags;
-    int flush;
-
-    VarpTable_write_lock(vtable, vtflags);
-    HashTable_for_each(entry, vtable->table){
-        ventry = entry->value;
-        VarpEntry_lock(ventry, flags);
-        flush = (!VarpEntry_get_flags(ventry, VARP_FLAG_PERMANENT) &&
-                 !VarpEntry_get_flags(ventry, VARP_FLAG_PROBING));             
   
-        if(flush){
-            iprintf("> Flushing:\n");
-            VarpEntry_print(ventry, iostdout);
-        }
-        VarpEntry_unlock(ventry, flags);
-        if(flush){
-            VarpTable_remove(vtable, ventry);
-        }
-    }
-    VarpTable_write_unlock(vtable, vtflags);
-}
-
-/** Handle a varp request. Look for a vif with the requested 
- * vnet and vmac. If find one, reply with the vnet, vmac and our
- * address. Otherwise do nothing.
- *
- * @param skb incoming message
- * @param varph varp message
- * @return 0 if ok, -ENOENT if no matching vif, or error code
- */
-int varp_handle_request(struct sk_buff *skb, VarpHdr *varph){
-    int err = -ENOENT;
-    VnetId *vnet;
-    Vmac *vmac;
-    Vif *vif = NULL;
-
-    dprintf(">\n");
-    vnet = &varph->vnet;
-    vmac = &varph->vmac;
-    if(vif_lookup(vnet, vmac, &vif)) goto exit;
-    varp_send(VARP_OP_ANNOUNCE, skb->dev, skb, vnet, vmac);
-    vif_decref(vif);
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Announce the vnet and vmac of a vif (gratuitous varp).
- *
- * @param dev device to send on (may be null)
- * @param vif vif
- * @return 0 on success, error code otherwise
- */
-int varp_announce_vif(struct net_device *dev, Vif *vif){
-    int err = 0;
-    dprintf(">\n");
-    if(!varp_table){
-        err = -ENOSYS;
-        goto exit;
-    }
-    err = varp_send(VARP_OP_ANNOUNCE, dev, NULL, &vif->vnet, &vif->vmac);
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Handle a varp announce message.
- * Update the matching ventry if we have one.
- *
- * @param skb incoming message
- * @param varp message
- * @return 0 if OK, -ENOENT if no matching entry
- */
-int varp_handle_announce(struct sk_buff *skb, VarpHdr *varph){
-    int err = 0;
-
-    dprintf(">\n");
-    err = VarpTable_update(varp_table,
-                           &varph->vnet, &varph->vmac, &varph->addr,
-                           VARP_STATE_REACHABLE, 
-                           (VARP_UPDATE_CREATE | VARP_UPDATE_QUEUE));
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Handle an incoming varp message.
- *
- * @param skb incoming message
- * @return 0 if OK, error code otherwise
- */
-int varp_handle_message(struct sk_buff *skb){
-    // Assume nh, h set, skb->data points at udp hdr (h).
-    int err = -EINVAL;
-    VarpHdr *varph; // = (void*)(skb->h.uh + 1);
-
-    dprintf("> skb=%p saddr=" IPFMT " daddr=" IPFMT "\n",
-            skb,
-            NIPQUAD(skb->nh.iph->saddr),
-            NIPQUAD(skb->nh.iph->daddr));
-    if(!varp_table){
-        err = -ENOSYS;
-        return err;
-    }
-    if(MULTICAST(skb->nh.iph->daddr)){
-        if(skb->nh.iph->daddr != varp_mcast_addr){
-            // Ignore multicast packets not addressed to us.
-            err = 0;
-            dprintf("> Ignoring daddr=" IPFMT " mcaddr=" IPFMT "\n",
-                    NIPQUAD(skb->nh.iph->daddr), NIPQUAD(varp_mcast_addr));
-            goto exit;
-        }
-    }
-    varph = (void*)skb_pull_vn(skb, sizeof(struct udphdr));
-    if(skb->len < sizeof(struct VnetMsgHdr)){
-        wprintf("> Varp msg too short: %d < %d\n", skb->len, sizeof(struct 
VnetMsgHdr));
-        goto exit;
-    }
-    switch(ntohs(varph->hdr.id)){
-    case VARP_ID: // Varp message. Handled below.
-        if(skb->len < sizeof(*varph)){
-            wprintf("> Varp msg too short: %d < %d\n", skb->len, 
sizeof(*varph));
-            goto exit;
-        }
-        break;
-    case VUDP_ID: // Etherip-in-udp packet.
-        skb_pull_vn(skb, sizeof(struct VnetMsgHdr));
-        err = etherip_protocol_recv(skb);
-        goto exit;
-    case VFWD_ID: // Forwarded.
-        skb_pull_vn(skb, sizeof(struct VnetMsgHdr));
-        err = vnet_forward_recv(skb);
-        goto exit;
-    default:
-        // It's not varp at all - ignore it.
-        wprintf("> Invalid varp id: %d\n", ntohs(varph->hdr.id));
-        print_skb("INVALID", 0, skb);
-        goto exit;
-    }
-#ifdef DEBUG
-    {
-        char vnetbuf[VNET_ID_BUF];
-        char addrbuf[VARP_ADDR_BUF];
-        dprintf("> saddr=" IPFMT " daddr=" IPFMT "\n",
-                NIPQUAD(skb->nh.iph->saddr), NIPQUAD(skb->nh.iph->daddr));
-        dprintf("> sport=%u dport=%u\n", ntohs(skb->h.uh->source), 
ntohs(skb->h.uh->dest));
-        dprintf("> opcode=%d vnet=%s vmac=" MACFMT " addr=%s\n",
-                ntohs(varph->hdr.opcode),
-                VnetId_ntoa(&varph->vnet, vnetbuf),
-                MAC6TUPLE(varph->vmac.mac),
-                VarpAddr_ntoa(&varph->addr, addrbuf));
-        varp_dprint();
-    }
-#endif
-    switch(ntohs(varph->hdr.opcode)){
-    case VARP_OP_REQUEST:
-        err = varp_handle_request(skb, varph);
-        break;
-    case VARP_OP_ANNOUNCE:
-        err = varp_handle_announce(skb, varph);
-        break;
-    default:
-        wprintf("> Unknown opcode: %d \n", ntohs(varph->hdr.opcode));
-        break;
-    }
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Send an outgoing packet on the appropriate vnet tunnel.
- *
- * @param skb outgoing message
- * @param vnet vnet (network order)
- * @return 0 on success, error code otherwise
- */
-int varp_output(struct sk_buff *skb, VnetId *vnet){
-    int err = 0;
-    unsigned char *mac = NULL;
-    Vmac *vmac = NULL;
-    VarpEntry *ventry = NULL;
-#if defined(DEBUG)
-    char vnetbuf[VNET_ID_BUF];
-#endif
-
-    dprintf("> vnet=%s\n", VnetId_ntoa(vnet, vnetbuf));
-    if(!varp_table){
-        err = -ENOSYS;
-        goto exit;
-    }
-    if(!skb->mac.raw){
-        wprintf("> No ethhdr in skb!\n");
-        err = -EINVAL;
-        goto exit;
-    }
-    mac = eth_hdr(skb)->h_dest;
-    vmac = (Vmac*)mac;
-    if(mac_is_multicast(mac)){
-        err = varp_multicast(vnet, skb);
-    } else {
-        ventry = VarpTable_lookup(varp_table, vnet, vmac, 1);
-        if(ventry){
-            err = VarpEntry_output(ventry, skb);
-            VarpEntry_decref(ventry);
-        } else {
-            err = -ENOMEM;
-        }
-    }
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Set the varp multicast address (after initialization).
- *
- * @param addr address (network order)
- * @return 0 on success, error code otherwise
- */
-int varp_set_mcast_addr(uint32_t addr){
-    int err = 0;
-    varp_close();
-    varp_mcast_addr = addr;
-    err = varp_open(varp_mcast_addr, varp_port);
-    return err;
-}
-
-/** Initialize the varp multicast address from a module parameter.
- *
- * @param s address in IPv4 notation
- * @return 0 on success, error code otherwise
- */
-static void varp_init_mcast_addr(char *s){
-    unsigned long v = 0;
-
-    dprintf("> %s\n", s);
-    if(s && (get_inet_addr(s, &v) >= 0)){
-        varp_mcast_addr = (u32)v;
-    } else {
-        varp_mcast_addr = htonl(VARP_MCAST_ADDR);
-    }
-}
-
-/** Initialize the varp cache.
- *
- * @return 0 on success, error code otherwise
- */
-int varp_init(void){
-    int err = 0;
-    
-    dprintf(">\n");
-    varp_table = VarpTable_new();
-    if(!varp_table){
-        err = -ENOMEM;
-        goto exit;
-    }
-    VarpTable_schedule(varp_table);
-    varp_init_mcast_addr(varp_mcaddr);
-    varp_port = htons(VARP_PORT);
-
-    err = varp_open(varp_mcast_addr, varp_port);
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Close the varp cache.
- */
-void varp_exit(void){
-    dprintf(">\n");
-    varp_close();
-    if(varp_table){
-        VarpTable *vtable = varp_table;
-        varp_table = NULL;
-        VarpTable_free(vtable);
-    }
-    dprintf("<\n");
-}
-
-module_param(varp_mcaddr, charp, 0644);
-module_param(varp_device, charp, 0644);
-MODULE_PARM_DESC(varp_mcaddr, "VARP multicast address");
-MODULE_PARM_DESC(varp_device, "VARP network device");
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/varp.h
--- a/tools/vnet/vnet-module/varp.h     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef _VNET_VARP_H
-#define _VNET_VARP_H
-
-#ifdef __KERNEL__
-
-#else
-
-#include "sys_kernel.h"
-
-#endif
-
-#include "hash_table.h"
-#include "if_varp.h"
-#include "varp_util.h"
-
-#define CONFIG_VARP_GRATUITOUS 1
-
-struct net_device;
-struct sk_buff;
-struct Vif;
-
-enum {
-    VARP_UPDATE_CREATE = 1,
-    VARP_UPDATE_QUEUE  = 2,
-};
-
-extern int vnet_get_device(const char *name, struct net_device **dev);
-extern int vnet_get_device_address(struct net_device *dev, u32 *addr);
-
-extern int varp_remove_vnet(struct VnetId *vnet);
-extern int varp_handle_message(struct sk_buff *skb);
-extern int varp_output(struct sk_buff *skb, struct VnetId *vnet);
-extern int varp_update(struct VnetId *vnet, unsigned char *vmac,
-                       struct VarpAddr *addr);
-
-extern int varp_init(void);
-extern void varp_exit(void);
-
-extern int varp_open(u32 mcaddr, u16 port);
-extern void varp_close(void);
-extern int varp_set_mcast_addr(u32 addr);
-
-extern void varp_print(struct IOStream *io);
-extern void varp_flush(void);
-
-extern int varp_announce_vif(struct net_device *dev, struct Vif *vif);
-
-extern u32 varp_mcast_addr;
-extern u16 varp_port;
-
-/* MAC broadcast addr is ff-ff-ff-ff-ff-ff (all 1's).
- * MAC multicast addr has low bit 1, i.e. 01-00-00-00-00-00.
- */
-
-/** Test if a MAC address is a multicast or broadcast address.
- *
- * @param mac address
- * @return 1 if it is, 0 if not
- */
-static inline int mac_is_multicast(u8 mac[ETH_ALEN]){
-    return mac[0] & 1;
-}
-
-/** Test if a MAC address is the broadcast address.
- *
- * @param mac address
- * @return 1 if it is, 0 if not
- */
-static inline int mac_is_broadcast(u8 mac[ETH_ALEN]){
-    u8 mac_bcast_val[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-    return memcmp(mac, mac_bcast_val, ETH_ALEN) == 0;
-}
-
-/** Test if a MAC address is the all-zero address.
- *
- * @param mac address
- * @return 1 if it is, 0 if not
- */
-static inline int mac_is_zero(u8 mac[ETH_ALEN]){
-    u8 mac_zero_val[ETH_ALEN] = {};
-    return memcmp(mac, mac_zero_val, ETH_ALEN) == 0;
-}
-
-/** Print format for a mac address. */
-#define MACFMT "%02x:%02x:%02x:%02x:%02x:%02x"
-
-#define MAC6TUPLE(_mac) (_mac)[0], (_mac)[1], (_mac)[2], (_mac)[3], (_mac)[4], 
(_mac)[5]
-
-/** Get the subnet defined by a netmask and addr.
- *
- * @param netmask subnet netmask
- * @param addr    subnet address
- * @return subnet
- */
-static inline u32 subnet_net(u32 netmask, u32 addr){
-    return netmask & addr;
-}
-
-/** Get the address within a subnet.
- *
- * @param netmask subnet netmask
- * @param addr    address
- * @return address within the subnet
- */
-static inline u32 subnet_addr(u32 netmask, u32 addr){
-    return ~netmask & addr;
-}
-
-/** Get the broadcast address for a subnet.
- *
- * @param netmask subnet netmask
- * @param netaddr subnet address
- * @return subnet broadcast address
- */
-static inline u32 subnet_broadcast_addr(u32 netmask, u32 netaddr){
-    return subnet_net(netmask, netaddr) | ~netmask;
-}
-
-/** Test if an address corresponds to a subnet broadcast.
- * True if the address within the subnet is all 1's (in binary).
- * (even if the address is not in the subnet).
- *
- * @param netmask subnet mask
- * @param add     address
- * @return 1 if it does, 0 otherwise
- */
-static inline int subnet_broadcast(u32 netmask, u32 addr){
-    return subnet_addr(netmask, INADDR_ANY) == subnet_addr(netmask, addr);
-}
-
-/** Test if an address is in a subnet.
- *
- * @param netmask subnet mask
- * @param netaddr subnet address
- * @param addr    address
- * @return 1 if it is, 0 otherwise
- */
-static inline int subnet_local(u32 netmask, u32 netaddr, u32 addr){
-    return subnet_net(netmask, netaddr) == subnet_net(netmask, addr);
-}
-
-#endif /* ! _VNET_VARP_H */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/varp_socket.c
--- a/tools/vnet/vnet-module/varp_socket.c      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,767 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/version.h>
-
-#include <asm/uaccess.h>
-#include <linux/net.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/sched.h>
-#include <linux/file.h>
-#include <linux/version.h>
-#include <linux/smp_lock.h>
-#include <net/sock.h>
-
-#include <if_varp.h>
-#include <varp.h>
-#include <vnet_forward.h>
-
-/* Get macros needed to define system calls as functions in the kernel. */
-#define __KERNEL_SYSCALLS__
-int errno=0;
-#include <linux/unistd.h>
-
-#define MODULE_NAME "VARP"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** @file
- * Support for the VARP udp sockets.
- */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-
-/* Compensate for struct sock fields having 'sk_' added to them in 2.6. */
-#define sk_receive_queue receive_queue
-#define sk_sleep         sleep
-
-/* Here because inline in 'socket.c' (2.4, in net.h for 2.6). */
-#define sockfd_put(sock) fput((sock)->file)
-
-#endif
-
-static inline mm_segment_t change_fs(mm_segment_t fs){
-    mm_segment_t oldfs = get_fs();
-    set_fs(fs);
-    return oldfs;
-}
-
-/** Define the fcntl() syscall. */
-static inline _syscall3(int, fcntl,
-                        unsigned int, fd, 
-                        unsigned int, cmd,
-                        unsigned long, arg)
-
-/* Replicate the user-space socket API.
- * The parts we need anyway.
- *
- * Some architectures use socketcall() to multiplex the socket-related calls,
- * but others define individual syscalls instead.
- * Architectures using socketcall() define __ARCH_WANT_SYS_SOCKETCALL.
- * NB. x86_64 architecture asserts __ARCH_WANT_SYS_SOCKETCALL in error.
- */
-
-#if defined(__ARCH_WANT_SYS_SOCKETCALL) && !defined(__x86_64__)
-
-/* Define the socketcall() syscall.
- * Multiplexes all the socket-related calls.
- *
- * @param call socket call id
- * @param args arguments (upto 6)
- * @return call-dependent value
- */
-static inline _syscall2(int, socketcall,
-                        int, call,
-                        unsigned long *, args)
-
-int socket(int family, int type, int protocol){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)family;
-    args[1] = (unsigned long)type;
-    args[2] = (unsigned long)protocol;
-    return socketcall(SYS_SOCKET, args);
-}
-
-int bind(int fd, struct sockaddr *umyaddr, int addrlen){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)umyaddr;
-    args[2] = (unsigned long)addrlen;
-    return socketcall(SYS_BIND, args);
-}
-
-int connect(int fd, struct sockaddr *uservaddr, int addrlen){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)uservaddr;
-    args[2] = (unsigned long)addrlen;
-    return socketcall(SYS_CONNECT, args);
-}
-
-int sendto(int fd, void * buff, size_t len,
-           unsigned flags, struct sockaddr *addr,
-           int addr_len){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)buff;
-    args[2] = (unsigned long)len;
-    args[3] = (unsigned long)flags;
-    args[4] = (unsigned long)addr;
-    args[5] = (unsigned long)addr_len;
-    return socketcall(SYS_SENDTO, args);
-}
-
-int recvfrom(int fd, void * ubuf, size_t size,
-             unsigned flags, struct sockaddr *addr,
-             int *addr_len){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)ubuf;
-    args[2] = (unsigned long)size;
-    args[3] = (unsigned long)flags;
-    args[4] = (unsigned long)addr;
-    args[5] = (unsigned long)addr_len;
-    return socketcall(SYS_RECVFROM, args);
-}
-
-int setsockopt(int fd, int level, int optname, void *optval, int optlen){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)level;
-    args[2] = (unsigned long)optname;
-    args[3] = (unsigned long)optval;
-    args[4] = (unsigned long)optlen;
-    return socketcall(SYS_SETSOCKOPT, args);
-}
-
-int getsockopt(int fd, int level, int optname, void *optval, int *optlen){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)level;
-    args[2] = (unsigned long)optname;
-    args[3] = (unsigned long)optval;
-    args[4] = (unsigned long)optlen;
-    return socketcall(SYS_GETSOCKOPT, args);
-}
-
-int shutdown(int fd, int how){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)how;
-    return socketcall(SYS_SHUTDOWN, args);
-}
-
-int getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)usockaddr;
-    args[2] = (unsigned long)usockaddr_len;
-    return socketcall(SYS_GETSOCKNAME, args);
-}
-
-#else /* !__ARCH_WANT_SYS_SOCKETCALL */
-
-/* No socketcall - define the individual syscalls. */
-
-static inline _syscall3(int, socket,
-                        int, family,
-                        int, type,
-                        int, protocol);
-
-static inline _syscall3(int, bind,
-                        int, fd,
-                        struct sockaddr *, umyaddr,
-                        int, addrlen);
-
-static inline _syscall3(int, connect,
-                        int, fd,
-                        struct sockaddr *, uservaddr,
-                        int, addrlen);
-
-static inline _syscall6(int, sendto,
-                        int, fd,
-                        void *, buff,
-                        size_t, len,
-                        unsigned, flags,
-                        struct sockaddr *, addr,
-                        int, addr_len);
-
-static inline _syscall6(int, recvfrom,
-                        int, fd,
-                        void *, ubuf,
-                        size_t, size,
-                        unsigned, flags,
-                        struct sockaddr *, addr,
-                        int *, addr_len);
-
-static inline _syscall5(int, setsockopt,
-                        int, fd,
-                        int, level,
-                        int, optname,
-                        void *, optval,
-                        int, optlen);
-
-static inline _syscall5(int, getsockopt,
-                        int, fd,
-                        int, level,
-                        int, optname,
-                        void *, optval,
-                        int *, optlen);
-
-static inline _syscall2(int, shutdown,
-                        int, fd,
-                        int, how);
-
-static inline _syscall3(int, getsockname,
-                        int, fd,
-                        struct sockaddr *, usockaddr,
-                        int *, usockaddr_len);
-
-#endif /* __ARCH_WANT_SYS_SOCKETCALL */
-
-/*============================================================================*/
-/** Socket flags. */
-enum VsockFlag {
-    VSOCK_REUSE     =  1,
-    VSOCK_BIND      =  2,
-    VSOCK_CONNECT   =  4,
-    VSOCK_BROADCAST =  8,
-    VSOCK_MULTICAST = 16,
-    VSOCK_NONBLOCK  = 32,
- };
-
-/** Convert socket flags to a string.
- *
- * @param flags flags
- * @return static string
- */
-char * socket_flags(int flags){
-    static char s[7];
-    int i = 0;
-    s[i++] = (flags & VSOCK_CONNECT   ? 'c' : '-');
-    s[i++] = (flags & VSOCK_BIND      ? 'b' : '-');
-    s[i++] = (flags & VSOCK_REUSE     ? 'r' : '-');
-    s[i++] = (flags & VSOCK_BROADCAST ? 'B' : '-');
-    s[i++] = (flags & VSOCK_MULTICAST ? 'M' : '-');
-    s[i++] = (flags & VSOCK_NONBLOCK  ? 'N' : '-');
-    s[i++] = '\0';
-    return s;
-}
-
-/** Control flag for whether varp should be running.
- * If this is set 0 then the varp thread will notice and
- * (eventually) exit.
- */
-atomic_t varp_run = ATOMIC_INIT(0);
-
-enum {
-    VARP_STATE_EXITED  = 2,
-    VARP_STATE_RUNNING = 1,
-    VARP_STATE_NONE    = 0,
-    VARP_STATE_ERROR   = -1,
-};
-
-/** State indicating whether the varp thread is running. */
-atomic_t varp_state = ATOMIC_INIT(VARP_STATE_NONE);
-
-int varp_thread_err = 0;
-
-/** The varp multicast socket. */
-int varp_mcast_sock = -1;
-
-/** The varp unicast socket. */
-int varp_ucast_sock = -1;
-
-/** Set socket option to reuse address.
- *
- * @param sock socket
- * @param reuse flag
- * @return 0 on success, error code otherwise
- */
-int setsock_reuse(int sock, int reuse){
-    int err = 0;
-    err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
-    if(err < 0){
-        eprintf("> setsockopt SO_REUSEADDR: %d %d\n", err, errno);
-    }
-    return err;
-}
-
-/** Set socket broadcast option.
- *
- * @param sock socket
- * @param bcast flag
- * @return 0 on success, error code otherwise
- */
-int setsock_broadcast(int sock, int bcast){
-    int err = 0;
-    err = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast));
-    if(err < 0){
-        eprintf("> setsockopt SO_BROADCAST: %d %d\n", err, errno);
-    }
-    return err;
-}
-
-/** Join a socket to a multicast group.
- *
- * @param sock socket
- * @param saddr multicast address
- * @return 0 on success, error code otherwise
- */
-int setsock_multicast(int sock, uint32_t saddr){
-    int err = 0;
-    struct ip_mreqn mreq = {};
-    int mloop = 0;
-
-    // See 'man 7 ip' for these options.
-    mreq.imr_multiaddr.s_addr = saddr;       // IP multicast address.
-    mreq.imr_address.s_addr   = INADDR_ANY;  // Interface IP address.
-    mreq.imr_ifindex = 0;                    // Interface index (0 means any).
-    err = setsockopt(sock, SOL_IP, IP_MULTICAST_LOOP, &mloop, sizeof(mloop));
-    if(err < 0){
-        eprintf("> setsockopt IP_MULTICAST_LOOP: %d %d\n", err, errno);
-        goto exit;
-    }
-    err = setsockopt(sock, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
-    if(err < 0){
-        eprintf("> setsockopt IP_ADD_MEMBERSHIP: %d %d\n", err, errno);
-        goto exit;
-    }
-  exit:
-    return err;
-}
-
-/** Set a socket's multicast ttl (default is 1).
- * @param sock socket
- * @param ttl ttl
- * @return 0 on success, error code otherwise
- */
-int setsock_multicast_ttl(int sock, uint8_t ttl){
-    int err = 0;
-    err = setsockopt(sock, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
-    return err;
-}
-
-/** Create a socket.
- * The flags can include values from enum VsockFlag.
- *
- * @param socktype socket type
- * @param saddr address
- * @param port port
- * @param flags flags
- * @param val return value for the socket connection
- * @return 0 on success, error code otherwise
- */
-int create_socket(int socktype, uint32_t saddr, uint32_t port, int flags, int 
*val){
-    int err = 0;
-    int sock;
-    struct sockaddr_in addr_in;
-    struct sockaddr *addr = (struct sockaddr *)&addr_in;
-    int addr_n = sizeof(addr_in);
-    int sockproto = 0;
-
-    //dprintf(">\n");
-    addr_in.sin_family      = AF_INET;
-    addr_in.sin_addr.s_addr = saddr;
-    addr_in.sin_port        = port;
-    dprintf("> flags=%s addr=%u.%u.%u.%u port=%d\n",
-            socket_flags(flags),
-            NIPQUAD(saddr), ntohs(port));
-
-    switch(socktype){
-    case SOCK_DGRAM:  sockproto = IPPROTO_UDP; break;
-    case SOCK_STREAM: sockproto = IPPROTO_TCP; break;
-    }
-    sock = socket(AF_INET, socktype, sockproto);
-    if(sock < 0) goto exit;
-    if(flags & VSOCK_REUSE){
-        err = setsock_reuse(sock, 1);
-        if(err < 0) goto exit;
-    }
-    if(flags & VSOCK_BROADCAST){
-        err = setsock_broadcast(sock, 1);
-        if(err < 0) goto exit;
-    }
-    if(flags & VSOCK_MULTICAST){
-        err = setsock_multicast(sock, saddr);
-        if(err < 0) goto exit;
-    }
-    if(flags & VSOCK_CONNECT){
-        err = connect(sock, addr, addr_n);
-        if(err < 0) goto exit;
-    }
-    if(flags & VSOCK_BIND){
-        err = bind(sock, addr, addr_n);
-        if(err < 0) goto exit;
-    }
-    if(flags & VSOCK_NONBLOCK){
-        err = fcntl(sock, F_SETFL, O_NONBLOCK);
-        if(err < 0) goto exit;
-    }
-  exit:
-    *val = (err ? -1 : sock);
-    if(err) eprintf("> err=%d errno=%d\n", err, errno);
-    return err;
-}
-
-/** Open the varp multicast socket.
- *
- * @param mcaddr multicast address 
- * @param port port
- * @param val return parameter for the socket
- * @return 0 on success, error code otherwise
- */
-int varp_mcast_open(uint32_t mcaddr, uint16_t port, int *val){
-    int err = 0;
-    int flags = VSOCK_REUSE;
-    int sock = 0;
-    
-    dprintf(">\n");
-    flags |= VSOCK_MULTICAST;
-    flags |= VSOCK_BROADCAST;
-    
-    err = create_socket(SOCK_DGRAM, mcaddr, port, flags, &sock);
-    if(err < 0) goto exit;
-    if(MULTICAST(mcaddr)){
-        err = setsock_multicast_ttl(sock, 1);
-        if(err < 0) goto exit;
-    }
-  exit:
-    if(err){
-        shutdown(sock, 2);
-    }
-    *val = (err ? -1 : sock);
-    dprintf("< err=%d val=%d\n", err, *val);
-    return err;
-}
-
-/** Open the varp unicast socket.
- *
- * @param addr address 
- * @param port port
- * @param val return parameter for the socket
- * @return 0 on success, error code otherwise
- */
-int varp_ucast_open(uint32_t addr, u16 port, int *val){
-    int err = 0;
-    int flags = (VSOCK_BIND | VSOCK_REUSE);
-    dprintf(">\n");
-    err = create_socket(SOCK_DGRAM, addr, port, flags, val);
-    dprintf("< err=%d val=%d\n", err, *val);
-    return err;
-}
-
-/**
- * Return code > 0 means the handler owns the packet.
- * Return code <= 0 means we still own it, with < 0 meaning
- * an error.
- */
-static int handle_varp_skb(struct sk_buff *skb){
-    int err = 0;
-    switch(skb->pkt_type){
-    case PACKET_BROADCAST:
-    case PACKET_MULTICAST:
-        vnet_forward_send(skb);
-        /* Fall through. */
-    case PACKET_HOST:
-        err = varp_handle_message(skb);
-        break;
-    case PACKET_OTHERHOST:
-        dprintf("> PACKET_OTHERHOST\n");
-        break;
-    case PACKET_OUTGOING:
-        dprintf("> PACKET_OUTGOING\n");
-        break;
-    case PACKET_FASTROUTE:
-        dprintf("> PACKET_FASTROUTE\n");
-        break;
-    case PACKET_LOOPBACK:
-        // Outbound mcast/bcast are echoed with this type. Drop.
-        dprintf("> LOOP src=" IPFMT " dst=" IPFMT " dev=%s\n",
-                NIPQUAD(skb->nh.iph->saddr),
-                NIPQUAD(skb->nh.iph->daddr),
-                (skb->dev ? skb->dev->name : "??"));
-      default:
-        // Drop.
-        break;
-    }
-    if(err <= 0){
-        kfree_skb(skb);
-    }
-    return (err < 0 ? err : 0);
-}
-
-/** Handle some skbs on a varp socket (if any).
- *
- * @param fd socket file descriptor
- * @param n maximum number of skbs to handle
- * @return number of skbs handled
- */
-static int handle_varp_sock(int fd, int n){
-    int ret = 0;
-    int err = 0;
-    struct sk_buff *skb;
-    struct socket *sock = NULL;
-
-    sock = sockfd_lookup(fd, &err);
-    if (!sock){
-        wprintf("> no sock for fd=%d\n", fd);
-        goto exit;
-    }
-    for( ; ret < n; ret++){
-        if(!sock->sk) break;
-        skb = skb_dequeue(&sock->sk->sk_receive_queue);
-        if(!skb) break;
-        // Call the skb destructor so it isn't charged to the socket anymore.
-        // An skb from a socket receive queue is charged to the socket
-        // by skb_set_owner_r() until its destructor is called.
-        // If the destructor is not called the socket will run out of
-        // receive queue space and be unable to accept incoming skbs.
-        // The destructor used is sock_rfree(), see 'include/net/sock.h'.
-        // Other destructors: sock_wfree, sk_stream_rfree.
-        skb_orphan(skb);
-        handle_varp_skb(skb);
-    }
-    sockfd_put(sock);
-  exit:
-    dprintf("< ret=%d\n", ret);
-    return ret;
-}
-
-/** Add a wait queue to a socket.
- *
- * @param fd socket file descriptor
- * @param waitq queue
- * @return 0 on success, error code otherwise
- */
-int sock_add_wait_queue(int fd, wait_queue_t *waitq){
-    int err = -EINVAL;
-    struct socket *sock = NULL;
-
-    if(fd < 0) goto exit;
-    sock = sockfd_lookup(fd, &err);
-    if (!sock) goto exit;
-    add_wait_queue(sock->sk->sk_sleep, waitq);
-    sockfd_put(sock);
-    err = 0;
-  exit:
-    return err;
-}
-
-/** Remove a wait queue from a socket.
- *
- * @param fd socket file descriptor
- * @param waitq queue
- * @return 0 on success, error code otherwise
- */
-int sock_remove_wait_queue(int fd, wait_queue_t *waitq){
-    int err = -EINVAL;
-    struct socket *sock = NULL;
-
-    if(fd < 0) goto exit;
-    sock = sockfd_lookup(fd, &err);
-    if (!sock) goto exit;
-    remove_wait_queue(sock->sk->sk_sleep, waitq);
-    sockfd_put(sock);
-    err = 0;
-  exit:
-    return err;
-}
-
-#if 0
-// Default data ready function on a socket.
-static void sock_def_readable(struct sock *sk, int len)
-{
-       read_lock(&sk->sk_callback_lock);
-       if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-               wake_up_interruptible(sk->sk_sleep);
-       sk_wake_async(sk,1,POLL_IN);
-       read_unlock(&sk->sk_callback_lock);
-}
-#endif
-
-static void sock_data_ready(struct sock *sk, int len){
-    struct sk_buff *skb;
-    //read_lock(&sk->sk_callback_lock);
-    skb = skb_dequeue(&sk->sk_receive_queue);
-    if(skb){
-        skb_orphan(skb);
-    }
-    //read_unlock(&sk->sk_callback_lock);
-    if(skb){
-        handle_varp_skb(skb);
-    }
-}
-
-/** Set the data ready callback on a socket.
- */
-int sock_set_callback(int fd){
-    int err = -EINVAL;
-    struct socket *sock = NULL;
-
-    if(fd < 0) goto exit;
-    sock = sockfd_lookup(fd, &err);
-    if (!sock) goto exit;
-    sock->sk->sk_data_ready = sock_data_ready;
-    sockfd_put(sock);
-    err = 0;
-  exit:
-    return err;
-}
-
-/** Open the sockets. */
-int varp_sockets_open(u32 mcaddr, u16 port){
-    int err = 0;
-    mm_segment_t oldfs;
-
-    dprintf("> mcaddr=%u.%u.%u.%u port=%u\n", NIPQUAD(mcaddr), ntohs(port));
-    oldfs = change_fs(KERNEL_DS);
-    err = varp_mcast_open(mcaddr, port, &varp_mcast_sock);
-    if(err < 0 ) goto exit;
-    err = varp_ucast_open(INADDR_ANY, port, &varp_ucast_sock);
-    if(err < 0 ) goto exit;
-    sock_set_callback(varp_ucast_sock);
-    sock_set_callback(varp_mcast_sock);
-  exit:
-    set_fs(oldfs);
-    dprintf("< err=%d\n", err);
-    return err;
-}      
-
-/** Close the sockets. */
-void varp_sockets_close(void){
-    mm_segment_t oldfs;
-    oldfs = change_fs(KERNEL_DS);
-    if(varp_mcast_sock >= 0){
-        shutdown(varp_mcast_sock, 2);
-        varp_mcast_sock = -1;
-    }
-    if(varp_ucast_sock >= 0){
-        shutdown(varp_ucast_sock, 2);
-        varp_ucast_sock = -1;
-    }
-    set_fs(oldfs);
-}
-
-/** Loop handling the varp sockets.
- * We use kernel API for this (waitqueue, schedule_timeout) instead
- * of select because the select syscall was returning EFAULT. Oh well.
- *
- * @param arg arguments
- * @return exit code
- */
-int varp_main(void *arg){
-    int err = 0;
-    long timeout = 1 * HZ;
-    int count = 0;
-    DECLARE_WAITQUEUE(mcast_wait, current);
-    DECLARE_WAITQUEUE(ucast_wait, current);
-
-    dprintf("> start\n");
-    snprintf(current->comm, sizeof(current->comm), "varp_main");
-
-    err = sock_add_wait_queue(varp_mcast_sock, &mcast_wait);
-    if(err) goto exit_mcast_sock;
-    err = sock_add_wait_queue(varp_ucast_sock, &ucast_wait);
-    if(err) goto exit_ucast_sock;
-    atomic_set(&varp_state, VARP_STATE_RUNNING);
-    for( ; atomic_read(&varp_run); ){
-        count = 0;
-        count += handle_varp_sock(varp_mcast_sock, 1);
-        count += handle_varp_sock(varp_ucast_sock, 16);
-        if(!count){
-            if(!atomic_read(&varp_run)) break;
-            // No skbs were handled, go to sleep.
-            set_current_state(TASK_INTERRUPTIBLE);
-            schedule_timeout(timeout);
-            __set_current_state(TASK_RUNNING);
-        }
-    }
-  exit_ucast_sock:
-    sock_remove_wait_queue(varp_ucast_sock, &ucast_wait);
-  exit_mcast_sock:
-    sock_remove_wait_queue(varp_mcast_sock, &mcast_wait);
-    varp_sockets_close();
-    if(err){
-        eprintf("%s< err=%d\n", __FUNCTION__, err);
-    }
-    varp_thread_err = err;
-    atomic_set(&varp_state, VARP_STATE_EXITED);
-    //MOD_DEC_USE_COUNT;
-    return err;
-}
-
-/** Close the varp sockets and stop the thread handling them.
- */
-void varp_close(void){
-    int tries = 10;
-    dprintf(">\n");
-    // Tell the varp thread to stop and wait a while for it.
-    atomic_set(&varp_run, 0);
-    while(atomic_read(&varp_state) == VARP_STATE_RUNNING && tries-- > 0){
-        set_current_state(TASK_INTERRUPTIBLE);
-        schedule_timeout(HZ / 2);
-        __set_current_state(TASK_RUNNING);
-    }
-    //MOD_DEC_USE_COUNT;
-    dprintf("<\n");
-}    
-
-/** Open the varp sockets and start the thread handling them.
- *
- * @param mcaddr multicast address
- * @param port port
- * @return 0 on success, error code otherwise
- */
-int varp_open(u32 mcaddr, u16 port){
-    int err = 0;
-    
-    //MOD_INC_USE_COUNT;
-    dprintf(">\n");
-    err = varp_sockets_open(mcaddr, port);
-    if(err) goto exit;
-    atomic_set(&varp_run, 1);
-    atomic_set(&varp_state, VARP_STATE_NONE);
-    kernel_thread(varp_main, NULL, (CLONE_FS | CLONE_FILES | CLONE_SIGHAND));
-#if 0
-    while(atomic_read(&varp_state) == VARP_STATE_NONE){
-        set_current_state(TASK_INTERRUPTIBLE);
-        schedule_timeout(1 * HZ);
-        __set_current_state(TASK_RUNNING);
-    }
-    err = varp_thread_err;
-#endif
-  exit:
-    if(err){
-        wprintf("> err=%d\n", err);
-    }
-    return err;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/varp_util.c
--- a/tools/vnet/vnet-module/varp_util.c        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-static int hex16(char *s, uint16_t *val)
-{
-    int err = -EINVAL;
-    uint16_t v = 0;
-    
-    for( ; *s; s++){
-        v <<= 4;
-        if('0' <= *s && *s <= '9'){
-            v |= *s - '0';
-        } else if('A' <= *s && *s <= 'F'){
-            v |= *s - 'A' + 10;
-        } else if('a' <= *s && *s <= 'f'){
-            v |= *s - 'a' + 10;
-        } else {
-            goto exit;
-        }
-    }
-    err = 0;
-  exit:
-    *val = (err ? 0 : v);
-    return err;
-}
-
-int VnetId_aton(const char *s, VnetId *vnet){
-    int err = -EINVAL;
-    const char *p, *q;
-    uint16_t v;
-    char buf[5];
-    int buf_n = sizeof(buf) - 1;
-    int i, n;
-    const int elts_n = VNETID_SIZE16;
-
-    q = s;
-    p = strchr(q, ':');
-    i = (p ? 0 : elts_n - 1);
-    do {
-        if(!p){
-            if(i < elts_n - 1) goto exit;
-            p = s + strlen(s);
-        }
-        n = p - q;
-        if(n > buf_n) goto exit;
-        memcpy(buf, q, n);
-        buf[n] = '\0';
-        err = hex16(buf, &v);
-        if(err) goto exit;
-        vnet->u.vnet16[i] = htons(v);
-        q = p+1;
-        p = strchr(q, ':');
-        i++;
-    } while(i < elts_n);
-    err = 0;
-  exit:
-    if(err){
-        *vnet = (VnetId){};
-    }
-    return err;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/varp_util.h
--- a/tools/vnet/vnet-module/varp_util.h        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _VNET_VARP_UTIL_H
-#define _VNET_VARP_UTIL_H
-
-#include "hash_table.h"
-
-/** Size of a string buffer to store a varp address. */
-#define VARP_ADDR_BUF 56
-
-/** Size of a string buffer to store a vnet id. */
-#define VNET_ID_BUF 56
-
-#ifndef NIPQUAD
-#define NIPQUAD(addr) \
-       ((unsigned char *)&addr)[0], \
-       ((unsigned char *)&addr)[1], \
-       ((unsigned char *)&addr)[2], \
-       ((unsigned char *)&addr)[3]
-#endif
-
-#ifndef NIP6
-#define NIP6(addr) \
-       ntohs((addr).s6_addr16[0]), \
-       ntohs((addr).s6_addr16[1]), \
-       ntohs((addr).s6_addr16[2]), \
-       ntohs((addr).s6_addr16[3]), \
-       ntohs((addr).s6_addr16[4]), \
-       ntohs((addr).s6_addr16[5]), \
-       ntohs((addr).s6_addr16[6]), \
-       ntohs((addr).s6_addr16[7])
-#endif
-
-
-static inline const char *VarpAddr_ntoa(VarpAddr *addr, char 
buf[VARP_ADDR_BUF])
-{
-    switch(addr->family){
-    default:
-    case AF_INET:
-        snprintf(buf, sizeof(buf), "%u.%u.%u.%u",
-                NIPQUAD(addr->u.ip4));
-        break;
-    case AF_INET6:
-        snprintf(buf, sizeof(buf), "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
-                NIP6(addr->u.ip6));
-        break;
-    }
-    return buf;
-}
-
-static inline const char *VnetId_ntoa(VnetId *vnet, char buf[VNET_ID_BUF])
-{
-    snprintf(buf, sizeof(buf), "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
-            ntohs(vnet->u.vnet16[0]), \
-            ntohs(vnet->u.vnet16[1]), \
-            ntohs(vnet->u.vnet16[2]), \
-            ntohs(vnet->u.vnet16[3]), \
-            ntohs(vnet->u.vnet16[4]), \
-            ntohs(vnet->u.vnet16[5]), \
-            ntohs(vnet->u.vnet16[6]), \
-            ntohs(vnet->u.vnet16[7]));
-    return buf;
-}
-
-extern int VnetId_aton(const char *s, VnetId *vnet);
-
-/** Convert an unsigned in host order to a vnet id.
- */
-static inline struct VnetId toVnetId(uint32_t vnetid){
-    struct VnetId vnet = {};
-    vnet.u.vnet32[VNETID_SIZE32 - 1] = htonl(vnetid);
-    return vnet;
-}
-
-static inline int VnetId_eq(VnetId *id1, VnetId *id2){
-    return memcmp(id1, id2, sizeof(VnetId)) == 0;
-}
-
-#endif /* _VNET_VARP_UTIL_H */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vif.c
--- a/tools/vnet/vnet-module/vif.c      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,387 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-
-#else
-
-#include "sys_kernel.h"
-#include "spinlock.h"
-#include "skbuff.h"
-
-#endif
-
-#include <vif.h>
-#include <varp.h>
-#include <varp_util.h>
-
-#include "allocate.h"
-#include "iostream.h"
-#include "hash_table.h"
-#include "timer_util.h"
-
-#define MODULE_NAME "VNET"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** Vif table ttl - interval between sweeps of old vifs. */
-#define VIF_TABLE_TTL (60*HZ)
-
-/** Vif entry ttl - a vif entry older than this is removed. */
-#define VIF_ENTRY_TTL (60*HZ)
-
-/** Table of vifs indexed by VifKey. */
-HashTable *vif_table = NULL;
-rwlock_t vif_table_lock = RW_LOCK_UNLOCKED;
-struct timer_list vif_table_timer = {};
-int vif_table_sweeps = 0;
-
-#define vif_read_lock(flags)    read_lock_irqsave(&vif_table_lock, (flags))
-#define vif_read_unlock(flags)  read_unlock_irqrestore(&vif_table_lock, 
(flags))
-#define vif_write_lock(flags)   write_lock_irqsave(&vif_table_lock, (flags))
-#define vif_write_unlock(flags) write_unlock_irqrestore(&vif_table_lock, 
(flags))
-
-void vif_entry_print(Vif *vif, IOStream *io){
-    char vnetbuf[VNET_ID_BUF];
-    unsigned long now = jiffies;
-
-    IOStream_print(io, "(vif\n");
-    IOStream_print(io, " (vnet %s)\n", VnetId_ntoa(&vif->vnet, vnetbuf));
-    IOStream_print(io, " (vmac " MACFMT ")\n", MAC6TUPLE(vif->vmac.mac));
-    IOStream_print(io, " (age %u)\n", now - vif->timestamp);
-    IOStream_print(io, ")\n");
-}
-
-void vif_print(IOStream *io){
-    HashTable_for_decl(entry);
-    Vif *vif;
-    unsigned long flags;
-
-    vif_read_lock(flags);
-    IOStream_print(io, "(viftable\n");
-    IOStream_print(io, " (table_ttl %u)\n", VIF_TABLE_TTL);
-    IOStream_print(io, " (entry_ttl %u)\n", VIF_ENTRY_TTL);
-    IOStream_print(io, " (sweeps %d)\n", vif_table_sweeps);
-    IOStream_print(io, ")\n");
-    
-    HashTable_for_each(entry, vif_table){
-        vif = entry->value;
-        vif_entry_print(vif, io);
-    }
-    vif_read_unlock(flags);
-}
-
-void vif_decref(Vif *vif){
-    if(!vif) return;
-    if(atomic_dec_and_test(&vif->refcount)){
-        kfree(vif);
-    }
-}
-
-void vif_incref(Vif *vif){
-    if(!vif) return;
-    atomic_inc(&vif->refcount);
-}
-
-/** Hash function for keys in the vif table.
- * Hashes the vnet id and mac.
- *
- * @param k key (VifKey)
- * @return hashcode
- */
-static Hashcode vif_key_hash_fn(void *k){
-    return hash_hvoid(0, k, sizeof(VifKey));
-}
-
-/** Test equality for keys in the vif table.
- * Compares vnet and mac.
- *
- * @param k1 key to compare (VifKey)
- * @param k2 key to compare (VifKey)
- * @return 1 if equal, 0 otherwise
- */
-static int vif_key_equal_fn(void *k1, void *k2){
-    return memcmp(k1, k2, sizeof(VifKey)) == 0;
-}
-
-/** Free an entry in the vif table.
- *
- * @param table containing table
- * @param entry entry to free
- */
-static void vif_entry_free_fn(HashTable *table, HTEntry *entry){
-    Vif *vif;
-    if(!entry) return;
-    vif = entry->value;
-    if(vif){
-        vif_decref(vif);
-    }
-    HTEntry_free(entry);
-}
-
-/** Lookup a vif.
- * Caller must hold vif lock.
- *
- * @param vnet vnet id
- * @param mac MAC address
- * @return 0 on success, -ENOENT otherwise
- */
-static int _vif_lookup(VnetId *vnet, Vmac *vmac, Vif **vif){
-    int err = 0;
-    VifKey key = { .vnet = *vnet, .vmac = *vmac };
-    HTEntry *entry = NULL;
-    
-    entry = HashTable_get_entry(vif_table, &key);
-    if(entry){
-        *vif = entry->value;
-        vif_incref(*vif);
-    } else {
-        *vif = NULL;
-        err = -ENOENT;
-    }
-    return err;
-}
-
-/** Lookup a vif.
- *
- * @param vnet vnet id
- * @param mac MAC address
- * @return 0 on success, -ENOENT otherwise
- */
-int vif_lookup(VnetId *vnet, Vmac *vmac, Vif **vif){
-    unsigned long flags;    
-    int err;
-
-    vif_read_lock(flags);
-    err = _vif_lookup(vnet, vmac, vif);
-    vif_read_unlock(flags);
-    return err;
-}
-
-/** Create a new vif.
- * Entry must not exist.
- * Caller must hold vif lock.
- *
- * @param vnet vnet id
- * @param mac MAC address
- * @return 0 on success, negative error code otherwise
- */
-static int _vif_add(VnetId *vnet, Vmac *vmac, Vif **val){
-    int err = 0;
-    Vif *vif = NULL;
-    HTEntry *entry;
-    unsigned long now = jiffies;
-
-    vif = ALLOCATE(Vif);
-    if(!vif){
-        err = -ENOMEM;
-        goto exit;
-    }
-    atomic_set(&vif->refcount, 1);
-    vif->vnet = *vnet;
-    vif->vmac = *vmac;
-    vif->timestamp = now;
-    entry = HashTable_add(vif_table, vif, vif);
-    if(!entry){
-        err = -ENOMEM;
-        deallocate(vif);
-        vif = NULL;
-        goto exit;
-    }
-    vif_incref(vif);
-  exit:
-    *val = (err ? NULL : vif);
-    return err;
-}
-
-/** Delete a vif entry.
- *
- * @param vnet vnet id
- * @param mac MAC address
- * @return number of entries deleted, or negative error code
- */
-int vif_remove(VnetId *vnet, Vmac *vmac){
-    int err = 0;
-    VifKey key = { .vnet = *vnet, .vmac = *vmac };
-    unsigned long flags;
-
-    vif_write_lock(flags);
-    err = HashTable_remove(vif_table, &key);
-    vif_write_unlock(flags);
-    return err;
-}
-
-/** Delete all vifs on a vnet.
- *
- * @param vnet vnet id
- * @return number of entries deleted
- */
-int vif_remove_vnet(VnetId *vnet){
-    int count = 0;
-    unsigned long flags;
-    HashTable_for_decl(entry);
-
-    
-    vif_write_lock(flags);
-    HashTable_for_each(entry, vif_table){
-        Vif *vif = entry->value;
-        if(VnetId_eq(&vif->vnet, vnet)){
-            count += HashTable_remove(vif_table, vif);
-        }
-    }
-    vif_write_unlock(flags);
-    return count;
-}
-
-/** Purge the vif table.
- */
-void vif_purge(void){
-    unsigned long flags;
-    vif_write_lock(flags);
-    HashTable_clear(vif_table);
-    vif_write_unlock(flags);
-}
-
-/** Sweep old vif entries from the vif table.
- */
-void vif_sweep(void){
-    HashTable_for_decl(entry);
-    Vif *vif;
-    int vif_count = 0;
-    unsigned long now = jiffies;
-    unsigned long old = VIF_ENTRY_TTL;
-    unsigned long flags;
-
-    vif_write_lock(flags);
-    vif_table_sweeps++;
-    HashTable_for_each(entry, vif_table){
-        vif = entry->value;
-        vif_count++;
-        if(!(vif->flags & VIF_FLAG_PERSISTENT)
-           && (now - vif->timestamp > old)){
-            iprintf("> Sweeping:\n");
-            vif_entry_print(vif, iostdout);
-            HashTable_remove(vif_table, entry->key);
-        }
-    }
-    vif_write_unlock(flags);
-}
-
-/** Create a new vif if it does not exist.
- * Caller must hold vif lock.
- *
- * @param vnet vnet id
- * @param mac MAC address
- * @return 0 on success, negative error code otherwise
- */
-int _vif_create(VnetId *vnet, Vmac *vmac, Vif **vif){
-    int err = 0;
-
-    if(_vif_lookup(vnet, vmac, vif) == 0){
-        goto exit;
-    }
-    err = _vif_add(vnet, vmac, vif);
-  exit:
-    return err;
-}
-
-/** Create a new vif if it does not exist.
- *
- * @param vnet vnet id
- * @param mac MAC address
- * @return 0 on success, negative error code otherwise
- */
-int vif_create(VnetId *vnet, Vmac *vmac, int vflags, Vif **vif){
-    int err = 0;
-    unsigned long flags;
-
-    vif_write_lock(flags);
-    err = _vif_create(vnet, vmac, vif);
-    if(!err && *vif){
-        (*vif)->flags = vflags;
-    }
-    vif_write_unlock(flags);
-    return err;
-}
-
-/** Update the timestamp for a vif.
- *
- * @param vnet vnet id
- * @param mac MAC address
- * @return 0 on success, negative error code otherwise
- */
-int vif_update(VnetId *vnet, Vmac *vmac){
-    Vif *vif = NULL;
-    int err = 0;
-    unsigned long now = jiffies;
-    unsigned long flags;
-
-    vif_write_lock(flags);
-    err = _vif_create(vnet, vmac, &vif);
-    if(err) goto exit;
-    vif->timestamp = now;
-    vif_decref(vif);
-  exit:
-    vif_write_unlock(flags);
-    return err;
-}
-
-static void vif_table_timer_fn(unsigned long arg){
-    if(!vif_table) return;
-    vif_sweep();
-    timer_set(&vif_table_timer, VIF_TABLE_TTL);
-}
-    
-/** Initialize the vif table.
- *
- * @return 0 on success, error code otherwise
- */
-int vif_init(void){
-    int err = 0;
-    vif_table = HashTable_new(0);
-    if(!vif_table){
-        err = -ENOMEM;
-        goto exit;
-    }
-    vif_table->entry_free_fn = vif_entry_free_fn;
-    vif_table->key_size = sizeof(VifKey);
-    vif_table->key_hash_fn   = vif_key_hash_fn;
-    vif_table->key_equal_fn  = vif_key_equal_fn;
-
-    timer_init(&vif_table_timer, vif_table_timer_fn, 0);
-    timer_set(&vif_table_timer, VIF_TABLE_TTL);
-
-  exit:
-    if(err < 0){
-        eprintf("> vif_init err=%d\n", err);
-    }
-    return err;
-}
-
-void vif_exit(void){
-    timer_cancel(&vif_table_timer);
-    HashTable_free(vif_table);
-    vif_table = NULL;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vif.h
--- a/tools/vnet/vnet-module/vif.h      Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _VNET_VIF_H_
-#define _VNET_VIF_H_
-
-#ifdef __KERNEL__
-#include <asm/atomic.h>
-#else
-#include "spinlock.h"
-#endif
-
-#include <if_varp.h>
-struct IOStream;
-
-/** Key for entries in the vif table. */
-typedef struct VifKey {
-    struct VnetId vnet;
-    struct Vmac vmac;
-} VifKey;
-
-typedef struct Vif {
-    struct VnetId vnet;
-    struct Vmac vmac;
-    atomic_t refcount;
-    unsigned long timestamp;
-    int flags;
-} Vif;
-
-enum {
-    VIF_FLAG_PERSISTENT = 1,
-};
-
-extern void vif_print(struct IOStream *io);
-
-extern void vif_decref(struct Vif *vif);
-extern void vif_incref(struct Vif *vif);
-
-extern int vif_create(struct VnetId *vnet, struct Vmac *vmac, int flags, 
struct Vif **vif);
-extern int vif_lookup(struct VnetId *vnet, struct Vmac *vmac, struct Vif 
**vif);
-extern int vif_update(struct VnetId *vnet, struct Vmac *vmac);
-extern int vif_remove(struct VnetId *vnet, struct Vmac *vmac);
-extern void vif_purge(void);
-extern int vif_remove_vnet(struct VnetId *vnet);
-
-extern int vif_init(void);
-extern void vif_exit(void);
-
-#endif
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vnet.c
--- a/tools/vnet/vnet-module/vnet.c     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,699 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/version.h>
-#include <linux/errno.h>
-
-#include <linux/string.h>
-#include <linux/spinlock.h>
-
-#include <linux/net.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-
-#include <linux/etherdevice.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/route.h>
-#include <linux/skbuff.h>
-#include <net/checksum.h>
-
-
-#else 
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "sys_kernel.h"
-#include "spinlock.h"
-#include "skbuff.h"
-
-#include <linux/ip.h>  // For struct iphdr.
-
-extern int netif_rx(struct sk_buff *skb);
-
-#endif
-
-#include <tunnel.h>
-#include <sa.h>
-#include <varp.h>
-#include <if_varp.h>
-#include <esp.h>
-#include <etherip.h>
-#include <random.h>
-
-#include <skb_context.h>
-
-#include <skb_util.h>
-#include <vnet_dev.h>
-#include <vnet.h>
-#include <vnet_forward.h>
-#include <vif.h>
-#include <vnet_ioctl.h>
-#include <sa.h>
-#ifdef __KERNEL__
-#include <sa_algorithm.h>
-#endif
-
-#include "allocate.h"
-#include "iostream.h"
-#include "hash_table.h"
-#include "sys_net.h"
-#include "sys_string.h"
-
-#define MODULE_NAME "VNET"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** Default vnet security level.
- */
-int vnet_security_default = SA_AUTH ; //| SA_CONF;
-
-/** The physical vnet. */
-Vnet *vnet_physical = NULL;
-
-/** Table of vnets indexed by id. */
-HashTable *vnet_table = NULL;
-
-rwlock_t vnet_lock = RW_LOCK_UNLOCKED;
-
-#define vnet_table_read_lock(flags)    read_lock_irqsave(&vnet_lock, flags)
-#define vnet_table_read_unlock(flags)  read_unlock_irqrestore(&vnet_lock, 
flags)
-#define vnet_table_write_lock(flags)   write_lock_irqsave(&vnet_lock, flags)
-#define vnet_table_write_unlock(flags) write_unlock_irqrestore(&vnet_lock, 
flags)
-
-/** Decrement reference count, freeing if zero.
- *
- * @param info vnet (OK if null)
- */
-void Vnet_decref(Vnet *info){
-    if(!info) return;
-    if(atomic_dec_and_test(&info->refcount)){
-        deallocate(info);
-    }
-}
-
-/** Increment reference count.
- *
- * @param info vnet (OK if null)
- */
-void Vnet_incref(Vnet *info){
-    if(!info) return;
-    atomic_inc(&info->refcount);
-}
-
-void Vnet_print(Vnet *info, IOStream *io)
-{
-    char vnetbuf[VNET_ID_BUF];
-    char *security;
-
-    if(info->security & SA_CONF){
-        security = "conf";
-    } else if(info->security & SA_AUTH){
-        security = "auth";
-    } else {
-        security = "none";
-    }
-
-    IOStream_print(io, "(vnet");
-    IOStream_print(io, " (id %s)", VnetId_ntoa(&info->vnet, vnetbuf));
-    IOStream_print(io, " (vnetif %s)", info->device);
-    IOStream_print(io, " (security %s)", security);
-    IOStream_print(io, " (header %d)", info->header_n);
-    IOStream_print(io, ")");
-}
-
-void vnet_print(IOStream *io)
-{
-    HashTable_for_decl(entry);
-    Vnet *info;
-    unsigned long flags;
-    
-    vnet_table_read_lock(flags);
-    HashTable_for_each(entry, vnet_table){
-        info = entry->value;
-        Vnet_print(info, io);
-        IOStream_print(io, "\n");
-    }
-    vnet_table_read_unlock(flags);
-}
-
-/** Allocate a vnet, setting reference count to 1.
- *
- * @param info return parameter for vnet
- * @return 0 on success, error code otherwise
- */
-int Vnet_alloc(Vnet **info){
-    int err = 0;
-    *info = ALLOCATE(Vnet);
-    if(*info){
-        atomic_set(&(*info)->refcount, 1);
-    } else {
-        err = -ENOMEM;
-    }
-    return err;
-}
-
-/** Create the virtual interface for a vnet.
- *
- * @param info vnet
- * @return 0 on success, error code otherwise
- */
-int Vnet_create(Vnet *info){
-    int err = 0;
-
-    err = vnet_dev_add(info);
-    if(err) goto exit;
-    err = Vnet_add(info);
-  exit:
-    return err;
-}
-    
-/** Add a vnet to the table under its vnet id.
- *
- * @param info vnet to add
- * @return 0 on success, error code otherwise
- */
-int Vnet_add(Vnet *info){
-    int err = 0;
-    HTEntry *entry = NULL;
-    unsigned long flags;
-
-    if(Vnet_lookup(&info->vnet, NULL) == 0){
-        //todo: Delete existing vnet info?
-        err = -EEXIST;
-        goto exit;
-    }
-    Vnet_incref(info);
-    vnet_table_write_lock(flags);
-    entry = HashTable_add(vnet_table, &info->vnet, info);
-    vnet_table_write_unlock(flags);
-    if(!entry){
-        err = -ENOMEM;
-        vnet_dev_remove(info);
-        Vnet_decref(info);
-    }
-  exit:
-    return err;
-}
-
-/** Remove a vnet from the table.
- * Also removes all vifs and varp entries for the vnet.
- *
- * @param vnet id of vnet to remove
- * @return number of vnets removed
- */
-int Vnet_del(VnetId *vnet){
-    int count;
-    unsigned long flags;
-    Vnet *info;
-
-    vnet_table_write_lock(flags);
-    info = HashTable_get(vnet_table, vnet);
-    count = HashTable_remove(vnet_table, vnet);
-    vnet_table_write_unlock(flags);
-    
-    varp_remove_vnet(vnet);
-    vif_remove_vnet(vnet);
-
-    if(info){
-        // Can't do this in the hashtable entry free function because it runs
-        // while we hold the vnet table lock, and the vnet tidy up calls
-        // vnet_dev_remove(), which calls unregister_netdev(), which schedules.
-        vnet_dev_remove(info);
-        Vnet_decref(info);
-    }
-    return count;
-}
-
-/** Lookup a vnet by id.
- * References the vnet on success - the caller must decref.
- *
- * @param vnet vnet id
- * @param pinfo return parameter for vnet (or NULL)
- * @return 0 on sucess, -ENOENT if no vnet found
- */
-int Vnet_lookup(VnetId *vnet, Vnet **pinfo){
-    int err = 0;
-    unsigned long flags;
-    Vnet *info;
-
-    vnet_table_read_lock(flags);
-    info = HashTable_get(vnet_table, vnet);
-    if(info){
-        if(pinfo){
-            Vnet_incref(info);
-        }
-    } else {
-        err = -ENOENT;
-    }
-    vnet_table_read_unlock(flags);
-
-    if(pinfo){
-        *pinfo = (err ? NULL : info);
-    }
-    return err;
-}
-
-static int vnet_key_equal_fn(void *k1, void *k2){
-    return memcmp(k1, k2, sizeof(VnetId)) == 0;
-}
-
-static Hashcode vnet_key_hash_fn(void *k){
-    return hash_hvoid(0, k, sizeof(VnetId));
-}
-
-/** Free an entry in the vnet table.
- *
- * @param table containing table
- * @param entry to free
- */
-static void vnet_entry_free_fn(HashTable *table, HTEntry *entry){
-    if(!entry) return;
-    HTEntry_free(entry);
-}
-
-void vnet_table_free(void){
-    HashTable *vnt;
-    HashTable_for_decl(entry);
-
-    vnt = vnet_table;
-    if(!vnt) return;
-    vnet_table = NULL;
-    HashTable_for_each(entry, vnt){
-        Vnet *info = entry->value;
-        vnet_dev_remove(info);
-        Vnet_decref(info);
-    }
-    HashTable_free(vnt);
-}
-
-int vnet_table_init(void){
-    int err = 0;
-    vnet_table = HashTable_new(0);
-    if(!vnet_table){
-        err = -ENOMEM;
-        goto exit;
-    }
-    vnet_table->key_size = sizeof(VnetId);
-    vnet_table->key_equal_fn = vnet_key_equal_fn;
-    vnet_table->key_hash_fn = vnet_key_hash_fn;
-    vnet_table->entry_free_fn = vnet_entry_free_fn;
-
-    err = Vnet_alloc(&vnet_physical);
-    if(err) goto exit;
-    vnet_physical->vnet = toVnetId(VNET_PHYS);
-    vnet_physical->security = 0;
-    err = Vnet_add(vnet_physical);
-
-  exit:
-    if(err){
-        vnet_table_free();
-    }
-    return err;
-}
-
-/** Setup some vnet entries (for testing).
- * Vnet 1 is physical, vnets 2 to 10 are insecure, vnets above
- * 10 are secure.
- *
- * @return 0 on success, negative error code otherwise
- */
-static int vnet_setup(void){
-    int err = 0;
-    int i, n = 3;
-    int security = vnet_security_default;
-    uint32_t vnetid;
-    Vnet *vnet;
-
-    for(i=0; i<n; i++){
-        err = Vnet_alloc(&vnet);
-        if(err) break;
-        vnetid = VNET_VIF + i;
-        vnet->vnet = toVnetId(vnetid);
-        snprintf(vnet->device, sizeof(vnet->device), "vnif%04x", vnetid);
-        vnet->security = (vnetid > 10 ? security : 0);
-        err = Vnet_create(vnet);
-        Vnet_decref(vnet);
-        if(err) break;
-    }
-    return err;
-}
-
-/** Initialize the vnet table and the physical vnet.
- *
- * @return 0 on success, error code otherwise
- */
-int vnet_init(void){
-    int err = 0;
-
-    err = vnet_forward_init();
-    if(err) goto exit;
-    err = vnet_table_init();
-    if(err) goto exit;
-    err = vnet_setup();
-    if(err) goto exit;
-    err = vif_init();
-    if(err) goto exit;
-    err = varp_init();
-  exit:
-    return err;
-}
-
-void vnet_exit(void){
-    varp_exit();
-    vif_exit();
-    vnet_table_free();
-    vnet_forward_exit();
-}
-
-#ifdef __KERNEL__
-inline int _skb_xmit(struct sk_buff *skb, uint32_t saddr){
-    int err = 0;
-    struct rtable *rt = NULL;
-
-    dprintf("> src=%u.%u.%u.%u dst=%u.%u.%u.%u\n",
-            NIPQUAD(skb->nh.iph->saddr),
-            NIPQUAD(skb->nh.iph->daddr));
-    skb->protocol = htons(ETH_P_IP);
-    if(saddr){
-        skb->nh.iph->saddr = 0;
-    }
-    err = skb_route(skb, &rt);
-    if(err){
-        wprintf("> skb_route=%d\n", err);
-        wprintf("> dev=%s idx=%d src=%u.%u.%u.%u dst=%u.%u.%u.%u tos=%d\n",
-                (skb->dev ? skb->dev->name : "???"),
-                (skb->dev ? skb->dev->ifindex : -1),
-                NIPQUAD(skb->nh.iph->saddr),
-                NIPQUAD(skb->nh.iph->daddr),
-                skb->nh.iph->tos);
-                
-        goto exit;
-    }
-    dst_release(skb->dst);
-    skb->dst = &rt->u.dst;
-    if(!skb->dev){
-        skb->dev = rt->u.dst.dev;
-    }
-
-    ip_select_ident(skb->nh.iph, &rt->u.dst, NULL);
-
-    if(saddr){
-        skb->nh.iph->saddr = saddr;
-    } else {
-        if(!skb->nh.iph->saddr){
-            skb->nh.iph->saddr = rt->rt_src;
-        }
-    }
-
-    ip_send_check(skb->nh.iph);
-
-#if 1
-        // Output to skb destination. Will use ip_output(), which fragments.
-        // Slightly slower than neigh_compat_output() (marginal - 1%).
-        err = dst_output(skb); 
-#else
-        // Sends direct to device via dev_queue_xmit(). No fragmentation?
-        err = neigh_compat_output(skb);
-#endif
-
-#if 0
-    if(needs_frags){
-        err = ip_fragment(skb, ip_finish_output);
-    } else {
-        err = ip_finish_output(skb);
-    }
-#endif
-
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-#else 
-
-extern int _skb_xmit(struct sk_buff *skb, uint32_t saddr);
-
-#endif
-
-int skb_xmit(struct sk_buff *skb){
-    if(MULTICAST(skb->nh.iph->daddr)){
-        vnet_forward_send(skb);
-    }
-    return _skb_xmit(skb, 0);
-}
-
-/** Called when a vif sends a packet to the network.
- * Encapsulates the packet for its vnet and forwards it.
- *
- * @param skb packet
- * @return 0 on success, error code otherwise
- *
- */
-int vnet_skb_send(struct sk_buff *skb, VnetId *vnet){
-    VnetId vnet_phys = toVnetId(VNET_PHYS);
-    int err = 0;
-
-    //dprintf(">\n");
-    skb->dev = NULL;
-    if(!vnet || VnetId_eq(vnet, &vnet_phys)){
-        // No vnet or physical vnet, send direct to the network. 
-        skb_xmit(skb);
-    } else {
-        // Update the vif table with the source MAC.
-        vif_update(vnet, (Vmac*)eth_hdr(skb)->h_source);
-        err = varp_output(skb, vnet);
-    }
-    //dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Receive an skb for a vnet.
- * We make the skb come out of the vif for the vnet, and
- * let ethernet bridging forward it to related interfaces.
- *
- * The packet must have skb->mac.raw set and skb->data must point
- * after the device (ethernet) header.
- *
- * Return code 1 means we now own the packet - the caller must not free it.
- * Return code < 0 means an error - caller still owns the packet.
- *
- * @param skb packet
- * @param vnet packet vnet
- */
-int vnet_skb_recv(struct sk_buff *skb, Vnet *vnet){
-    int err = 1;
-
-    if(!vnet->dev){
-        // No device for the vnet.
-        err = -ENOTCONN;
-        goto exit;
-    }
-    skb->dev = vnet->dev;
-    vnet->stats.rx_packets++;
-    vnet->stats.rx_bytes += skb->len;
-    netif_rx(skb);
-  exit:
-    return err;
-}
-
-
-/** Check that a context has the correct properties w.r.t. a vnet.
- * The context must be secure if the vnet requires security.
- *
- * @param vnet vnet id
- * @param context context
- * @return 0 on success, error code otherwise
- *
- * @todo Need to check that the sa provides the correct security level.
- */
-int vnet_check_context(VnetId *vnet, SkbContext *context, Vnet **val){
-    int err = 0;
-    Vnet *info = NULL;
-    SAState *sa = NULL;
-    
-    err = Vnet_lookup(vnet, &info);
-    if(err){
-        goto exit;
-    }
-    if(!info->security) goto exit;
-    err = -EINVAL;
-    if(!context){
-        wprintf("> No security context\n");
-        goto exit;
-    }
-    if(context->protocol != IPPROTO_ESP){
-        wprintf("> Invalid protocol: wanted %d, got %d\n",
-                IPPROTO_ESP, context->protocol);
-        goto exit;
-    }
-    sa = context->data;
-    //todo: Check security properties of the SA are correct w.r.t. the vnet.
-    //Something like  sa->security == info->security;
-    err = 0;
-  exit:
-    *val = info;
-    return err;
-}
-
-
-/** Create a tunnel for a vnet to a given address.
- *
- * @param vnet vnet id
- * @param addr destination address
- * @param tunnel return parameter
- * @return 0 on success, error code otherwise
- */
-static int vnet_tunnel_create(VnetId *vnet, VarpAddr *addr, Tunnel **tunnel){
-    int err = 0;
-    Vnet *info = NULL;
-    Tunnel *base = NULL;
-    Tunnel *sa_tunnel = NULL;
-    Tunnel *eth_tunnel = NULL;
-
-    err = Vnet_lookup(vnet, &info);
-    if(err) goto exit;
-    if(info->security){
-        err = sa_tunnel_create(info, addr, base, &sa_tunnel);
-        if(err) goto exit;
-        base = sa_tunnel;
-    }
-    err = etherip_tunnel_create(vnet, addr, base, &eth_tunnel);
-  exit:
-    Tunnel_decref(sa_tunnel);
-    Vnet_decref(info);
-    *tunnel = (err ? NULL : eth_tunnel);
-    return err;
-}
-
-/** Lookup a tunnel for a vnet to a given address.
- * Uses an existing tunnel if there is one.
- *
- * @param vnet vnet id
- * @param addr care-of address
- * @param tunnel return parameter
- * @return 0 on success, error code otherwise
- */
-int vnet_tunnel_lookup(VnetId *vnet, VarpAddr *addr, Tunnel **tunnel){
-    int err = 0;
-    err = Tunnel_lookup(vnet, addr, tunnel);
-    if(err){
-        err = Tunnel_open(vnet, addr, vnet_tunnel_create, tunnel);
-    }
-    return err;
-}
-
-/** Send a packet on the appropriate tunnel.
- *
- * @param vnet vnet
- * @param addr tunnel endpoint
- * @param skb packet
- * @return 0 on success, error code otherwise
- */
-int vnet_tunnel_send(VnetId *vnet, VarpAddr *addr, struct sk_buff *skb){
-    int err = 0;
-    Tunnel *tunnel = NULL;
-
-    err = vnet_tunnel_lookup(vnet, addr, &tunnel);
-    if(err) {
-        char vnetbuf[VNET_ID_BUF];
-        char addrbuf[VARP_ADDR_BUF];
-        wprintf("No tunnel: skb=%p vnet=%s addr=%s\n",
-                skb,
-                VnetId_ntoa(vnet, vnetbuf),
-                VarpAddr_ntoa(addr, addrbuf));
-        goto exit;
-    }
-    err = Tunnel_send(tunnel, skb);
-    Tunnel_decref(tunnel);
-  exit:
-    return err;
-}
-
-#ifdef __KERNEL__
-
-/** Module parameter for vnet encapsulation. */
-static char *vnet_encaps = NULL;
-
-static void __exit vnet_module_exit(void){
-    ProcFS_exit();
-    sa_table_exit();
-    vnet_exit();
-    esp_module_exit();
-    etherip_module_exit();
-    tunnel_module_exit();
-    random_module_exit();
-}
-
-/** Initialize the vnet module.
- * Failure is fatal.
- *
- * @return 0 on success, error code otherwise
- */
-static int __init vnet_module_init(void){
-    int err = 0;
-
-    if(vnet_encaps && !strcmp(vnet_encaps, "udp")){
-        etherip_in_udp = 1;
-    }
-    dprintf(">\n");
-    err = random_module_init();
-    if(err) wprintf("> random_module_init err=%d\n", err);
-    if(err) goto exit;
-    err = tunnel_module_init();
-    if(err) wprintf("> tunnel_module_init err=%d\n", err);
-    if(err) goto exit;
-    err = etherip_module_init();
-    if(err) wprintf("> etherip_module_init err=%d\n", err);
-    if(err) goto exit;
-    err = esp_module_init();
-    if(err) wprintf("> esp_module_init err=%d\n", err);
-    if(err) goto exit;
-    err = vnet_init();
-    if(err) wprintf("> vnet_init err=%d\n", err);
-    if(err) goto exit;
-    sa_algorithm_probe_all();
-    err = sa_table_init();
-    if(err) wprintf("> sa_table_init err=%d\n", err);
-    if(err) goto exit;
-    ProcFS_init();
-  exit:
-    if(err < 0){
-        vnet_module_exit();
-        wprintf("< err=%d\n", err);
-    }
-    return err;
-}
-
-module_init(vnet_module_init);
-module_exit(vnet_module_exit);
-MODULE_LICENSE("GPL");
-
-module_param(vnet_encaps, charp, 0644);
-MODULE_PARM_DESC(vnet_encaps, "Vnet encapsulation: etherip or udp.");
-
-#endif
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vnet.h
--- a/tools/vnet/vnet-module/vnet.h     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef __VNET_VNET_H__
-#define __VNET_VNET_H__
-
-#ifdef __KERNEL__
-
-#include <asm/atomic.h>
-#include <linux/skbuff.h>
-#include <linux/if.h>
-#include <linux/netdevice.h>
-
-#else
-
-#include <linux/netdevice.h> // struct net_device_stats
-
-struct net_device {
-    char name[IFNAMSIZ];
-    char tap[255];
-    int  tapfd;
-};
-
-#endif
-
-#include <if_varp.h>
-
-struct sk_buff;
-
-struct IOStream;
-struct Vmac;
-struct Vif;
-struct SkbContext;
-struct VarpAddr;
-struct Tunnel;
-struct SAState;
-
-/** Vnet property record. */
-typedef struct Vnet {
-    /** Vnet id. */
-    struct VnetId vnet;
-    /** Reference count. */
-    atomic_t refcount;
-    /** Security flag. If true the vnet requires ESP. */
-    int security;
-    char device[IFNAMSIZ];
-
-    struct net_device *dev;
-    
-    /** Max size of the header. */
-    int header_n;
-    int mtu;
-    /** Statistics. */
-    struct net_device_stats stats;
-    int recursion;
-} Vnet;
-
-extern void vnet_print(struct IOStream *io);
-extern void Vnet_print(struct Vnet *info, struct IOStream *io);
-
-extern int Vnet_lookup(struct VnetId *vnet, struct Vnet **info);
-extern int Vnet_create(struct Vnet *info);
-extern int Vnet_add(struct Vnet *info);
-extern int Vnet_del(struct VnetId *vnet);
-extern void Vnet_incref(struct Vnet *info);
-extern void Vnet_decref(struct Vnet *info);
-extern int Vnet_alloc(struct Vnet **info);
-extern struct Vnet *vnet_physical;
-
-extern int skb_xmit(struct sk_buff *skb);
-extern int skb_xmit_fwd(struct sk_buff *skb);
-extern int vnet_skb_send(struct sk_buff *skb, struct VnetId *vnet);
-extern int vnet_skb_recv(struct sk_buff *skb, struct Vnet *vnet);
-
-extern int vnet_check_context(struct VnetId *vnet, struct SkbContext *context, 
struct Vnet **vinfo);
-
-extern int vnet_tunnel_open(struct VnetId *vnet, struct VarpAddr *addr, struct 
Tunnel **tunnel);
-extern int vnet_tunnel_lookup(struct VnetId *vnet, struct VarpAddr *addr, 
struct Tunnel **tunnel);
-extern int vnet_tunnel_send(struct VnetId *vnet, struct VarpAddr *addr, struct 
sk_buff *skb);
-
-extern int vnet_init(void);
-
-extern int vnet_sa_security(u32 spi, int protocol, u32 addr);
-extern int vnet_sa_create(u32 spi, int protocol, u32 addr, struct SAState 
**sa);
-
-enum {
-    VNET_PHYS = 1,
-    VNET_VIF = 2,
-};
-
-extern struct HashTable *vnet_table;
-
-#endif /* !__VNET_VNET_H__ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vnet_dev.c
--- a/tools/vnet/vnet-module/vnet_dev.c Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,296 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/in.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-
-#include <net/ip.h>
-#include <net/protocol.h>
-
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/inetdevice.h>
-#include <linux/arcdevice.h>
-#include <linux/if_bridge.h>
-
-#include <etherip.h>
-#include <vnet.h>
-#include <varp.h>
-#include <vif.h>
-#include <vnet_dev.h>
-#include <random.h>
-
-#define MODULE_NAME "VNET"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-#if !defined(CONFIG_BRIDGE) && !defined(CONFIG_BRIDGE_MODULE)
-#warning Should configure Ethernet Bridging in kernel Network Options
-#endif
-
-#ifndef CONFIG_BRIDGE_NETFILTER
-#warning Should configure CONFIG_BRIDGE_NETFILTER in kernel
-#endif
-
-static void vnet_dev_destructor(struct net_device *dev){
-    Vnet *vnet = dev->priv;
-    if(vnet){
-        if(vnet->dev == dev){
-            vnet->dev = NULL;
-        }
-        dev->priv = NULL;
-        Vnet_decref(vnet);
-    }
-    free_netdev(dev);
-}
-
-static struct net_device_stats *vnet_dev_get_stats(struct net_device *dev){
-    static struct net_device_stats stats = {};
-    Vnet *vnet = dev->priv;
-    return (vnet ? &vnet->stats : &stats);
-}
-
-static int vnet_dev_change_mtu(struct net_device *dev, int mtu){
-    int err = 0;
-    Vnet *vnet = dev->priv;
-    if (mtu < 68 || mtu > (vnet ? vnet->mtu : 1500)){
-        err = -EINVAL;
-        goto exit;
-    }
-    dev->mtu = mtu;
-  exit:
-    return err;
-}
-
-/** Remove the net device for a vnet.
- * Safe to call if the vnet or its dev are null.
- *
- * @param vnet vnet
- */
-void vnet_dev_remove(Vnet *vnet){
-    if(vnet && vnet->dev){
-        iprintf("> Removing vnet device %s\n", vnet->dev->name);
-        unregister_netdev(vnet->dev);
-    }
-}
-
-static int vnet_dev_open(struct net_device *dev){
-    int err = 0;
-
-    netif_start_queue(dev);
-    return err;
-}
-
-static int vnet_dev_stop(struct net_device *dev){
-    int err = 0;
-
-    netif_stop_queue(dev);
-    return err;
-}
-
-static int vnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device 
*dev){
-    int err = 0;
-    Vnet *vnet = dev->priv;
-    int len = 0;
-
-    if(!skb){
-        wprintf("> skb NULL!\n");
-        return -EINVAL;
-    }
-    if(!vnet){
-        return -ENOTCONN;
-    }
-    if(vnet->recursion++) {
-        extern void print_skb(const char *msg, int count, struct sk_buff *skb);
-        char vnetbuf[VNET_ID_BUF];
-        
-        vnet->stats.collisions++;
-       vnet->stats.tx_errors++;
-        wprintf("> recursion! vnet=%s\n", VnetId_ntoa(&vnet->vnet, vnetbuf));
-        print_skb("RECURSION", 0, skb);
-        varp_print(iostdout);
-       kfree_skb(skb);
-        goto exit;
-    }
-    if(!skb->mac.raw){
-        skb->mac.raw = skb->data;
-    }        
-    len = skb->len;
-    // Must not use skb pointer after vnet_skb_send().
-    err = vnet_skb_send(skb, &vnet->vnet);
-    if(err < 0){
-        vnet->stats.tx_errors++;
-    } else {
-        vnet->stats.tx_packets++;
-        vnet->stats.tx_bytes += len;
-    }
-  exit:
-    vnet->recursion--;
-    return 0;
-}
-
-void vnet_dev_set_multicast_list(struct net_device *dev){
-}
-
-#if 0
-static int vnet_dev_do_ioctl(struct net_device *dev, struct ifreq *ifr, int 
cmd){
-    int err = 0;
-    
-    return err;
-}
-
-void vnet_dev_tx_timeout(struct net_device *dev){
-    //dev->trans_start = jiffies;
-    //netif_wake_queue(dev);
-}
-
-static int (*eth_hard_header)(struct sk_buff *skb,
-                              struct net_device *dev, unsigned short type,
-                              void *daddr, void *saddr, unsigned len) = NULL;
-
-static int vnet_dev_hard_header(struct sk_buff *skb,
-                                struct net_device *dev, unsigned short type,
-                                void *daddr, void *saddr, unsigned len){
-    int err = 0;
-
-    err = eth_hard_header(skb, dev, type, daddr, saddr, len);
-    if(err) goto exit;
-    skb->mac.raw = skb->data;
-  exit:
-    return err;
-}
-#endif
-
-int vnet_device_mac(const char *device, unsigned char *mac){
-    int err;
-    struct net_device *dev;
-
-    err = vnet_get_device(device, &dev);
-    if(err) goto exit;
-    memcpy(mac, dev->dev_addr, ETH_ALEN);
-    dev_put(dev);
-  exit:
-    return err;
-}
-
-void vnet_dev_mac(unsigned char *mac){
-    mac[0] = 0xAA;
-    mac[1] = 0xFF;
-    get_random_bytes(mac + 2, 4);
-}
-
-/** Initial setup of the device for a vnet.
- */
-static void vnet_dev_init(struct net_device *dev){
-    ether_setup(dev);
-
-#if 0
-    if(!eth_hard_header){
-        eth_hard_header = dev->hard_header;
-    }
-    dev->hard_header          = vnet_dev_hard_header;
-    //dev->do_ioctl             = vnet_dev_do_ioctl;
-    //dev->tx_timeout           = vnet_dev_tx_timeout;
-    //dev->watchdog_timeo       = TX_TIMEOUT;
-    
-#endif
-
-    dev->open                 = vnet_dev_open;
-    dev->stop                 = vnet_dev_stop;
-    dev->destructor           = vnet_dev_destructor;
-    dev->hard_start_xmit      = vnet_dev_hard_start_xmit;
-    dev->get_stats            = vnet_dev_get_stats;
-    dev->change_mtu           = vnet_dev_change_mtu;
-    dev->set_multicast_list   = vnet_dev_set_multicast_list;
-
-    dev->flags |= IFF_DEBUG;
-    dev->flags |= IFF_PROMISC;
-    dev->flags |= IFF_ALLMULTI;
-
-    vnet_dev_mac(dev->dev_addr);
-}
-
-/** Complete the setup of the device for a vnet.
- * Associate the device and the vnet and set mtu etc.
- */
-static int vnet_dev_setup(Vnet *vnet, struct net_device *dev){
-    int err;
-
-    Vnet_incref(vnet);
-    dev->priv = vnet;
-    vnet->dev = dev;
-    dev->hard_header_len += vnet->header_n;
-    if(!etherip_in_udp){
-        dev->mtu -= vnet->header_n;
-    }
-    vnet->mtu = dev->mtu;
-    iprintf("> Adding vnet device %s\n", dev->name);
-    err = register_netdev(dev);
-    if(err){
-        eprintf("> register_netdev(%s) = %d\n", dev->name, err);
-        vnet_dev_destructor(dev);
-    }
-    return err;
-}
-
-static inline int roundupto(int n, int k){
-    return k * ((n + k - 1) / k);
-}
-
-/** Add the interface (net device) for a vnet.
- * Sets the dev field of the vnet on success.
- * Does nothing if the vnet already has an interface.
- *
- * @param vnet vnet
- * @return 0 on success, error code otherwise
- */
-int vnet_dev_add(Vnet *vnet){
-    int err = 0;
-    struct net_device *dev = NULL;
-
-    if(vnet->dev) goto exit;
-    vnet->header_n = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct 
etheriphdr);
-    if(etherip_in_udp){
-        vnet->header_n += sizeof(struct VnetMsgHdr);
-        vnet->header_n += sizeof(struct udphdr);
-    }
-    vnet->header_n = roundupto(vnet->header_n, 4);
-    dev = alloc_netdev(0, vnet->device, vnet_dev_init);
-    if(!dev){
-        err = -ENOMEM;
-        goto exit;
-    }
-    err = vnet_dev_setup(vnet, dev);
-    if(err) goto exit;
-    rtnl_lock();
-    dev_open(dev);
-    rtnl_unlock();
-
-  exit:
-    return err;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vnet_dev.h
--- a/tools/vnet/vnet-module/vnet_dev.h Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _VNET_VNET_DEV_H_
-#define _VNET_VNET_DEV_H_
-
-struct Vnet;
-
-extern int vnet_dev_add(struct Vnet *vnet);
-extern void vnet_dev_remove(struct Vnet *vnet);
-
-#endif
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vnet_eval.c
--- a/tools/vnet/vnet-module/vnet_eval.c        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/version.h>
-#include <linux/errno.h>
-
-#else 
-
-#include "sys_kernel.h"
-#include "spinlock.h"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#endif
-
-#include "vnet.h"
-#include "varp.h"
-#include "vif.h"
-#include "vnet_forward.h"
-#include "sa.h"
-
-#include "iostream.h"
-
-#ifdef __KERNEL__
-#include "kernel_stream.h"
-#else
-#include "file_stream.h"
-#endif
-
-#include "sxpr_util.h"
-#include "vnet_eval.h"
-
-#define MODULE_NAME "VNET"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** Create a vnet.
- * It is an error if a vnet with the same id exists.
- *
- * @param vnet vnet id
- * @param device vnet device name
- * @param security security level
- * @return 0 on success, error code otherwise
- */
-static int ctrl_vnet_add(VnetId *vnet, char *device, int security){
-    int err = 0;
-    Vnet *vnetinfo = NULL;
-
-    if(strlen(device) >= IFNAMSIZ){
-        err = -EINVAL;
-        goto exit;
-    }
-    if(Vnet_lookup(vnet, NULL) == 0){
-        err = -EEXIST;
-        goto exit;
-    }
-    err = Vnet_alloc(&vnetinfo);
-    if(err) goto exit;
-    vnetinfo->vnet = *vnet;
-    vnetinfo->security = security;
-    strcpy(vnetinfo->device, device);
-    err = Vnet_create(vnetinfo);
-  exit:
-    if(vnetinfo) Vnet_decref(vnetinfo);
-    return err;
-}
-
-/** Create an entry for a vif with the given vnet and vmac.
- *
- * @param vnet vnet id
- * @param vmac mac address
- * @return 0 on success, error code otherwise
- */
-static int ctrl_vif_add(VnetId *vnet, Vmac *vmac){
-    int err = 0;
-    Vif *vif = NULL;
-
-    err = Vnet_lookup(vnet, NULL);
-    if(err) goto exit;
-    err = vif_create(vnet, vmac, 0, &vif);
-  exit:
-    if(vif) vif_decref(vif);
-    return err;
-}
-
-/** Delete a vif.
- *
- * @param vnet vnet id
- * @param vmac mac address
- * @return 0 on success, error code otherwise
- */
-static int ctrl_vif_del(VnetId *vnet, Vmac *vmac){
-    int err = 0;
-    Vif *vif = NULL;
-
-    err = Vnet_lookup(vnet, NULL);
-    if(err) goto exit;
-    err = vif_lookup(vnet, vmac, &vif);
-    if(err) goto exit;
-    vif_remove(vnet, vmac);
-  exit:
-    if(vif) vif_decref(vif);
-    return err;
-}
-
-/** (varp.print)
- */
-static int eval_varp_print(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    vnet_print(out);
-    vif_print(out);
-    varp_print(out);
-    return err;
-}
-
-static int eval_varp_list(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    varp_print(out);
-    return err;
-}
-
-/** (varp.mcaddr (addr <addr>))
- */
-static int eval_varp_mcaddr(Sxpr exp, IOStream *out, void *data){
-    int err =0;
-    Sxpr oaddr = intern("addr");
-    uint32_t addr;
-
-    err = child_addr(exp, oaddr, &addr);
-    if(err < 0) goto exit;
-    varp_set_mcast_addr(addr);
-  exit:
-    return err;
-}
-
-/** (varp.flush)
- */
-static int eval_varp_flush(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    varp_flush();
-    return err;
-}
-
-/** (vnet.add (id <id>)
- *            [(vnetif <name>)]
- *            [(security { none | auth | conf } )]
- *  )
- */
-int eval_vnet_add(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    Sxpr oid = intern("id");
-    Sxpr osecurity = intern("security");
-    Sxpr ovnetif = intern("vnetif");
-    Sxpr csecurity;
-    VnetId vnet = {};
-    char *device = NULL;
-    char dev[IFNAMSIZ] = {};
-    char *security = NULL;
-    int sec;
-
-    err = child_vnet(exp, oid, &vnet);
-    if(err) goto exit;
-    child_string(exp, ovnetif, &device);
-    if(!device){
-        snprintf(dev, IFNAMSIZ-1, "vnif%04x", 
ntohs(vnet.u.vnet16[VNETID_SIZE16 - 1]));
-        device = dev;
-    }
-    csecurity = sxpr_child_value(exp, osecurity, intern("none"));
-    err = stringof(csecurity, &security);
-    if(err) goto exit;
-    if(strcmp(security, "none")==0){
-        sec = 0;
-    } else if(strcmp(security, "auth")==0){
-        sec = SA_AUTH;
-    } else if(strcmp(security, "conf")==0){
-        sec = SA_CONF;
-    } else {
-        err = -EINVAL;
-        goto exit;
-    }
-    err = ctrl_vnet_add(&vnet, device, sec);
- exit:
-    return err;
-}
-
-/** Delete a vnet.
- *
- * (vnet.del (id <id>))
- *
- * @param vnet vnet id
- * @return 0 on success, error code otherwise
- */
-static int eval_vnet_del(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    Sxpr oid = intern("id");
-    VnetId vnet = {};
-
-    err = child_vnet(exp, oid, &vnet);
-    if(err) goto exit;
-    err = Vnet_del(&vnet);
-  exit:
-    return err;
-}
-
-static int eval_vnet_list(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    vnet_print(out);
-    return err;
-}
-
-/** (vif.add (vnet <vnet>) (vmac <macaddr>))
- */
-static int eval_vif_add(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    Sxpr ovnet = intern("vnet");
-    Sxpr ovmac = intern("vmac");
-    VnetId vnet = {};
-    Vmac vmac = {};
-
-    err = child_vnet(exp, ovnet, &vnet);
-    if(err) goto exit;
-    err = child_mac(exp, ovmac, vmac.mac);
-    if(err) goto exit;
-    err = ctrl_vif_add(&vnet, &vmac);
-  exit:
-    return err;
-}
-
-/** (vif.del (vnet <vnet>) (vmac <macaddr>))
- */
-static int eval_vif_del(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    Sxpr ovnet = intern("vnet");
-    Sxpr ovmac = intern("vmac");
-    VnetId vnet = {};
-    Vmac vmac = {};
-
-    err = child_vnet(exp, ovnet, &vnet);
-    if(err) goto exit;
-    err = child_mac(exp, ovmac, vmac.mac);
-    if(err) goto exit;
-    err = ctrl_vif_del(&vnet, &vmac);
-  exit:
-    return err;
-}
-
-static int eval_vif_list(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    vif_print(out);
-    return err;
-}
-
-/** Eval a vnet add request.
- *
- * (peer.add (addr <addr>) [(port <port>)])
- *
- * @param exp request
- * @param out output stream
- * @param data data
- * @return 0 on success, error code otherwise
- */
-int eval_peer_add(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    Sxpr oaddr = intern("addr");
-    Sxpr oport = intern("port");
-    VarpAddr addr = { .family = AF_INET };
-    int port;
-
-    err = child_addr(exp, oaddr, &addr.u.ip4.s_addr);
-    if(err < 0) goto exit;
-    err = child_int(exp, oport, &port);
-    if(err < 0){
-        err = 0;
-        port = varp_port;
-    }
-    if(err) goto exit;
-    err = vnet_peer_add(&addr, port);
-  exit:
-    return err;
-}
-
-/** Eval a peer delete request.
- *
- * (peer.del (addr <addr>))
- *
- * @param vnetd vnetd
- * @param exp request
- * @param out output stream
- * @param data data
- * @return 0 on success, error code otherwise
- */
-static int eval_peer_del(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    Sxpr oaddr = intern("addr");
-    VarpAddr addr = { .family = AF_INET };
-
-    err = child_addr(exp, oaddr, &addr.u.ip4.s_addr);
-    if(err < 0) goto exit;
-    err = vnet_peer_del(&addr);
-  exit:
-    return err;
-}
-
-/** Eval a peer list request.
- *
- * (peer.list)
- *
- * @param exp request
- * @param out output stream
- * @param data data
- * @return 0 on success, error code otherwise
- */
-static int eval_peer_list(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    vnet_peer_print(out);
-    return err;
-}
-
-int vnet_eval_defs(SxprEval *defs, Sxpr exp, IOStream *io, void *data){
-    int err = 0;
-    SxprEval *def;
-
-    iprintf("> "); objprint(iostdout, exp, 0); IOStream_print(iostdout, "\n");
-    err = -ENOSYS;
-    for(def = defs; !NONEP(def->name); def++){
-        if(sxpr_elementp(exp, def->name)){
-            err = def->fn(exp, io, data);
-            break;
-        }
-    }
-    iprintf("< err=%d\n", err);
-    return err;
-}
-
-int vnet_eval(Sxpr exp, IOStream *io, void *data){
-    SxprEval defs[] = {
-        { .name = intern("peer.add"),     .fn = eval_peer_add     },
-        { .name = intern("peer.del"),     .fn = eval_peer_del     },
-        { .name = intern("peer.list"),    .fn = eval_peer_list    },
-        { .name = intern("varp.flush"),   .fn = eval_varp_flush   },
-        { .name = intern("varp.list"),    .fn = eval_varp_list    },
-        { .name = intern("varp.mcaddr"),  .fn = eval_varp_mcaddr  },
-        { .name = intern("varp.print"),   .fn = eval_varp_print   },
-        { .name = intern("vif.add"),      .fn = eval_vif_add      },
-        { .name = intern("vif.del"),      .fn = eval_vif_del      },
-        { .name = intern("vif.list"),     .fn = eval_vif_list     },
-        { .name = intern("vnet.add"),     .fn = eval_vnet_add     },
-        { .name = intern("vnet.del"),     .fn = eval_vnet_del     },
-        { .name = intern("vnet.list"),    .fn = eval_vnet_list    },
-        { .name = ONONE, .fn = NULL } };
-    return vnet_eval_defs(defs, exp, io, data);
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vnet_eval.h
--- a/tools/vnet/vnet-module/vnet_eval.h        Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _VNET_EVAL_H_
-#define _VNET_EVAL_H_
-
-#include "sxpr.h"
-struct IOStream;
-
-typedef struct SxprEval {
-    Sxpr name;
-    int (*fn)(Sxpr, struct IOStream *, void *data);
-} SxprEval;
-
-extern int eval_peer_add(Sxpr exp, struct IOStream *out, void *data);
-extern int eval_vnet_add(Sxpr exp, struct IOStream *out, void *data);
-extern int vnet_eval_defs(SxprEval *defs, Sxpr exp, struct IOStream *out, void 
*data);
-extern int vnet_eval(Sxpr exp, struct IOStream *out, void *data);
-
-#endif /* ! _VNET_EVAL_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vnet_forward.c
--- a/tools/vnet/vnet-module/vnet_forward.c     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2005, 2006 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <linux/version.h>
-#include <linux/spinlock.h>
-
-#include <linux/skbuff.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netfilter_bridge.h>
-#include <linux/netfilter_ipv4.h>
-#include <linux/udp.h>
-
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/route.h>
-#include <net/checksum.h>
-
-#else
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "sys_kernel.h"
-#include "spinlock.h"
-#include "skbuff.h"
-#include <linux/ip.h>
-#include <linux/udp.h>
-
-#endif
-
-#include <varp.h>
-#include <if_varp.h>
-#include <varp.h>
-#include <skb_util.h>
-#include <skb_context.h>
-
-#include "allocate.h"
-#include "iostream.h"
-#include "hash_table.h"
-#include "vnet_forward.h"
-
-#define MODULE_NAME "VNET"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-extern int _skb_xmit(struct sk_buff *skb, uint32_t saddr);
-
-typedef struct VnetPeer {
-    struct VarpAddr addr;
-    uint16_t port;
-    atomic_t refcount;
-    int tx_packets;
-    int rx_packets;
-} VnetPeer;
-
-static HashTable *vnet_peer_table = NULL;
-static rwlock_t vnet_peer_table_lock = RW_LOCK_UNLOCKED;
-
-#define vnet_peer_read_lock(flags)    read_lock_irqsave(&vnet_peer_table_lock, 
(flags))
-#define vnet_peer_read_unlock(flags)  
read_unlock_irqrestore(&vnet_peer_table_lock, (flags))
-#define vnet_peer_write_lock(flags)   
write_lock_irqsave(&vnet_peer_table_lock, (flags))
-#define vnet_peer_write_unlock(flags) 
write_unlock_irqrestore(&vnet_peer_table_lock, (flags))
-
-static void VnetPeer_decref(VnetPeer *peer){
-    if(!peer) return;
-    if(atomic_dec_and_test(&peer->refcount)){
-        kfree(peer);
-    }
-}
-
-static void VnetPeer_incref(VnetPeer *peer){
-    if(!peer) return;
-    atomic_inc(&peer->refcount);
-}
-
-static void VnetPeer_print(VnetPeer *peer, IOStream *io){
-    char addrbuf[VARP_ADDR_BUF];
-    
-    IOStream_print(io, "(vnet_peer\n");
-    IOStream_print(io, "  (addr %s)\n", VarpAddr_ntoa(&peer->addr, addrbuf));
-    IOStream_print(io, "  (port %d)\n", htons(peer->port));
-    IOStream_print(io, "  (tx_packets %d)\n", peer->tx_packets);
-    IOStream_print(io, "  (rx_packets %d)\n", peer->tx_packets);
-    IOStream_print(io, ")\n");
-}
-
-static int VnetPeer_forward(VnetPeer *peer, struct sk_buff *fwdskb){
-    int err = 0;
-    const int ip_n = sizeof(struct iphdr);
-    const int udp_n = sizeof(struct udphdr);
-    const int vnet_n = sizeof(struct VnetMsgHdr);
-    int head_n = 16 + ip_n + udp_n + vnet_n;
-    int push_n = 0;
-    struct sk_buff *skb = NULL;
-    struct VnetMsgHdr *vhdr;
-    uint32_t saddr = 0;
-    uint16_t sport = varp_port;
-    uint32_t daddr = peer->addr.u.ip4.s_addr;
-    uint16_t dport = varp_port;
-
-    if(!fwdskb) goto exit;
-    if(daddr == fwdskb->nh.iph->saddr){
-        // Don't forward if the skb src addr is the peer addr.
-        dprintf("> Forward loop on " IPFMT "\n", NIPQUAD(daddr));
-        goto exit;
-    }
-    // On entry fwdskb->data should be at fwdskb->nh.raw (adjust if not).
-    // Also fwdskb->h.raw and fwdskb->nh.raw are set.
-    if(fwdskb->data > fwdskb->nh.raw){
-        push_n = fwdskb->data - fwdskb->nh.raw;
-        head_n += push_n;
-    }
-    // If has headroom, copies header (which incs ref on dst),
-    // otherwise only clones header, which does not inc ref on dst.
-    skb = skb_realloc_headroom(fwdskb, head_n);
-    //skb = skb_copy_expand(fwdskb, head_n, 0, GFP_ATOMIC);
-    if(!skb){
-        err = -ENOMEM;
-        goto exit;
-    }
-
-    if(push_n){
-        skb_push(skb, push_n);
-    }
-
-#ifdef DEBUG
-    printk("\nOriginal packet:\n");
-    print_iphdr(__FUNCTION__, skb);
-    skb_print_bits(__FUNCTION__, skb, 0, skb->len);
-#endif
-
-    skb->mac.raw = NULL;
-    vhdr = (void*)skb_push(skb, vnet_n);
-    vhdr->id       = htons(VFWD_ID);
-    vhdr->opcode   = 0;
-
-    // Setup the UDP header.
-    skb->h.raw = skb_push(skb, udp_n);
-    skb->h.uh->source = sport;                 // Source port.
-    skb->h.uh->dest   = dport;                 // Destination port.
-    skb->h.uh->len    = htons(skb->len);       // Total packet length (bytes).
-    skb->h.uh->check  = 0;
-
-    // Setup the IP header.
-    skb->nh.raw = skb_push(skb, ip_n); 
-    skb->nh.iph->version  = 4;                 // Standard version.
-    skb->nh.iph->ihl      = ip_n / 4;          // IP header length (32-bit 
words).
-    skb->nh.iph->tos      = 0;                 // No special type-of-service.
-    skb->nh.iph->tot_len  = htons(skb->len);    // Total packet length (bytes).
-    skb->nh.iph->id       = 0;                 // No flow id.
-    skb->nh.iph->protocol = IPPROTO_UDP;        // IP protocol number.
-    skb->nh.iph->frag_off = 0;
-    skb->nh.iph->ttl      = 64;                        // Linux default 
time-to-live.
-    skb->nh.iph->saddr    = saddr;             // Source address.
-    skb->nh.iph->daddr    = daddr;              // Destination address.
-    skb->nh.iph->check    = 0;
-
-#ifdef DEBUG
-    printk("\nWrapped packet:\n");
-    print_iphdr(__FUNCTION__, skb);
-    print_udphdr(__FUNCTION__, skb);
-    skb_print_bits(__FUNCTION__, skb, 0, skb->len);
-#endif
-
-    err = _skb_xmit(skb, saddr);
-    peer->tx_packets++;
-
-  exit:
-    if(err < 0) kfree_skb(skb);
-    return err;
-}
-
-int vnet_peer_get(VarpAddr *addr, VnetPeer **peer){
-    unsigned long flags;
-
-    vnet_peer_read_lock(flags);
-    *peer = HashTable_get(vnet_peer_table, addr);
-    VnetPeer_incref(*peer);
-    vnet_peer_read_unlock(flags);
-    return (*peer ? 0 : -ENOENT);
-}
-
-int vnet_peer_add(VarpAddr *addr, uint16_t port){
-    int err = 0;
-    unsigned long flags;
-    VnetPeer *peer;
-    
-    vnet_peer_write_lock(flags);
-    peer = HashTable_get(vnet_peer_table, addr);
-    if(peer){
-        VnetPeer_incref(peer);
-        goto exit;
-    }
-    peer = ALLOCATE(VnetPeer);
-    if(!peer){
-        err = -ENOMEM;
-        goto exit;
-    }
-    peer->addr = *addr;
-    peer->port = port;
-    VnetPeer_incref(peer);
-    if(!HashTable_add(vnet_peer_table, &peer->addr, peer)){
-        VnetPeer_decref(peer);
-        err = -ENOMEM;
-    }
-  exit:
-    vnet_peer_write_unlock(flags);
-    return err;
-}
-
-int vnet_peer_del(VarpAddr *addr){
-    int ret = 0;
-    unsigned long flags;
-
-    vnet_peer_write_lock(flags);
-    ret = HashTable_remove(vnet_peer_table, addr);
-    vnet_peer_write_unlock(flags);
-    return ret;
-}
-
-void vnet_peer_print(IOStream *io){
-    HashTable_for_decl(entry);
-    unsigned long flags;
-
-    if(!vnet_peer_table) return;
-    vnet_peer_read_lock(flags);
-    HashTable_for_each(entry, vnet_peer_table){
-        VnetPeer *peer = entry->value;
-        VnetPeer_print(peer, io);
-    }
-    vnet_peer_read_unlock(flags);
-}
-
-int vnet_forward_send(struct sk_buff *skb){
-    int err = 0;
-    unsigned long flags;
-    HashTable_for_decl(entry);
-    int count = 0;
-
-    if(!vnet_peer_table){
-        goto exit;
-    }
-    vnet_peer_read_lock(flags);
-    HashTable_for_each(entry, vnet_peer_table){
-        VnetPeer *peer = entry->value;
-        VnetPeer_forward(peer, skb);
-        count++;
-    }
-    vnet_peer_read_unlock(flags);
-  exit:
-    return err;
-}
-
-int vnet_forward_recv(struct sk_buff *skb){
-    int err = 0;
-    VarpAddr addr = { .family = AF_INET };
-    VnetPeer *peer = NULL;
-    unsigned char eth[ETH_HLEN] = {};
-    struct sk_buff *recvskb;
-
-    if(!vnet_peer_table){
-        dprintf("> no table\n");
-        return -ENOSYS;
-    }
-    // On entry mac.raw, h.raw, nh.raw are set.
-    // skb->data points after the fwd vnet header, at the complete
-    // forwarded packet (which has IP hdr, no eth hdr).
-
-    // Save the eth hdr and source addr (peer).
-    memcpy(eth, skb->mac.raw, ETH_HLEN);
-    addr.u.ip4.s_addr = skb->nh.iph->saddr;
-    err = vnet_peer_get(&addr, &peer);
-    if(err){
-        wprintf("> no peer for " IPFMT "\n", NIPQUAD(skb->nh.iph->saddr));
-        goto exit;
-    }
-    peer->rx_packets++;
-    skb->mac.raw = NULL;
-    skb->nh.raw = skb->data;
-    skb->h.raw = skb->data + sizeof(struct iphdr);
-    if(!skb->nh.iph->saddr){
-        skb->nh.iph->saddr = addr.u.ip4.s_addr;
-    }
-#ifdef __KERNEL__
-    // Fix IP options, checksum, skb dst, netfilter state.
-    memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-    skb->dev = NULL;
-    dst_release(skb->dst);
-    skb->dst = NULL;
-    nf_reset(skb);
-#endif // __KERNEL__
-
-    skb->mac.raw = skb->nh.raw - ETH_HLEN;
-    memcpy(skb->mac.raw, eth, ETH_HLEN);
-
-    // Map destination mcast addresses to our mcast address.
-    if(MULTICAST(skb->nh.iph->daddr)){
-        skb->nh.iph->daddr = varp_mcast_addr;
-        //xmit does this: ip_eth_mc_map(varp_mcast_addr, eth_hdr(skb)->h_dest);
-    }
-
-    // Handle (a copy of) it ourselves, because
-    // if it is looped-back by xmit it will be ignored.
-    recvskb = alloc_skb(skb->len, GFP_ATOMIC);
-    if(recvskb){
-        recvskb->protocol = htons(ETH_P_IP);
-
-        recvskb->nh.raw = skb_put(recvskb, skb->len);
-        recvskb->h.raw = recvskb->data + sizeof(struct iphdr); 
-        skb_copy_bits(skb, 0, recvskb->data, skb->len);
-        
-        // Data points at the unwrapped iphdr, but varp_handle_message()
-        // expects it to point at the udphdr, so pull.
-        skb_pull_vn(recvskb, sizeof(struct iphdr));
-        if(varp_handle_message(recvskb) <= 0){
-            kfree_skb(recvskb);
-        }
-    }
-    err = _skb_xmit(skb, skb->nh.iph->saddr);
-    if(err >= 0) err = 1;
-  exit:
-    return err;
-}
-
-/** Hash function for keys in the peer table.
- */
-static Hashcode peer_key_hash_fn(void *k){
-    return hash_hvoid(0, k, sizeof(struct VarpAddr));
-}
-
-/** Equality function for keys in the peer table.
- */
-static int peer_key_equal_fn(void *k1, void *k2){
-    return memcmp(k1, k2, sizeof(struct VarpAddr)) == 0;
-}
-
-static void peer_entry_free_fn(HashTable *table, HTEntry *entry){
-    if(!entry) return;
-    VnetPeer_decref((VnetPeer*)entry->value);
-    HTEntry_free(entry);
-}
-
-int vnet_forward_init(void){
-    int err = 0;
-    if(vnet_peer_table) goto exit;
-    vnet_peer_table = HashTable_new(0);
-    if(!vnet_peer_table){
-        err = -ENOMEM;
-        goto exit;
-    }
-    vnet_peer_table->key_size = sizeof(struct VarpAddr);
-    vnet_peer_table->key_equal_fn = peer_key_equal_fn;
-    vnet_peer_table->key_hash_fn = peer_key_hash_fn;
-    vnet_peer_table->entry_free_fn = peer_entry_free_fn;
-  exit:
-    return err;
-}
-
-void vnet_forward_exit(void){
-    HashTable_free(vnet_peer_table);
-    vnet_peer_table = NULL;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vnet_forward.h
--- a/tools/vnet/vnet-module/vnet_forward.h     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2005, 2006 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _VNET_FORWARD_H_
-#define _VNET_FORWARD_H_
-
-#include <if_varp.h>
-
-struct sk_buff;
-struct IOStream;
-
-extern int vnet_peer_add(struct VarpAddr *addr, uint16_t port);
-extern int vnet_peer_del(struct VarpAddr *addr);
-extern void vnet_peer_print(struct IOStream *io);
-
-extern int vnet_forward_send(struct sk_buff *skb);
-extern int vnet_forward_recv(struct sk_buff *skb);
-extern int vnet_forward_init(void);
-extern void vnet_forward_exit(void);
-
-#endif /* _VNET_FORWARD_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vnet_ioctl.c
--- a/tools/vnet/vnet-module/vnet_ioctl.c       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,509 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-
-#include <asm/uaccess.h>
-
-#include <linux/slab.h>
-
-#include <linux/proc_fs.h>
-#include <linux/string.h>
-
-#include <linux/net.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-
-#include <sa.h>
-#include "vif.h"
-#include "vnet.h"
-#include "varp.h"
-#include "vnet_dev.h"
-#include "vnet_eval.h"
-#include "vnet_forward.h"
-
-#include "iostream.h"
-#include "kernel_stream.h"
-#include "mem_stream.h"
-#include "sys_string.h"
-#include "sys_net.h"
-#include "sxpr_parser.h"
-
-#define MODULE_NAME "VNET"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** @file
- *
- * Kernel interface to files in /proc.
- * todo: Add a sysfs interface using kobject.
- */
-
-#define PROC_ROOT "/proc/"
-#define PROC_ROOT_LEN 6
-#define MODULE_ROOT PROC_ROOT "vnet"
-
-enum {
-    VNET_POLICY = 1,
-    VNET_VNETS,
-    VNET_VIFS,
-    VNET_VARP,
-    VNET_PEERS,
-};
-
-typedef struct proc_dir_entry ProcEntry;
-typedef struct inode Inode;
-typedef struct file File;
-
-static int proc_open_fn(struct inode *inode, File *file);
-//static ssize_t proc_read_fn(File *file, char *buffer, size_t count, loff_t 
*offset);
-//static ssize_t proc_write_fn(File *file, const char *buffer, size_t count, 
loff_t *offset) ;
-//static int proc_flush_fn(File *file);
-static loff_t proc_lseek_fn(File * file, loff_t offset, int orig);
-static int proc_ioctl_fn(struct inode *inode, File *file, unsigned opcode, 
unsigned long arg);
-//static int proc_release_fn(struct inode *inode, File *file);
-
-static int ProcEntry_has_name(ProcEntry *entry, const char *name, int namelen){
-    dprintf("> name=%.*s entry=%.*s\n", namelen, name, entry->namelen, 
entry->name);
-    if(!entry || !entry->low_ino) return FALSE;
-    if(entry->namelen != namelen) return FALSE;
-    return memcmp(name, entry->name, namelen) == 0;
-}
-
-// Set f->f_error on error?
-// Does interface stop r/w on first error?
-// Is release called after an error?
-//
-
-static int proc_get_parser(File *file, Parser **val){
-    int err = 0;
-    Parser *parser = NULL;
-    parser = file->private_data;
-    if(!parser){
-        parser = Parser_new();
-        if(!parser){
-            err = -ENOMEM;
-            goto exit;
-        }
-        file->private_data = parser;
-    }
-  exit:
-    *val = parser;
-    return err;
-}
-
-static int proc_open_fn(Inode *inode, File *file){
-    // User open.
-    // Return errcode or 0 on success.
-    // Can stuff data in file->private_data (void*).
-    // Get entry from
-    //ProcEntry *entry = (ProcEntry *)inode->u.generic_ip;
-    //file->private_data = NULL;
-    //file->f_dentry->d_ino is inode.
-    // Check for user privilege - deny otherwise.
-    // -EACCESS
-    int err = 0;
-    dprintf(">\n");
-    file->private_data = NULL;
-    return err;
-}
-
-static ssize_t proc_read_fn(File *file, char *buffer,
-                            size_t count, loff_t *offset){
-    // User read.
-    // Copy data to user buffer, increment offset by count, return count.
-    dprintf(">\n");
-    count = 0;
-    //if(copy_to_user(buffer, data, count)){
-    //    return -EFAULT;
-    //}
-    //*offset += count;
-    return count;
-}
-
-#if 0
-static ssize_t proc_write_fn(File *file, const char *buffer,
-                             size_t count, loff_t *offset) {
-    return -EINVAL;
-}
-#endif
-
-
-#if 0
-static int proc_flush_fn(File *file){
-    // User flush.
-    int writing = (file->f_flags & O_ACCMODE) == O_WRONLY;
-    int f_count = atomic_read(&file->f_count);
-    if (writing && f_count == 1) {
-        ProcEntry *pentry = (ProcEntry *)file->f_dentry->d_inode->u.generic_ip;
-        // ...
-    }
-  return retval;
-}
-#endif
-
-#ifndef SEEK_SET
-enum {
-    /** Offset from start. */
-    SEEK_SET = 0,
-    /** Offset from current position. */
-    SEEK_CUR = 1,
-    /** Offset from size of file. */
-    SEEK_END = 2
-};
-#endif /* !SEEK_SET */
-
-static loff_t proc_lseek_fn(File * file, loff_t offset, int from){
-    // User lseek.
-    dprintf(">\n");
-    switch(from){
-    case SEEK_SET:
-        break;
-    case SEEK_CUR:
-       offset += file->f_pos;
-        break;
-    case SEEK_END:
-       return -EINVAL;
-    default:
-       return -EINVAL;
-    }
-    if(offset < 0) return -EINVAL;    
-    file->f_pos = offset;
-    return offset;
-}
-
-static int proc_ioctl_fn(Inode *inode, File *file,
-                         unsigned opcode, unsigned long arg){
-    // User ioctl.
-    dprintf(">\n");
-    return 0;
-}
-
-static ssize_t proc_policy_write_fn(File *file, const char *buffer,
-                             size_t count, loff_t *offset) {
-    // User write.
-    // Copy data into kernel space from buffer.
-    // Increment offset by count, return count (or code).
-    int err = 0;
-    char *data = NULL;
-    Parser *parser = NULL;
-
-    err = proc_get_parser(file, &parser);
-    if(err) goto exit;
-    data = allocate(count);
-    if(!data){
-        err = -ENOMEM;
-        goto exit;
-    }
-    err = copy_from_user(data, buffer, count);
-    if(err) goto exit;
-    *offset += count;
-    err = Parser_input(parser, data, count);
-  exit:
-    deallocate(data);
-    err = (err < 0 ? err : count);
-    return err;
-}
-
-static int proc_policy_release_fn(Inode *inode, File *file){
-    // User close.
-    // Cleanup file->private_data, return errcode.
-    int err = 0;
-    Parser *parser = NULL;
-    Sxpr obj, l;
-
-    dprintf(">\n");
-    err = proc_get_parser(file, &parser);
-    if(err) goto exit;
-    err = Parser_input(parser, NULL, 0);
-    if(err) goto exit;
-    obj = parser->val;
-    for(l = obj; CONSP(l); l = CDR(l)){
-        err = vnet_eval(CAR(l), iostdout, NULL);
-        if(err) break;
-    }
-  exit:
-    Parser_free(parser);
-    file->private_data = NULL;
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-static int proc_io_open(Inode *inode, File *file, IOStream **val){
-    int err = 0;
-    IOStream *io = mem_stream_new();
-    if(!io){
-        err = -ENOMEM;
-        goto exit;
-    }
-    file->private_data = io;
-  exit:
-    *val = (err ? NULL: io);
-    return err;
-}
-
-static ssize_t proc_io_read_fn(File *file, char *buffer,
-                               size_t count, loff_t *offset){
-    // User read.
-    // Copy data to user buffer, increment offset by count, return count.
-    int err = 0;
-    char kbuf[1024] = {};
-    int kbuf_n = sizeof(kbuf);
-    int k, n = 0;
-    char *ubuf = buffer;
-    IOStream *io = file->private_data;
-
-    dprintf(">\n");
-    if(!io) goto exit;
-    while(n < count){
-        k = count - n;
-        if(k > kbuf_n){
-            k = kbuf_n;
-        }
-        k = IOStream_read(io, kbuf, k);
-        if(k <= 0) break;
-        if(copy_to_user(ubuf, kbuf, k)){
-            err = -EFAULT;
-            goto exit;
-        }
-        n += k;
-        ubuf += k;
-    }
-    *offset += n;
-  exit:
-    return (err ? err : n);
-}
-
-static int proc_io_release_fn(Inode *inode, File *file){
-    // User close.
-    int err = 0;
-    IOStream *io = file->private_data;
-    if(io) IOStream_close(io);
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-static int proc_vnets_open_fn(Inode *inode, File *file){
-    int err = 0;
-    IOStream *io;
-    if(proc_io_open(inode, file, &io)) goto exit;
-    vnet_print(io);
-  exit:
-    return err;
-}
-
-static int proc_vifs_open_fn(Inode *inode, File *file){
-    int err = 0;
-    IOStream *io;
-    if(proc_io_open(inode, file, &io)) goto exit;
-    vif_print(io);
-  exit:
-    return err;
-}
-
-static int proc_peers_open_fn(Inode *inode, File *file){
-    int err = 0;
-    IOStream *io;
-    if(proc_io_open(inode, file, &io)) goto exit;
-    vnet_peer_print(io);
-  exit:
-    return err;
-}
-
-static int proc_varp_open_fn(Inode *inode, File *file){
-    int err = 0;
-    IOStream *io;
-    if(proc_io_open(inode, file, &io)) goto exit;
-    varp_print(io);
-  exit:
-    return err;
-}
-
-static struct file_operations proc_policy_ops = {
-    open:    proc_open_fn,
-    read:    proc_read_fn,
-    write:   proc_policy_write_fn,
-    //flush:   proc_flush_fn,
-    llseek:  proc_lseek_fn,
-    ioctl:   proc_ioctl_fn,
-    release: proc_policy_release_fn,
-};
-
-static struct file_operations proc_vnets_ops = {
-    open:    proc_vnets_open_fn,
-    read:    proc_io_read_fn,
-    release: proc_io_release_fn,
-};
-
-static struct file_operations proc_vifs_ops = {
-    open:    proc_vifs_open_fn,
-    read:    proc_io_read_fn,
-    release: proc_io_release_fn,
-};
-
-static struct file_operations proc_peers_ops = {
-    open:    proc_peers_open_fn,
-    read:    proc_io_read_fn,
-    release: proc_io_release_fn,
-};
-
-static struct file_operations proc_varp_ops = {
-    open:    proc_varp_open_fn,
-    read:    proc_io_read_fn,
-    release: proc_io_release_fn,
-};
-
-static ProcEntry *proc_fs_root = &proc_root;
-
-static int proc_path_init(const char *path, const char **rest){
-    int err = 0;
-
-    if(!path){
-        err = -EINVAL;
-        goto exit;
-    }
-    if(*path == '/'){
-        if(strncmp(PROC_ROOT, path, PROC_ROOT_LEN)){
-            err = -EINVAL;
-        } else {
-            path += PROC_ROOT_LEN;
-        }
-    }
-  exit:
-    *rest = path;
-    return err;
-}
-
-/** Parse a path relative to `dir'. If dir is null or the proc root
- * the path is relative to "/proc/", and the leading "/proc/" may be
- * supplied.
- *
- */
-static ProcEntry * ProcFS_lookup(const char *path, ProcEntry *dir){
-    const char *pathptr = path, *next = NULL;
-    ProcEntry *entry, *result = NULL;
-    int pathlen;
-
-    if(dir && (dir != proc_fs_root)){
-        entry = dir;
-    } else {
-        if(proc_path_init(path, &pathptr)) goto exit;
-        entry = proc_fs_root;
-    }
-    if(!pathptr || !*pathptr) goto exit;
-    while(1){
-        next = strchr(pathptr, '/');
-        pathlen = (next ? next - pathptr : strlen(pathptr));
-        for(entry = entry->subdir; entry ; entry = entry->next) {
-            if(ProcEntry_has_name(entry, pathptr, pathlen)) break;
-        }
-        if (!entry) break;
-        if(!next){
-            result = entry;
-            break;
-        }
-        pathptr = next + 1;
-    }
-  exit:
-    return result;
-}
-
-static ProcEntry *ProcFS_register(const char *name, ProcEntry *dir,
-                                  int val, struct file_operations *ops){
-    mode_t mode = 0;
-    ProcEntry *entry;
-
-    entry = create_proc_entry(name, mode, dir);
-    if(entry){
-        entry->proc_fops = ops;
-        entry->data = (void*)val; // Whatever data we need.
-    }
-    return entry;
-}
-
-static ProcEntry *ProcFS_mkdir(const char *name, ProcEntry *parent){
-    ProcEntry *entry = NULL;
-    entry = ProcFS_lookup(name, parent);
-    if(!entry){
-        const char *path;
-        if(proc_path_init(name, &path)) goto exit;
-        entry = proc_mkdir(path, parent);
-    }
-  exit:
-    return entry;
-}
-
-static void ProcFS_remove(const char *name, ProcEntry *parent){
-    remove_proc_entry(name, parent);
-}
-
-static void ProcFS_rmrec_entry(ProcEntry *entry){
-    if(entry){
-        // Don't want to remove /proc itself!
-        if(entry->parent == entry) return;
-        while(entry->subdir){
-            ProcFS_rmrec_entry(entry->subdir);
-        }
-        dprintf("> remove %s\n", entry->name);
-        ProcFS_remove(entry->name, entry->parent);
-    }
-}
-
-static void ProcFS_rmrec(const char *name, ProcEntry *parent){
-    ProcEntry *entry;
-
-    dprintf("> name=%s\n", name);
-    entry = ProcFS_lookup(name, parent);
-    if(entry){
-        ProcFS_rmrec_entry(entry);
-    }
-    dprintf("<\n");
-}
-
-void __init ProcFS_init(void){
-    ProcEntry *root_entry;
-    ProcEntry *policy_entry;
-    ProcEntry *vnets_entry;
-    ProcEntry *vifs_entry;
-    ProcEntry *peers_entry;
-    ProcEntry *varp_entry;
-
-    dprintf(">\n");
-    root_entry = ProcFS_mkdir(MODULE_ROOT, NULL);
-    if(!root_entry) goto exit;
-    policy_entry = ProcFS_register("policy", root_entry, VNET_POLICY, 
&proc_policy_ops);
-    vnets_entry = ProcFS_register("vnets", root_entry, VNET_VNETS, 
&proc_vnets_ops);
-    vifs_entry = ProcFS_register("vifs", root_entry, VNET_VIFS, 
&proc_vifs_ops);
-    peers_entry = ProcFS_register("peers", root_entry, VNET_PEERS, 
&proc_peers_ops);
-    varp_entry = ProcFS_register("varp", root_entry, VNET_VARP, 
&proc_varp_ops);
-  exit:
-    dprintf("<\n");
-}
-
-void __exit ProcFS_exit(void){
-    dprintf(">\n");
-    ProcFS_rmrec(MODULE_ROOT, NULL);
-    dprintf("<\n");
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnet-module/vnet_ioctl.h
--- a/tools/vnet/vnet-module/vnet_ioctl.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free software Foundation, Inc.,
- * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _VNET_VNET_IOCTL_H_
-#define _VNET_VNET_IOCTL_H_
-
-extern void ProcFS_init(void);
-extern void ProcFS_exit(void);
-
-#endif /* ! _VNET_VNET_IOCTL_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/Makefile
--- a/tools/vnet/vnetd/Makefile Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-# -*- mode: Makefile; -*-
-#----------------------------------------------------------------------------
-# Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>.
-#
-# This library is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as
-# published by the Free Software Foundation; either version 2.1 of the
-# License, or  (at your option) any later version. This library is 
-# distributed in the  hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.
-# See the GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this library; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-#----------------------------------------------------------------------------
-
-VNET_ROOT ?= $(shell cd .. && pwd)
-include $(VNET_ROOT)/Make.env
-
-.PHONY: all
-all: vnetd
-
-#----------------------------------------------------------------------------
-
-# Comment out when outside xen.
-#include $(XEN_ROOT)/tools/Rules.mk
-
-INSTALL_PROG ?= $(INSTALL) -m0755 -p
-
-INCLUDES += -I$(LIBXUTIL_DIR)
-INCLUDES += -I$(VNET_MODULE_DIR)
-INCLUDES += -I$(shell pwd)
-
-#----------------------------------------------------------------------------
-# GC.
-
-INCLUDES += -I$(GC_INCLUDE)
-#LIBS += -L$(GC_LIB_DIR)
-CPPFLAGS += -D USE_GC
-
-# Sometimes linux/atomic.h is not #ifdef __KERNEL__.
-CPPFLAGS += -D __ARCH_I386_ATOMIC__
-
-#----------------------------------------------------------------------------
-CFLAGS += -O3
-CFLAGS += $(INCLUDES) $(LIBS)
-
-LDFLAGS += $(LIBS)
-
-# Dependencies. Gcc generates them for us.
-CFLAGS += -Wp,-MD,.$(@F).d
-PROG_DEP = .*.d
-
-vpath %.c $(LIBXUTIL_DIR)
-vpath %.c $(VNET_MODULE_DIR)
-
-IPATHS:=$(INCLUDES:-I=)
-vpath %.h $(IPATHS)
-
-#----------------------------------------------------------------------------
-VNETD_SRC:=
-VNETD_SRC+= connection.c
-VNETD_SRC+= select.c
-VNETD_SRC+= timer.c
-VNETD_SRC+= spinlock.c
-VNETD_SRC+= skbuff.c
-VNETD_SRC+= vnetd.c
-
-VNETD_SRC+= skb_util.c
-VNETD_SRC+= sxpr_util.c
-VNETD_SRC+= timer_util.c
-VNETD_SRC+= etherip.c
-VNETD_SRC+= vnet.c
-VNETD_SRC+= vnet_eval.c
-VNETD_SRC+= vnet_forward.c
-VNETD_SRC+= vif.c
-VNETD_SRC+= tunnel.c
-VNETD_SRC+= sa.c
-VNETD_SRC+= varp.c
-
-#----------------------------------------------------------------------------
-LIB_SRC:=
-LIB_SRC+= allocate.c
-LIB_SRC+= enum.c
-LIB_SRC+= file_stream.c
-LIB_SRC+= hash_table.c
-LIB_SRC+= iostream.c
-LIB_SRC+= lexis.c
-LIB_SRC+= socket_stream.c
-LIB_SRC+= string_stream.c
-LIB_SRC+= sxpr.c
-LIB_SRC+= sxpr_parser.c
-LIB_SRC+= sys_net.c
-LIB_SRC+= sys_string.c
-LIB_SRC+= util.c
-
-VNETD_SRC+=$(LIB_SRC)
-
-VNETD_OBJ := $(VNETD_SRC:.c=.o)
-
-#VNETD_LIBS:= $(GC_LIB_SO)
-#VNETD_LIBS:= -lgc
-VNETD_LIBS:= $(GC_LIB_A)
-
-vnetd: $(VNETD_OBJ)
-       $(CC) $(CFLAGS) -o $@ $^ $(VNETD_LIBS) -ldl -lpthread
-
-.PHONY: install
-install: vnetd
-       $(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
-       $(INSTALL_PROG) vnetd $(DESTDIR)$(SBINDIR)
-
-.PHONY: clean
-clean:
-       -@$(RM) *.a *.o *~
-       -@$(RM) vnetd
-       -@$(RM) $(PROG_DEP)
-
--include $(PROG_DEP)
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/connection.c
--- a/tools/vnet/vnetd/connection.c     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,412 +0,0 @@
-/*
- * Copyright (C) 2003 - 2004 Mike Wray <mike.wray@xxxxxx>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "allocate.h"
-#include "connection.h"
-#include "file_stream.h"
-#include "socket_stream.h"
-
-#define MODULE_NAME "conn"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-/** Initialize a file stream from a file desciptor.
- *
- * @param fd file descriptor
- * @param mode file mode
- * @param buffered make the stream buffered if 1, unbuffered if 0
- * @param io return parameter for the stream
- * @return 0 on success, error code otherwise
- */
-int stream_init(int fd, const char *mode, int buffered, IOStream **io){
-    int err = 0;
-    *io = file_stream_fdopen(fd, mode);
-    if(!*io){
-        err = -errno;
-        perror("fdopen");
-        goto exit;
-    }
-    if(!buffered){
-        // Make unbuffered.
-        err = file_stream_setvbuf(*io, NULL, _IONBF, 0);
-        if(err){
-            err = -errno;
-            perror("setvbuf");
-            goto exit;
-        }
-    }
-  exit:
-    if(err && *io){
-        IOStream_close(*io);
-        *io = NULL;
-    }
-    return err;
-}
-
-ConnList * ConnList_add(ConnList *l, Conn *conn){
-    ConnList *v;
-    v = ALLOCATE(ConnList);
-    v->conn = conn;
-    v->next =l;
-    return v;
-}
-
-ConnList * ConnList_del(ConnList *l, Conn *conn){
-    ConnList *prev, *curr, *next;
-    for(prev = NULL, curr = l; curr; prev = curr, curr = next){
-        next = curr->next;
-        if(curr->conn == conn){
-            if(prev){
-                prev->next = curr->next;
-            } else {
-                l = curr->next;
-            }
-        }
-    }
-    return l;
-}
-
-void ConnList_close(ConnList *l){
-    for( ; l; l = l->next){
-        Conn_close(l->conn);
-    }
-}
-    
-void ConnList_select(ConnList *l, SelectSet *set){
-    for( ; l; l = l->next){
-        Conn_select(l->conn, set);
-    }
-}
-
-/** Handle connections according to a select set.
- *
- * @param set indicates ready connections
- */
-ConnList * ConnList_handle(ConnList *l, SelectSet *set){
-    ConnList *prev, *curr, *next;
-    Conn *conn;
-    int err;
-
-    for(prev = NULL, curr = l; curr; prev = curr, curr = next){
-        next = curr->next;
-        conn = curr->conn;
-        err = Conn_handle(conn, set);
-        if(err){
-            if(prev){
-                prev->next = curr->next;
-            } else {
-                l = curr->next;
-            }
-        }
-    }
-    return l;
-}
-
-Conn *Conn_new(int (*fn)(Conn *conn, int mode), void *data){
-    Conn *conn;
-    conn = ALLOCATE(Conn);
-    conn->fn = fn;
-    conn->data = data;
-    return conn;
-}
-
-int Conn_handler(Conn *conn, int mode){
-    int err = 0;
-    dprintf(">\n");
-    if(conn->fn){
-        err = conn->fn(conn, mode);
-    } else {
-        dprintf("> no handler\n");
-        err = -ENOSYS;
-    }
-    if(err < 0){
-        dprintf("> err=%d, closing %d\n", err, conn->sock);
-        Conn_close(conn);
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-int Conn_handle(Conn *conn, SelectSet *set){
-    int err = 0;
-    int mode = SelectSet_in(set, conn->sock);
-
-    dprintf("> sock=%d mode=%d\n", conn->sock, mode);
-    if(mode){
-        err = Conn_handler(conn, mode);
-
-    }
-    return err;
-}
-
-void Conn_select(Conn *conn, SelectSet *set){
-    dprintf("> sock=%d\n", conn->sock);
-    SelectSet_add(set, conn->sock, conn->mode);
-}
-
-/** Initialize a connection.
- *
- * @param conn connection
- * @param sock socket
- * @param ipaddr ip address
- * @return 0 on success, error code otherwise
- */
-int Conn_init(Conn *conn, int sock, int type, int mode, struct sockaddr_in 
addr){
-    int err = 0;
-    conn->addr = addr;
-    conn->type = type;
-    conn->mode = mode;
-    conn->sock = sock;
-    if(type == SOCK_STREAM){
-        err = stream_init(sock, "r", 0, &conn->in);
-        if(err) goto exit;
-        err = stream_init(sock, "w", 0, &conn->out);
-        if(err) goto exit;
-    } else {
-        conn->in = socket_stream_new(sock);
-        conn->out = socket_stream_new(sock);
-        socket_stream_set_addr(conn->out, &addr);
-    }
-  exit:
-    if(err) eprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Open a connection.
- *
- * @param conn connection
- * @param socktype socket type
- * @param ipaddr ip address to connect to
- * @param port port
- * @return 0 on success, error code otherwise
- */
-int Conn_connect(Conn *conn, int socktype, struct in_addr ipaddr, uint16_t 
port){
-    int err = 0;
-    int sock;
-    struct sockaddr_in addr_in;
-    struct sockaddr *addr = (struct sockaddr *)&addr_in;
-    socklen_t addr_n = sizeof(addr_in);
-    dprintf("> addr=%s:%d\n", inet_ntoa(ipaddr), ntohs(port));
-    sock = socket(AF_INET, socktype, 0);
-    if(sock < 0){
-        err = -errno;
-        goto exit;
-    }
-    addr_in.sin_family = AF_INET;
-    addr_in.sin_addr = ipaddr;
-    addr_in.sin_port = port;
-    err = connect(sock, addr, addr_n);
-    if(err) goto exit;
-    err = Conn_init(conn, sock, socktype, 0, addr_in);
-  exit:
-    if(err){
-        perror("Conn_connect");
-        eprintf("< err=%d\n", err);
-    }
-    return err;
-}
-
-/** Close a connection.
- *
- * @param conn connection
- */
-void Conn_close(Conn *conn){
-    if(!conn) return;
-    if(conn->in) IOStream_close(conn->in);
-    if(conn->out) IOStream_close(conn->out);
-    shutdown(conn->sock, 2);
-}
-
-/** Set socket option to reuse address.
- */
-int setsock_reuse(int sock, int val){
-    int err = 0;
-    err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
-    if(err < 0){
-        err = -errno;
-        perror("setsockopt SO_REUSEADDR");
-    }
-    return err;
-}
-
-/** Set socket broadcast option.
- */
-int setsock_broadcast(int sock, int val){
-    int err = 0;
-    err = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val));
-    if(err < 0){
-        err = -errno;
-        perror("setsockopt SO_BROADCAST");
-    }
-    return err;
-}
-
-/** Join a socket to a multicast group.
- */
-int setsock_multicast(int sock, uint32_t iaddr, uint32_t maddr){
-    int err = 0;
-    struct ip_mreqn mreq = {};
-    int mloop = 0;
-    // See 'man 7 ip' for these options.
-    mreq.imr_multiaddr.s_addr = maddr;       // IP multicast address.
-    mreq.imr_address.s_addr   = iaddr;       // Interface IP address.
-    mreq.imr_ifindex = 0;                    // Interface index (0 means any).
-    err = setsockopt(sock, SOL_IP, IP_MULTICAST_LOOP, &mloop, sizeof(mloop));
-    if(err < 0){
-        err = -errno;
-        perror("setsockopt IP_MULTICAST_LOOP");
-        goto exit;
-    }
-    err = setsockopt(sock, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
-    if(err < 0){
-        err = -errno;
-        perror("setsockopt IP_ADD_MEMBERSHIP");
-        goto exit;
-    }
-  exit:
-    return err;
-}
-
-/** Set a socket's multicast ttl (default is 1).
- */
-int setsock_multicast_ttl(int sock, uint8_t ttl){
-    int err = 0;
-    err = setsockopt(sock, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
-    if(err < 0){
-        err = -errno;
-        perror("setsockopt IP_MULTICAST_TTL");
-    }
-    return err;
-}
-
-int setsock_pktinfo(int sock, int val){
-    int err = 0;
-    err = setsockopt(sock, SOL_IP, IP_PKTINFO, &val, sizeof(val));
-    if(err < 0){
-        err = -errno;
-        perror("setsockopt IP_PKTINFO");
-    }
-    return err;
-}
-
-char * socket_flags(int flags){
-    static char s[6];
-    int i = 0;
-    s[i++] = (flags & VSOCK_CONNECT   ? 'c' : '-');
-    s[i++] = (flags & VSOCK_BIND      ? 'b' : '-');
-    s[i++] = (flags & VSOCK_REUSE     ? 'r' : '-');
-    s[i++] = (flags & VSOCK_BROADCAST ? 'B' : '-');
-    s[i++] = (flags & VSOCK_MULTICAST ? 'M' : '-');
-    s[i++] = '\0';
-    return s;
-}
-
-/** Create a socket.
- * The flags can include VSOCK_REUSE, VSOCK_BROADCAST, VSOCK_CONNECT.
- *
- * @param socktype socket type
- * @param saddr address
- * @param port port
- * @param flags flags
- * @param val return value for the socket connection
- * @return 0 on success, error code otherwise
- */
-int create_socket(int socktype, uint32_t saddr, uint32_t port, int flags, int 
*val){
-    int err = 0;
-    int sock = 0;
-    struct sockaddr_in addr_in;
-    struct sockaddr *addr = (struct sockaddr *)&addr_in;
-    socklen_t addr_n = sizeof(addr_in);
-    int reuse, bcast;
-
-    //dprintf(">\n");
-    reuse = (flags & VSOCK_REUSE);
-    bcast = (flags & VSOCK_BROADCAST);
-    addr_in.sin_family      = AF_INET;
-    addr_in.sin_addr.s_addr = saddr;
-    addr_in.sin_port        = port;
-    dprintf("> flags=%s addr=%s port=%d\n", socket_flags(flags),
-            inet_ntoa(addr_in.sin_addr), ntohs(addr_in.sin_port));
-
-    sock = socket(AF_INET, socktype, 0);
-    if(sock < 0){
-        err = -errno;
-        goto exit;
-    }
-    if(reuse){
-        err = setsock_reuse(sock, reuse);
-        if(err < 0) goto exit;
-    }
-    if(bcast){
-        err = setsock_broadcast(sock, bcast);
-        if(err < 0) goto exit;
-    }
-    if(flags & VSOCK_CONNECT){
-        err = connect(sock, addr, addr_n);
-        if(err < 0){
-            err = -errno;
-            perror("connect");
-            goto exit;
-        }
-    }
-    if(flags & VSOCK_BIND){
-        err = bind(sock, addr, addr_n);
-        if(err < 0){
-            err = -errno;
-            perror("bind");
-            goto exit;
-        }
-    }
-    {
-        struct sockaddr_in self = {};
-        socklen_t self_n = sizeof(self);
-        getsockname(sock, (struct sockaddr *)&self, &self_n);
-        dprintf("> sockname sock=%d addr=%s port=%d reuse=%d bcast=%d\n",
-                sock, inet_ntoa(self.sin_addr), ntohs(self.sin_port),
-                reuse, bcast);
-    }
-  exit:
-    *val = (err ? -1 : sock);
-    //dprintf("< err=%d\n", err);
-    return err;
-}
-
-int Conn_socket(int socktype, uint32_t saddr, uint32_t port, int flags, Conn 
**val){
-    int err;
-    int sock;
-    struct sockaddr_in addr_in;
-    Conn *conn;
-
-    err = create_socket(socktype, saddr, port, flags, &sock);
-    if(err) goto exit;
-    conn = Conn_new(NULL, NULL);
-    addr_in.sin_family      = AF_INET;
-    addr_in.sin_addr.s_addr = saddr;
-    addr_in.sin_port        = port;
-    Conn_init(conn, sock, socktype, 0, addr_in);
-  exit:
-    *val = (err ? NULL : conn);
-    return err;
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/connection.h
--- a/tools/vnet/vnetd/connection.h     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2003 - 2004 Mike Wray <mike.wray@xxxxxx>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-#ifndef _VNET_CONNECTION_H_
-#define _VNET_CONNECTION_H_
-
-#include <netinet/in.h>
-
-#include "iostream.h"
-#include "select.h"
-
-/** A connection.
- * The underlying transport is a socket. 
- * Contains in and out streams using the socket.
- */
-typedef struct Conn {
-    struct sockaddr_in addr;
-    int sock;
-    int type;
-    int mode; // select mode
-    IOStream *in;
-    IOStream *out;
-    int (*fn)(struct Conn *conn, int mode);
-    void *data;
-} Conn;
-
-typedef struct ConnList {
-    Conn *conn;
-    struct ConnList *next;
-} ConnList;
-
-extern ConnList * ConnList_add(ConnList *l, Conn *conn);
-extern ConnList * ConnList_del(ConnList *l, Conn *conn);
-extern void ConnList_close(ConnList *l);
-extern void ConnList_select(ConnList *l, SelectSet *set);
-extern ConnList * ConnList_handle(ConnList *l, SelectSet *set);
-    
-extern Conn * Conn_new(int (*fn)(struct Conn *conn, int mode), void *data);
-extern int Conn_init(Conn *conn, int sock, int type, int mode, struct 
sockaddr_in addr);
-extern int Conn_connect(Conn *conn, int type, struct in_addr ipaddr, uint16_t 
port);
-extern void Conn_select(Conn *conn, SelectSet *set);
-extern int Conn_handle(Conn *conn, SelectSet *set);
-extern void Conn_close(Conn *conn);
-extern int Conn_socket(int socktype, uint32_t saddr, uint32_t port, int flags, 
Conn **val);
-
-/** Socket flags. */
-enum {
-    VSOCK_REUSE     =  1,
-    VSOCK_BIND      =  2,
-    VSOCK_CONNECT   =  4,
-    VSOCK_BROADCAST =  8,
-    VSOCK_MULTICAST = 16,
- };
-
-extern int create_socket(int socktype, uint32_t saddr, uint32_t port, int 
flags, int *sock);
-extern int setsock_reuse(int sock, int val);
-extern int setsock_broadcast(int sock, int val);
-extern int setsock_multicast(int sock, uint32_t iaddr, uint32_t maddr);
-extern int setsock_multicast_ttl(int sock, uint8_t ttl);
-extern int setsock_pktinfo(int sock, int val);
-extern char * socket_flags(int flags);
-
-#endif /* ! _VNET_CONNECTION_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/list.h
--- a/tools/vnet/vnetd/list.h   Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,284 +0,0 @@
-#ifndef _VNETD_LIST_H_
-#define _VNETD_LIST_H_
-
-/* Taken from Linux kernel code, but de-kernelized for userspace. */
-#include <stddef.h>
-
-/*
- * These are non-NULL pointers that will result in page faults
- * under normal circumstances, used to verify that nobody uses
- * non-initialized list entries.
- */
-#define LIST_POISON1  ((void *) 0x00100100)
-#define LIST_POISON2  ((void *) 0x00200200)
-
-#define container_of(ptr, type, member) ({                     \
-        const typeof( ((type *)0)->member ) *__mptr = (ptr);   \
-        (type *)( (char *)__mptr - offsetof(type,member) );})
-
-/*
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-
-struct list_head {
-       struct list_head *next, *prev;
-};
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
-       struct list_head name = LIST_HEAD_INIT(name)
-
-#define INIT_LIST_HEAD(ptr) do { \
-       (ptr)->next = (ptr); (ptr)->prev = (ptr); \
-} while (0)
-
-/*
- * Insert a new entry between two known consecutive entries. 
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_add(struct list_head *new,
-                             struct list_head *prev,
-                             struct list_head *next)
-{
-       next->prev = new;
-       new->next = next;
-       new->prev = prev;
-       prev->next = new;
-}
-
-/**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static inline void list_add(struct list_head *new, struct list_head *head)
-{
-       __list_add(new, head, head->next);
-}
-
-/**
- * list_add_tail - add a new entry
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
-{
-       __list_add(new, head->prev, head);
-}
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_del(struct list_head * prev, struct list_head * next)
-{
-       next->prev = prev;
-       prev->next = next;
-}
-
-/**
- * list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static inline void list_del(struct list_head *entry)
-{
-       __list_del(entry->prev, entry->next);
-       entry->next = LIST_POISON1;
-       entry->prev = LIST_POISON2;
-}
-
-/**
- * list_del_rcu - deletes entry from list without re-initialization
- * @entry: the element to delete from the list.
- *
- * Note: list_empty on entry does not return true after this, 
- * the entry is in an undefined state. It is useful for RCU based
- * lockfree traversal.
- *
- * In particular, it means that we can not poison the forward 
- * pointers that may still be used for walking the list.
- */
-static inline void list_del_rcu(struct list_head *entry)
-{
-       __list_del(entry->prev, entry->next);
-       entry->prev = LIST_POISON2;
-}
-
-/**
- * list_del_init - deletes entry from list and reinitialize it.
- * @entry: the element to delete from the list.
- */
-static inline void list_del_init(struct list_head *entry)
-{
-       __list_del(entry->prev, entry->next);
-       INIT_LIST_HEAD(entry); 
-}
-
-/**
- * list_move - delete from one list and add as another's head
- * @list: the entry to move
- * @head: the head that will precede our entry
- */
-static inline void list_move(struct list_head *list, struct list_head *head)
-{
-        __list_del(list->prev, list->next);
-        list_add(list, head);
-}
-
-/**
- * list_move_tail - delete from one list and add as another's tail
- * @list: the entry to move
- * @head: the head that will follow our entry
- */
-static inline void list_move_tail(struct list_head *list,
-                                 struct list_head *head)
-{
-        __list_del(list->prev, list->next);
-        list_add_tail(list, head);
-}
-
-/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(struct list_head *head)
-{
-       return head->next == head;
-}
-
-static inline void __list_splice(struct list_head *list,
-                                struct list_head *head)
-{
-       struct list_head *first = list->next;
-       struct list_head *last = list->prev;
-       struct list_head *at = head->next;
-
-       first->prev = head;
-       head->next = first;
-
-       last->next = at;
-       at->prev = last;
-}
-
-/**
- * list_splice - join two lists
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- */
-static inline void list_splice(struct list_head *list, struct list_head *head)
-{
-       if (!list_empty(list))
-               __list_splice(list, head);
-}
-
-/**
- * list_splice_init - join two lists and reinitialise the emptied list.
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- *
- * The list at @list is reinitialised
- */
-static inline void list_splice_init(struct list_head *list,
-                                   struct list_head *head)
-{
-       if (!list_empty(list)) {
-               __list_splice(list, head);
-               INIT_LIST_HEAD(list);
-       }
-}
-
-/**
- * list_entry - get the struct for this entry
- * @ptr:       the &struct list_head pointer.
- * @type:      the type of the struct this is embedded in.
- * @member:    the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
-       container_of(ptr, type, member)
-
-/**
- * list_for_each       -       iterate over a list
- * @pos:       the &struct list_head to use as a loop counter.
- * @head:      the head for your list.
- */
-#define list_for_each(pos, head) \
-       for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev  -       iterate over a list backwards
- * @pos:       the &struct list_head to use as a loop counter.
- * @head:      the head for your list.
- */
-#define list_for_each_prev(pos, head) \
-       for (pos = (head)->prev; pos != (head); pos = pos->prev)
-               
-/**
- * list_for_each_safe  -       iterate over a list safe against removal of 
list entry
- * @pos:       the &struct list_head to use as a loop counter.
- * @n:         another &struct list_head to use as temporary storage
- * @head:      the head for your list.
- */
-#define list_for_each_safe(pos, n, head) \
-       for (pos = (head)->next, n = pos->next; pos != (head); \
-               pos = n, n = pos->next)
-
-/**
- * list_for_each_entry -       iterate over list of given type
- * @pos:       the type * to use as a loop counter.
- * @head:      the head for your list.
- * @member:    the name of the list_struct within the struct.
- */
-#define list_for_each_entry(pos, head, member)                         \
-       for (pos = list_entry((head)->next, typeof(*pos), member);      \
-            &pos->member != (head);                                    \
-            pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_reverse - iterate backwards over list of given type.
- * @pos:       the type * to use as a loop counter.
- * @head:      the head for your list.
- * @member:    the name of the list_struct within the struct.
- */
-#define list_for_each_entry_reverse(pos, head, member)                 \
-       for (pos = list_entry((head)->prev, typeof(*pos), member);      \
-            &pos->member != (head);                                    \
-            pos = list_entry(pos->member.prev, typeof(*pos), member))
-
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against
- *  removal of list entry
- * @pos:       the type * to use as a loop counter.
- * @n:         another type * to use as temporary storage
- * @head:      the head for your list.
- * @member:    the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member)                 \
-       for (pos = list_entry((head)->next, typeof(*pos), member),      \
-               n = list_entry(pos->member.next, typeof(*pos), member); \
-            &pos->member != (head);                                    \
-            pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-
-
-#endif /* _VNETD_LIST_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/select.c
--- a/tools/vnet/vnetd/select.c Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2003 - 2004 Mike Wray <mike.wray@xxxxxx>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "select.h"
-
-#define MODULE_NAME  "select"
-#define DEBUG
-#undef DEBUG
-#include "debug.h"
-
-/** Zero all the file descriptor sets.
- *
- * @param set select set
- * @param fd file descriptor
- * @return 0 on success, -1 otherwise
- */
-void SelectSet_zero(SelectSet *set){
-    set->n = 0;
-    FD_ZERO(&set->rd);
-    FD_ZERO(&set->wr);
-    FD_ZERO(&set->er);
-}
-
-/** Add a file descriptor to the set.
- *
- * @param set select set
- * @param fd file descriptor
- * @param mode mask of sets to add to
- * @return 0 on success, -1 otherwise
- */
-void SelectSet_add(SelectSet *set, int fd, int mode){
-    if(fd < 0) return;
-    if(mode & SELECT_READ){
-        SelectSet_add_read(set, fd);
-    }
-    if(mode & SELECT_WRITE){
-        SelectSet_add_write(set, fd);
-    }
-    if(mode & SELECT_ERROR){
-        SelectSet_add_error(set, fd);
-    }
-}
-
-/** Add a file descriptor to the write set.
- *
- * @param set select set
- * @param fd file descriptor
- * @return 0 on success, -1 otherwise
- */
-void SelectSet_add_read(SelectSet *set, int fd){
-    dprintf("> fd=%d\n", fd);
-    if(fd < 0) return;
-    FD_SET(fd, &set->rd);
-    if(fd > set->n) set->n = fd;
-}
-
-/** Add a file descriptor to the write set.
- *
- * @param set select set
- * @param fd file descriptor
- * @return 0 on success, -1 otherwise
- */
-void SelectSet_add_write(SelectSet *set, int fd){
-    dprintf("> fd=%d\n", fd);
-    if(fd < 0) return;
-    FD_SET(fd, &set->wr);
-    if(fd > set->n) set->n = fd;
-}
-
-/** Add a file descriptor to the error set.
- *
- * @param set select set
- * @param fd file descriptor
- * @return 0 on success, -1 otherwise
- */
-void SelectSet_add_error(SelectSet *set, int fd){
-    dprintf("> fd=%d\n", fd);
-    if(fd < 0) return;
-    FD_SET(fd, &set->er);
-    if(fd > set->n) set->n = fd;
-}
-
-/** Select on file descriptors.
- *
- * @param set select set
- * @param timeout timeout (may be NULL for no timeout)
- * @return 0 on success, -1 otherwise
- */
-int SelectSet_select(SelectSet *set, struct timeval *timeout){
-    return select(set->n+1, &set->rd, &set->wr, &set->er, timeout);
-}
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/select.h
--- a/tools/vnet/vnetd/select.h Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2003 - 2004 Mike Wray <mike.wray@xxxxxx>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-#ifndef _VFC_SELECT_H_
-#define _VFC_SELECT_H_
-
-/** Set of file descriptors for select.
- */
-typedef struct SelectSet {
-    int n;
-    fd_set rd, wr, er;
-} SelectSet;
-
-enum {
-    SELECT_READ  = 1,
-    SELECT_WRITE = 2,
-    SELECT_ERROR = 4,
-};
-
-extern void SelectSet_zero(SelectSet *set);
-extern void SelectSet_add(SelectSet *set, int fd, int mode);
-extern void SelectSet_add_read(SelectSet *set, int fd);
-extern void SelectSet_add_write(SelectSet *set, int fd);
-extern void SelectSet_add_error(SelectSet *set, int fd);
-extern int SelectSet_select(SelectSet *set, struct timeval *timeout);
-
-static inline int SelectSet_in(SelectSet *set, int fd){
-    return ((fd >= 0)
-            ? ((FD_ISSET(fd, &set->rd) ? SELECT_READ : 0) |
-               (FD_ISSET(fd, &set->wr) ? SELECT_WRITE : 0) |
-               (FD_ISSET(fd, &set->er) ? SELECT_ERROR : 0))
-            : 0);
-}
-
-static inline int SelectSet_in_read(SelectSet *set, int fd){
-    return (fd >= 0) && FD_ISSET(fd, &set->rd);
-}
-
-static inline int SelectSet_in_write(SelectSet *set, int fd){
-    return (fd >= 0) && FD_ISSET(fd, &set->wr);
-}
-
-static inline int SelectSet_in_err(SelectSet *set, int fd){
-    return (fd >= 0) && FD_ISSET(fd, &set->er);
-}
-
-#endif /* ! _VFC_SELECT_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/selector.c
--- a/tools/vnet/vnetd/selector.c       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "connection.h"
-#include "selector.h"
-
-#define MODULE_NAME "select"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-void Selector_init(Selector *sel){
-    INIT_LIST_HEAD(&sel->list);
-}
-
-/** Close a selector and remove it from its list.
- *
- * @param sel selector (may be null)
- */
-void Selector_close(Selector *sel){
-    if(!sel) return;
-    dprintf(">\n");
-    if(sel->close){
-        sel->close(sel);
-    }
-    if(sel->list.next
-       && sel->list.next != LIST_POISON1
-       && !list_empty(&sel->list)){
-        list_del_init(&sel->list);
-    }
-}
-
-/** Add a selector to a select set.
- * The selector is closed if it has no 'select' function,
- * or it has one and it returns an error.
- *
- * @param sel selector
- * @param set select set
- */
-int Selector_select(Selector *sel, SelectSet *set){
-    int err = -EINVAL;
-    dprintf(">\n");
-    if(sel->select){
-        err = sel->select(sel, set);
-    }
-    if(err){
-        Selector_close(sel);
-    }
-    return err;
-}
-
-/** Call a selector with a select set.
- * The selector is closed if it has no 'selected' function,
- * or it has one and it returns an error.
- *
- * @param sel selector
- * @param set select set
- */
-int Selector_selected(Selector *sel, SelectSet *set){
-    int err = -EINVAL;
-    dprintf(">\n");
-    if(sel->selected){
-        err = sel->selected(sel, set);
-    }
-    if(err){
-        Selector_close(sel);
-    }
-    return err;
-}
-
-int conn_select_fn(Selector *sel, SelectSet *set){
-    int err = -EINVAL;
-    Conn *conn = sel->data;
-
-    dprintf(">\n");
-    if(conn){
-        err = 0;
-        SelectSet_add(set, conn->sock, conn->mode);
-    }
-    return err;
-}
-
-int conn_selected_fn(Selector *sel, SelectSet *set){
-    int err = -EINVAL;
-    Conn *conn = sel->data;
-
-    dprintf(">\n");
-    if(conn){
-        err = Conn_handle(conn, set);
-    }
-    return err;
-}
-
-void conn_close_fn(Selector *sel){
-    Conn *conn = sel->data;
-    
-    wprintf("> sel=%p\n", sel);
-    if(conn){
-        Conn_close(conn);
-    }
-}
-
-void Selector_conn_init(Selector *sel, Conn *conn,
-                        int mode, void *data,
-                        int (*fn)(struct Conn *conn, int mode)){
-    conn->mode = SELECT_READ;
-    conn->data = data;
-    conn->fn = fn;
-    sel->data = conn;
-    sel->select = conn_select_fn;
-    sel->close  = conn_close_fn;
-    sel->selected = conn_selected_fn;
-}
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/selector.h
--- a/tools/vnet/vnetd/selector.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _VNETD_SELECTOR_H_
-#define _VNETD_SELECTOR_H_
-
-#include "list.h"
-#include "select.h"
-
-struct Conn;
-
-typedef struct Selector {
-
-    /** List the selector is linked into (if any). */
-    struct list_head list;
-
-    /** Function called by Selector_select() to add a selector to a select set.
-     * The selector is closed if this returns an error (non-zero).
-     */
-    int (*select)(struct Selector *sel, struct SelectSet *set);
-
-    /** Function called by Selector_selected() to notify a selector of select 
set.
-     * The selector is closed if this returns an error (non-zero).
-     */
-    int (*selected)(struct Selector *sel, struct SelectSet *set);
-
-    /** Function called by Selector_close() to close a selector.
-     */
-    void (*close)(struct Selector *sel);
-
-    /** User data. */
-    void *data;
-
-} Selector;
-
-void Selector_init(struct Selector *sel);
-void Selector_close(struct Selector *sel);
-int Selector_select(struct Selector *sel, struct SelectSet *set);
-int Selector_selected(struct Selector *sel, struct SelectSet *set);
-
-int conn_select_fn(struct Selector *sel, struct SelectSet *set);
-int conn_selected_fn(struct Selector *sel, struct SelectSet *set);
-void conn_close_fn(struct Selector *sel);
-void Selector_conn_init(struct Selector *sel, struct Conn *conn,
-                        int mode, void *data,
-                        int (*fn)(struct Conn *conn, int mode));
-
-#endif /* _VNETD_SELECTOR_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/skbuff.c
--- a/tools/vnet/vnetd/skbuff.c Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,530 +0,0 @@
-/*
- *     Routines having to do with the 'struct sk_buff' memory handlers.
- *
- *     Authors:        Alan Cox <iiitac@xxxxxxxxxxxxxx>
- *                     Florian La Roche <rzsfl@xxxxxxxxxxxx>
- *
- *     Fixes:
- *             Alan Cox        :       Fixed the worst of the load
- *                                     balancer bugs.
- *             Dave Platt      :       Interrupt stacking fix.
- *     Richard Kooijman        :       Timestamp fixes.
- *             Alan Cox        :       Changed buffer format.
- *             Alan Cox        :       destructor hook for AF_UNIX etc.
- *             Linus Torvalds  :       Better skb_clone.
- *             Alan Cox        :       Added skb_copy.
- *             Alan Cox        :       Added all the changed routines Linus
- *                                     only put in the headers
- *             Ray VanTassle   :       Fixed --skb->lock in free
- *             Alan Cox        :       skb_copy copy arp field
- *             Andi Kleen      :       slabified it.
- *             Robert Olsson   :       Removed skb_head_pool
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     as published by the Free Software Foundation; either version
- *     2 of the License, or (at your option) any later version.
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "allocate.h"
-#include "debug.h"
-#include "skbuff.h"
-
-#define SKB_DATA_ALIGN(size) ((((size) + 7) >> 3) << 3)
-
-/**
- *     skb_over_panic  -       private function
- *     @skb: buffer
- *     @sz: size
- *     @here: address
- *
- *     Out of line support code for skb_put(). Not user callable.
- */
-void skb_over_panic(struct sk_buff *skb, int sz, void *here)
-{
-        eprintf("skput:over: %p:%d put:%d\n", here, skb->len, sz);
-       BUG();
-}
-
-/**
- *     skb_under_panic -       private function
- *     @skb: buffer
- *     @sz: size
- *     @here: address
- *
- *     Out of line support code for skb_push(). Not user callable.
- */
-
-void skb_under_panic(struct sk_buff *skb, int sz, void *here)
-{
-        eprintf("skput:under: %p:%d put:%d\n", here, skb->len, sz);
-        BUG();
-}
-
-/**
- *     alloc_skb       -       allocate a network buffer
- *     @size: size to allocate
- *     @gfp_mask: allocation mask
- *
- *     Allocate a new &sk_buff. The returned buffer has no headroom and a
- *     tail room of size bytes. The object has a reference count of one.
- *     The return is the buffer. On a failure the return is %NULL.
- */
-struct sk_buff *alloc_skb(unsigned int size, int gfp_mask)
-{
-       struct sk_buff *skb;
-       u8 *data;
-
-       /* Get the HEAD */
-       skb = ALLOCATE(struct sk_buff);
-       if (!skb)
-               goto out;
-
-       /* Get the DATA. Size must match skb_add_mtu(). */
-       size = SKB_DATA_ALIGN(size);
-       data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
-       if (!data)
-               goto nodata;
-
-       memset(skb, 0, offsetof(struct sk_buff, truesize));
-       skb->truesize = size + sizeof(struct sk_buff);
-       atomic_set(&skb->users, 1);
-       skb->head = data;
-       skb->data = data;
-       skb->tail = data;
-       skb->end  = data + size;
-        skb->list = NULL;
-
-       atomic_set(&(skb_shinfo(skb)->dataref), 1);
-       skb_shinfo(skb)->nr_frags  = 0;
-       skb_shinfo(skb)->tso_size = 0;
-       skb_shinfo(skb)->tso_segs = 0;
-       skb_shinfo(skb)->frag_list = NULL;
-out:
-       return skb;
-nodata:
-       kfree(skb);
-       skb = NULL;
-       goto out;
-}
-
-
-void skb_release_data(struct sk_buff *skb)
-{
-        kfree(skb->head);
-}
-
-/*
- *     Free an skbuff by memory without cleaning the state.
- */
-void kfree_skbmem(struct sk_buff *skb)
-{
-       skb_release_data(skb);
-       kfree(skb);
-}
-
-/**
- *     __kfree_skb - private function
- *     @skb: buffer
- *
- *     Free an sk_buff. Release anything attached to the buffer.
- *     Clean the state. This is an internal helper function. Users should
- *     always call kfree_skb
- */
-
-void __kfree_skb(struct sk_buff *skb)
-{
-       if (skb->list) {
-               wprintf("Warning: kfree_skb passed an skb still "
-                        "on a list.\n");
-               //BUG();
-       }
-
-       if(skb->destructor) {
-               skb->destructor(skb);
-       }
-       kfree_skbmem(skb);
-}
-
-
-/**
- *     skb_clone       -       duplicate an sk_buff
- *     @skb: buffer to clone
- *     @gfp_mask: allocation priority
- *
- *     Duplicate an &sk_buff. The new one is not owned by a socket. Both
- *     copies share the same packet data but not structure. The new
- *     buffer has a reference count of 1. If the allocation fails the
- *     function returns %NULL otherwise the new buffer is returned.
- *
- *     If this function is called from an interrupt gfp_mask() must be
- *     %GFP_ATOMIC.
- */
-
-struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
-{
-    return pskb_copy(skb, gfp_mask);
-}
-
-static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
-{
-       /*
-        *      Shift between the two data areas in bytes
-        */
-       unsigned long offset = new->data - old->data;
-
-       new->list       = NULL;
-       new->protocol   = old->protocol;
-       new->h.raw      = old->h.raw + offset;
-       new->nh.raw     = old->nh.raw + offset;
-       new->mac.raw    = old->mac.raw + offset;
-       new->pkt_type   = old->pkt_type;
-       new->destructor = NULL;
-       atomic_set(&new->users, 1);
-}
-
-
-/**
- *     pskb_expand_head - reallocate header of &sk_buff
- *     @skb: buffer to reallocate
- *     @nhead: room to add at head
- *     @ntail: room to add at tail
- *     @gfp_mask: allocation priority
- *
- *     Expands (or creates identical copy, if &nhead and &ntail are zero)
- *     header of skb. &sk_buff itself is not changed. &sk_buff MUST have
- *     reference count of 1. Returns zero in the case of success or error,
- *     if expansion failed. In the last case, &sk_buff is not changed.
- *
- *     All the pointers pointing into skb header may change and must be
- *     reloaded after call to this function.
- */
-
-int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, int gfp_mask)
-{
-       u8 *data;
-       int size = nhead + (skb->end - skb->head) + ntail;
-       long off;
-
-       if (skb_shared(skb))
-               BUG();
-
-       size = SKB_DATA_ALIGN(size);
-
-       data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
-       if (!data)
-               goto nodata;
-
-       /* Copy only real data... and, alas, header. This should be
-        * optimized for the cases when header is void. */
-       memcpy(data + nhead, skb->head, skb->tail - skb->head);
-       memcpy(data + size, skb->end, sizeof(struct skb_shared_info));
-
-       skb_release_data(skb);
-
-       off = (data + nhead) - skb->head;
-
-       skb->head     = data;
-       skb->end      = data + size;
-       skb->data    += off;
-       skb->tail    += off;
-       skb->mac.raw += off;
-       skb->h.raw   += off;
-       skb->nh.raw  += off;
-       return 0;
-
-nodata:
-       return -ENOMEM;
-}
-
-struct sk_buff *pskb_copy(struct sk_buff *skb, int gfp_mask)
-{
-       /*
-        *      Allocate the copy buffer
-        */
-       struct sk_buff *n = alloc_skb(skb->end - skb->head, gfp_mask);
-
-       if (!n)
-               goto out;
-
-       /* Set the data pointer */
-       skb_reserve(n, skb->data - skb->head);
-       /* Set the tail pointer and length */
-       skb_put(n, skb_headlen(skb));
-       /* Copy the bytes */
-       memcpy(n->data, skb->data, n->len);
-
-       n->data_len  = skb->data_len;
-       n->len       = skb->len;
-
-       copy_skb_header(n, skb);
-out:
-       return n;
-}
-
-/* Make private copy of skb with writable head and some headroom */
-
-struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int 
headroom)
-{
-       struct sk_buff *skb2;
-       int delta = headroom - skb_headroom(skb);
-
-       if (delta <= 0)
-               skb2 = pskb_copy(skb, GFP_ATOMIC);
-       else {
-            skb2 = skb_copy_expand(skb, headroom, 0, GFP_ATOMIC);
-       }
-       return skb2;
-}
-
-
-/**
- *     skb_copy_expand -       copy and expand sk_buff
- *     @skb: buffer to copy
- *     @newheadroom: new free bytes at head
- *     @newtailroom: new free bytes at tail
- *     @gfp_mask: allocation priority
- *
- *     Make a copy of both an &sk_buff and its data and while doing so
- *     allocate additional space.
- *
- *     This is used when the caller wishes to modify the data and needs a
- *     private copy of the data to alter as well as more space for new fields.
- *     Returns %NULL on failure or the pointer to the buffer
- *     on success. The returned buffer has a reference count of 1.
- *
- *     You must pass %GFP_ATOMIC as the allocation priority if this function
- *     is called from an interrupt.
- *
- *     BUG ALERT: ip_summed is not copied. Why does this work? Is it used
- *     only by netfilter in the cases when checksum is recalculated? --ANK
- */
-struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
-                               int newheadroom, int newtailroom, int gfp_mask)
-{
-       /*
-        *      Allocate the copy buffer
-        */
-       struct sk_buff *n = alloc_skb(newheadroom + skb->len + newtailroom,
-                                     gfp_mask);
-       int head_copy_len, head_copy_off;
-
-       if (!n)
-               return NULL;
-
-       skb_reserve(n, newheadroom);
-
-       /* Set the tail pointer and length */
-       skb_put(n, skb->len);
-
-       head_copy_len = skb_headroom(skb);
-       head_copy_off = 0;
-       if (newheadroom <= head_copy_len)
-               head_copy_len = newheadroom;
-       else
-               head_copy_off = newheadroom - head_copy_len;
-
-       /* Copy the linear header and data. */
-       if (skb_copy_bits(skb, -head_copy_len, n->head + head_copy_off,
-                         skb->len + head_copy_len))
-               BUG();
-
-       copy_skb_header(n, skb);
-
-       return n;
-}
-
-
-/* Copy some data bits from skb to kernel buffer. */
-
-int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
-{
-       int copy;
-       int start = skb_headlen(skb);
-
-       if (offset > (int)skb->len - len)
-               goto fault;
-
-       /* Copy header. */
-       if ((copy = start - offset) > 0) {
-               if (copy > len)
-                       copy = len;
-               memcpy(to, skb->data + offset, copy);
-               if ((len -= copy) == 0)
-                       return 0;
-               offset += copy;
-               to     += copy;
-       }
-
-       if (!len)
-               return 0;
-
-fault:
-       return -EFAULT;
-}
-
-
-/**
- *     skb_dequeue - remove from the head of the queue
- *     @list: list to dequeue from
- *
- *     Remove the head of the list. The list lock is taken so the function
- *     may be used safely with other locking list functions. The head item is
- *     returned or %NULL if the list is empty.
- */
-
-struct sk_buff *skb_dequeue(struct sk_buff_head *list)
-{
-       unsigned long flags;
-       struct sk_buff *result;
-
-       spin_lock_irqsave(&list->lock, flags);
-       result = __skb_dequeue(list);
-       spin_unlock_irqrestore(&list->lock, flags);
-       return result;
-}
-
-/**
- *     skb_dequeue_tail - remove from the tail of the queue
- *     @list: list to dequeue from
- *
- *     Remove the tail of the list. The list lock is taken so the function
- *     may be used safely with other locking list functions. The tail item is
- *     returned or %NULL if the list is empty.
- */
-struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list)
-{
-       unsigned long flags;
-       struct sk_buff *result;
-
-       spin_lock_irqsave(&list->lock, flags);
-       result = __skb_dequeue_tail(list);
-       spin_unlock_irqrestore(&list->lock, flags);
-       return result;
-}
-
-/**
- *     skb_queue_purge - empty a list
- *     @list: list to empty
- *
- *     Delete all buffers on an &sk_buff list. Each buffer is removed from
- *     the list and one reference dropped. This function takes the list
- *     lock and is atomic with respect to other list locking functions.
- */
-void skb_queue_purge(struct sk_buff_head *list)
-{
-       struct sk_buff *skb;
-       while ((skb = skb_dequeue(list)) != NULL)
-               kfree_skb(skb);
-}
-
-/**
- *     skb_queue_head - queue a buffer at the list head
- *     @list: list to use
- *     @newsk: buffer to queue
- *
- *     Queue a buffer at the start of the list. This function takes the
- *     list lock and can be used safely with other locking &sk_buff functions
- *     safely.
- *
- *     A buffer cannot be placed on two lists at the same time.
- */
-void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&list->lock, flags);
-       __skb_queue_head(list, newsk);
-       spin_unlock_irqrestore(&list->lock, flags);
-}
-
-/**
- *     skb_queue_tail - queue a buffer at the list tail
- *     @list: list to use
- *     @newsk: buffer to queue
- *
- *     Queue a buffer at the tail of the list. This function takes the
- *     list lock and can be used safely with other locking &sk_buff functions
- *     safely.
- *
- *     A buffer cannot be placed on two lists at the same time.
- */
-void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&list->lock, flags);
-       __skb_queue_tail(list, newsk);
-       spin_unlock_irqrestore(&list->lock, flags);
-}
-/**
- *     skb_unlink      -       remove a buffer from a list
- *     @skb: buffer to remove
- *
- *     Place a packet after a given packet in a list. The list locks are taken
- *     and this function is atomic with respect to other list locked calls
- *
- *     Works even without knowing the list it is sitting on, which can be
- *     handy at times. It also means that THE LIST MUST EXIST when you
- *     unlink. Thus a list must have its contents unlinked before it is
- *     destroyed.
- */
-void skb_unlink(struct sk_buff *skb)
-{
-       struct sk_buff_head *list = skb->list;
-
-       if (list) {
-               unsigned long flags;
-
-               spin_lock_irqsave(&list->lock, flags);
-               if (skb->list == list)
-                       __skb_unlink(skb, skb->list);
-               spin_unlock_irqrestore(&list->lock, flags);
-       }
-}
-
-
-/**
- *     skb_append      -       append a buffer
- *     @old: buffer to insert after
- *     @newsk: buffer to insert
- *
- *     Place a packet after a given packet in a list. The list locks are taken
- *     and this function is atomic with respect to other list locked calls.
- *     A buffer cannot be placed on two lists at the same time.
- */
-
-void skb_append(struct sk_buff *old, struct sk_buff *newsk)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&old->list->lock, flags);
-       __skb_append(old, newsk);
-       spin_unlock_irqrestore(&old->list->lock, flags);
-}
-
-
-/**
- *     skb_insert      -       insert a buffer
- *     @old: buffer to insert before
- *     @newsk: buffer to insert
- *
- *     Place a packet before a given packet in a list. The list locks are taken
- *     and this function is atomic with respect to other list locked calls
- *     A buffer cannot be placed on two lists at the same time.
- */
-
-void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&old->list->lock, flags);
-       __skb_insert(newsk, old->prev, old, old->list);
-       spin_unlock_irqrestore(&old->list->lock, flags);
-}
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/skbuff.h
--- a/tools/vnet/vnetd/skbuff.h Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,538 +0,0 @@
-/*
- *     Definitions for the 'struct sk_buff' memory handlers.
- *
- *     Authors:
- *             Alan Cox, <gw4pts@xxxxxxxxxxxxxxx>
- *             Florian La Roche, <rzsfl@xxxxxxxxxxxx>
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     as published by the Free Software Foundation; either version
- *     2 of the License, or (at your option) any later version.
- */
-
-#ifndef _VNET_SKBUFF_H
-#define _VNET_SKBUFF_H
-
-#include "sys_kernel.h"
-#include "spinlock.h"
-
-struct sk_buff;
-
-struct sk_buff_head {
-       /* These two members must be first. */
-       struct sk_buff  *next;
-       struct sk_buff  *prev;
-
-       __u32           qlen;
-       spinlock_t      lock;
-};
-
-
-
-#define MAX_SKB_FRAGS 8 // (65536/PAGE_SIZE + 2)
-
-typedef struct skb_frag_struct skb_frag_t;
-
-struct skb_frag_struct {
-    //struct page *page;
-    void *page;
-       __u16 page_offset;
-       __u16 size;
-};
-
-/* This data is invariant across clones and lives at
- * the end of the header data, ie. at skb->end.
- */
-struct skb_shared_info {
-       atomic_t        dataref;
-       unsigned int    nr_frags;
-       unsigned short  tso_size;
-       unsigned short  tso_segs;
-       struct sk_buff  *frag_list;
-       skb_frag_t      frags[MAX_SKB_FRAGS];
-};
-
-struct sk_buff {
-       /* These two members must be first. */
-       struct sk_buff          *next;
-       struct sk_buff          *prev;
-
-       struct sk_buff_head     *list;
-        struct net_device       *dev;
-
-       union {
-               struct tcphdr   *th;
-               struct udphdr   *uh;
-               struct icmphdr  *icmph;
-               struct igmphdr  *igmph;
-               struct iphdr    *ipiph;
-               struct ipv6hdr  *ipv6h;
-               unsigned char   *raw;
-       } h;
-
-       union {
-               struct iphdr    *iph;
-               struct ipv6hdr  *ipv6h;
-               struct arphdr   *arph;
-               unsigned char   *raw;
-       } nh;
-
-       union {
-               unsigned char   *raw;
-       } mac;
-
-       unsigned int            len,
-                                data_len;
-    unsigned char              pkt_type;
-       unsigned short          protocol;
-
-       void                    (*destructor)(struct sk_buff *skb);
-
-       /* These elements must be at the end, see alloc_skb() for details.  */
-       unsigned int            truesize;
-       atomic_t                users;
-       unsigned char           *head,
-                               *data,
-                               *tail,
-                               *end;
-};
-
-extern void          skb_over_panic(struct sk_buff *skb, int len,
-                                    void *here);
-extern void          skb_under_panic(struct sk_buff *skb, int len,
-                                     void *here);
-
-#define skb_shinfo(SKB)                ((struct skb_shared_info *)((SKB)->end))
-
-extern void           __kfree_skb(struct sk_buff *skb);
-extern struct sk_buff *alloc_skb(unsigned int size, int priority);
-extern struct sk_buff *skb_clone(struct sk_buff *skb, int priority);
-extern struct sk_buff *pskb_copy(struct sk_buff *skb, int gfp_mask);
-extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb,
-                                           unsigned int headroom);
-extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
-                                      int newheadroom, int newtailroom,
-                                      int priority);
-
-extern int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int 
len);
-
-static inline void kfree_skb(struct sk_buff *skb)
-{
-       if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users))
-               __kfree_skb(skb);
-}
-
-static inline void dev_kfree_skb(struct sk_buff *skb)
-{
-        kfree_skb(skb);
-}
-
-static inline int skb_cloned(const struct sk_buff *skb)
-{
-        return 0;
-}
-
-/**
- *     skb_shared - is the buffer shared
- *     @skb: buffer to check
- *
- *     Returns true if more than one person has a reference to this
- *     buffer.
- */
-static inline int skb_shared(const struct sk_buff *skb)
-{
-       return atomic_read(&skb->users) != 1;
-}
-
-/**
- *     skb_peek
- *     @list_: list to peek at
- *
- *     Peek an &sk_buff. Unlike most other operations you _MUST_
- *     be careful with this one. A peek leaves the buffer on the
- *     list and someone else may run off with it. You must hold
- *     the appropriate locks or have a private queue to do this.
- *
- *     Returns %NULL for an empty list or a pointer to the head element.
- *     The reference count is not incremented and the reference is therefore
- *     volatile. Use with caution.
- */
-static inline struct sk_buff *skb_peek(struct sk_buff_head *list_)
-{
-       struct sk_buff *list = ((struct sk_buff *)list_)->next;
-       if (list == (struct sk_buff *)list_)
-               list = NULL;
-       return list;
-}
-
-/**
- *     skb_peek_tail
- *     @list_: list to peek at
- *
- *     Peek an &sk_buff. Unlike most other operations you _MUST_
- *     be careful with this one. A peek leaves the buffer on the
- *     list and someone else may run off with it. You must hold
- *     the appropriate locks or have a private queue to do this.
- *
- *     Returns %NULL for an empty list or a pointer to the tail element.
- *     The reference count is not incremented and the reference is therefore
- *     volatile. Use with caution.
- */
-static inline struct sk_buff *skb_peek_tail(struct sk_buff_head *list_)
-{
-       struct sk_buff *list = ((struct sk_buff *)list_)->prev;
-       if (list == (struct sk_buff *)list_)
-               list = NULL;
-       return list;
-}
-
-/**
- *     skb_queue_len   - get queue length
- *     @list_: list to measure
- *
- *     Return the length of an &sk_buff queue.
- */
-static inline __u32 skb_queue_len(const struct sk_buff_head *list_)
-{
-       return list_->qlen;
-}
-
-static inline void skb_queue_head_init(struct sk_buff_head *list)
-{
-       spin_lock_init(&list->lock);
-       list->prev = list->next = (struct sk_buff *)list;
-       list->qlen = 0;
-}
-
-/*
- *     Insert an sk_buff at the start of a list.
- *
- *     The "__skb_xxxx()" functions are the non-atomic ones that
- *     can only be called with interrupts disabled.
- */
-
-/**
- *     __skb_queue_head - queue a buffer at the list head
- *     @list: list to use
- *     @newsk: buffer to queue
- *
- *     Queue a buffer at the start of a list. This function takes no locks
- *     and you must therefore hold required locks before calling it.
- *
- *     A buffer cannot be placed on two lists at the same time.
- */
-extern void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk);
-static inline void __skb_queue_head(struct sk_buff_head *list,
-                                   struct sk_buff *newsk)
-{
-       struct sk_buff *prev, *next;
-
-       newsk->list = list;
-       list->qlen++;
-       prev = (struct sk_buff *)list;
-       next = prev->next;
-       newsk->next = next;
-       newsk->prev = prev;
-       next->prev  = prev->next = newsk;
-}
-
-/**
- *     __skb_queue_tail - queue a buffer at the list tail
- *     @list: list to use
- *     @newsk: buffer to queue
- *
- *     Queue a buffer at the end of a list. This function takes no locks
- *     and you must therefore hold required locks before calling it.
- *
- *     A buffer cannot be placed on two lists at the same time.
- */
-extern void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk);
-static inline void __skb_queue_tail(struct sk_buff_head *list,
-                                  struct sk_buff *newsk)
-{
-       struct sk_buff *prev, *next;
-
-       newsk->list = list;
-       list->qlen++;
-       next = (struct sk_buff *)list;
-       prev = next->prev;
-       newsk->next = next;
-       newsk->prev = prev;
-       next->prev  = prev->next = newsk;
-}
-
-
-/**
- *     __skb_dequeue - remove from the head of the queue
- *     @list: list to dequeue from
- *
- *     Remove the head of the list. This function does not take any locks
- *     so must be used with appropriate locks held only. The head item is
- *     returned or %NULL if the list is empty.
- */
-extern struct sk_buff *skb_dequeue(struct sk_buff_head *list);
-static inline struct sk_buff *__skb_dequeue(struct sk_buff_head *list)
-{
-       struct sk_buff *next, *prev, *result;
-
-       prev = (struct sk_buff *) list;
-       next = prev->next;
-       result = NULL;
-       if (next != prev) {
-               result       = next;
-               next         = next->next;
-               list->qlen--;
-               next->prev   = prev;
-               prev->next   = next;
-               result->next = result->prev = NULL;
-               result->list = NULL;
-       }
-       return result;
-}
-
-
-/*
- *     Insert a packet on a list.
- */
-extern void        skb_insert(struct sk_buff *old, struct sk_buff *newsk);
-static inline void __skb_insert(struct sk_buff *newsk,
-                               struct sk_buff *prev, struct sk_buff *next,
-                               struct sk_buff_head *list)
-{
-       newsk->next = next;
-       newsk->prev = prev;
-       next->prev  = prev->next = newsk;
-       newsk->list = list;
-       list->qlen++;
-}
-
-/*
- *     Place a packet after a given packet in a list.
- */
-extern void       skb_append(struct sk_buff *old, struct sk_buff *newsk);
-static inline void __skb_append(struct sk_buff *old, struct sk_buff *newsk)
-{
-       __skb_insert(newsk, old, old->next, old->list);
-}
-
-/*
- * remove sk_buff from list. _Must_ be called atomically, and with
- * the list known..
- */
-extern void       skb_unlink(struct sk_buff *skb);
-static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
-{
-       struct sk_buff *next, *prev;
-
-       list->qlen--;
-       next       = skb->next;
-       prev       = skb->prev;
-       skb->next  = skb->prev = NULL;
-       skb->list  = NULL;
-       next->prev = prev;
-       prev->next = next;
-}
-
-
-/* XXX: more streamlined implementation */
-
-/**
- *     __skb_dequeue_tail - remove from the tail of the queue
- *     @list: list to dequeue from
- *
- *     Remove the tail of the list. This function does not take any locks
- *     so must be used with appropriate locks held only. The tail item is
- *     returned or %NULL if the list is empty.
- */
-extern struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list);
-static inline struct sk_buff *__skb_dequeue_tail(struct sk_buff_head *list)
-{
-       struct sk_buff *skb = skb_peek_tail(list);
-       if (skb)
-               __skb_unlink(skb, list);
-       return skb;
-}
-
-
-/*
- *     Add data to an sk_buff
- */
-static inline unsigned char *__skb_put(struct sk_buff *skb, unsigned int len)
-{
-       unsigned char *tmp = skb->tail;
-       skb->tail += len;
-       skb->len  += len;
-       return tmp;
-}
-
-/**
- *     skb_put - add data to a buffer
- *     @skb: buffer to use
- *     @len: amount of data to add
- *
- *     This function extends the used data area of the buffer. If this would
- *     exceed the total buffer size the kernel will panic. A pointer to the
- *     first byte of the extra data is returned.
- */
-static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
-{
-       unsigned char *tmp = skb->tail;
-       skb->tail += len;
-       skb->len  += len;
-       if (unlikely(skb->tail>skb->end))
-               skb_over_panic(skb, len, current_text_addr());
-       return tmp;
-}
-
-static inline unsigned char *__skb_push(struct sk_buff *skb, unsigned int len)
-{
-       skb->data -= len;
-       skb->len  += len;
-       return skb->data;
-}
-
-/**
- *     skb_push - add data to the start of a buffer
- *     @skb: buffer to use
- *     @len: amount of data to add
- *
- *     This function extends the used data area of the buffer at the buffer
- *     start. If this would exceed the total buffer headroom the kernel will
- *     panic. A pointer to the first byte of the extra data is returned.
- */
-static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
-{
-       skb->data -= len;
-       skb->len  += len;
-       if (unlikely(skb->data<skb->head)){
-               skb_under_panic(skb, len, current_text_addr());
-        }
-       return skb->data;
-}
-
-static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
-{
-       skb->len -= len;
-       //BUG_ON(skb->len < skb->data_len);
-       return skb->data += len;
-}
-
-/**
- *     skb_pull - remove data from the start of a buffer
- *     @skb: buffer to use
- *     @len: amount of data to remove
- *
- *     This function removes data from the start of a buffer, returning
- *     the memory to the headroom. A pointer to the next data in the buffer
- *     is returned. Once the data has been pulled future pushes will overwrite
- *     the old data.
- */
-static inline unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
-{
-       return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
-}
-
-static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
-{
-    return (len <= skb->len);
-}
-
-static inline unsigned int skb_headlen(const struct sk_buff *skb)
-{
-       return skb->len - skb->data_len;
-}
-
-/**
- *     skb_headroom - bytes at buffer head
- *     @skb: buffer to check
- *
- *     Return the number of bytes of free space at the head of an &sk_buff.
- */
-static inline int skb_headroom(const struct sk_buff *skb)
-{
-       return skb->data - skb->head;
-}
-
-/**
- *     skb_tailroom - bytes at buffer end
- *     @skb: buffer to check
- *
- *     Return the number of bytes of free space at the tail of an sk_buff
- */
-static inline int skb_tailroom(const struct sk_buff *skb)
-{
-       return skb->end - skb->tail;
-}
-
-/**
- *     skb_reserve - adjust headroom
- *     @skb: buffer to alter
- *     @len: bytes to move
- *
- *     Increase the headroom of an empty &sk_buff by reducing the tail
- *     room. This is only allowed for an empty buffer.
- */
-static inline void skb_reserve(struct sk_buff *skb, unsigned int len)
-{
-       skb->data += len;
-       skb->tail += len;
-}
-
-/**
- *     __skb_queue_purge - empty a list
- *     @list: list to empty
- *
- *     Delete all buffers on an &sk_buff list. Each buffer is removed from
- *     the list and one reference dropped. This function does not take the
- *     list lock and the caller must hold the relevant locks to use it.
- */
-extern void skb_queue_purge(struct sk_buff_head *list);
-static inline void __skb_queue_purge(struct sk_buff_head *list)
-{
-       struct sk_buff *skb;
-       while ((skb = __skb_dequeue(list)) != NULL)
-               kfree_skb(skb);
-}
-
-/**
- *     __dev_alloc_skb - allocate an skbuff for sending
- *     @length: length to allocate
- *     @gfp_mask: get_free_pages mask, passed to alloc_skb
- *
- *     Allocate a new &sk_buff and assign it a usage count of one. The
- *     buffer has unspecified headroom built in. Users should allocate
- *     the headroom they think they need without accounting for the
- *     built in space. The built in space is used for optimisations.
- *
- *     %NULL is returned in there is no free memory.
- */
-static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
-                                             int gfp_mask)
-{
-       struct sk_buff *skb = alloc_skb(length + 16, gfp_mask);
-       if (likely(skb))
-               skb_reserve(skb, 16);
-       return skb;
-}
-
-/**
- *     dev_alloc_skb - allocate an skbuff for sending
- *     @length: length to allocate
- *
- *     Allocate a new &sk_buff and assign it a usage count of one. The
- *     buffer has unspecified headroom built in. Users should allocate
- *     the headroom they think they need without accounting for the
- *     built in space. The built in space is used for optimisations.
- *
- *     %NULL is returned in there is no free memory. Although this function
- *     allocates memory it can be called from an interrupt.
- */
-static inline struct sk_buff *dev_alloc_skb(unsigned int length)
-{
-       return __dev_alloc_skb(length, GFP_ATOMIC);
-}
-
-#define MULTICAST(x)   (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
-
-#endif /* _VNET_SKBUFF_H */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/spinlock.c
--- a/tools/vnet/vnetd/spinlock.c       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-#include "spinlock.h"
-
-int atomic_read(const atomic_t *v){
-    return v->val;
-}
-
-int atomic_dec_and_test(atomic_t *v){
-    if(v->val > 0){
-        v->val--;
-        return v->val == 0;
-    }
-    return 0;
-}
-
-void atomic_inc(atomic_t *v){
-    v->val++;
-}
-
-void atomic_set(atomic_t *v, int x){
-    v->val = x;
-}
-
-void spin_lock_init(spinlock_t *lock){
-    *lock = (spinlock_t){};
-}
-
-unsigned long _spin_lock_irqsave(spinlock_t *lock){
-    lock->val++;
-    return 0;
-}
-
-void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags){
-    lock->val--;
-}
-
-unsigned long _read_lock_irqsave(rwlock_t *lock){
-    lock->val++;
-    return 0;
-}
-
-void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags){
-    lock->val--;
-}
-
-unsigned long _write_lock_irqsave(rwlock_t *lock){
-    lock->val++;
-    return 0;
-}
-
-void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags){
-    lock->val--;
-}
-
-void init_MUTEX(struct semaphore *sem){
-    *sem = (struct semaphore){ .count = 1 };
-}
-
-void down(struct semaphore *sem){
-    sem->count--;
-}
-
-void up(struct semaphore *sem){
-    sem->count++;
-}
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/spinlock.h
--- a/tools/vnet/vnetd/spinlock.h       Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-#ifndef _VNET_SPINLOCK_H_
-#define _VNET_SPINLOCK_H_
-
-typedef struct atomic_t {
-    unsigned val;
-} atomic_t;
-
-int atomic_read(const atomic_t *v);
-int atomic_dec_and_test(atomic_t *v);
-void atomic_inc(atomic_t *v);
-void atomic_set(atomic_t *v, int x);
-
-typedef struct spinlock_t {
-    unsigned val;
-} spinlock_t;
-
-#define SPIN_LOCK_UNLOCKED ((struct spinlock_t){})
-
-void spin_lock_init(spinlock_t *lock);
-
-unsigned long _spin_lock_irqsave(spinlock_t *lock);
-#define spin_lock_irqsave(lock, flags) flags = _spin_lock_irqsave(lock)
-void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
-
-typedef struct rwlock_t{
-    unsigned val;
-} rwlock_t;
-
-#define RW_LOCK_UNLOCKED ((struct rwlock_t){})
-
-unsigned long _read_lock_irqsave(rwlock_t *lock);
-#define read_lock_irqsave(lock, flags) flags = _read_lock_irqsave(lock)
-void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
-
-unsigned long _write_lock_irqsave(rwlock_t *lock);
-#define write_lock_irqsave(lock, flags)        flags = 
_write_lock_irqsave(lock)
-void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
-
-struct semaphore {
-    int count;
-};
-
-void init_MUTEX(struct semaphore *sem);
-void down(struct semaphore *sem);
-void up(struct semaphore *sem);
-
-#endif /* ! _VNET_SPINLOCK_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/sys_kernel.h
--- a/tools/vnet/vnetd/sys_kernel.h     Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef _VNET_SYS_KERNEL_H_
-#define _VNET_SYS_KERNEL_H_
-
-/** @file Compatibility replacements for some kernel defs.
- */
-
-#include <assert.h>
-#include <asm/types.h>
-//#include <sys/types.h>
-#include <unistd.h>
-
-#define printk              printf
-
-#define likely(x)           x
-#define unlikely(x)         x
-#define current_text_addr() NULL
-
-#define BUG_ON(x)           assert(x)    
-#define BUG()               BUG_ON(1)
-#define kmalloc(n, m)       allocate_type(n, m)
-#define kfree(p)            deallocate(p)
-#define in_atomic()         0
-
-#define __init
-#define __exit
-
-#define module_init(x)
-#define module_exit(x)
-#define MODULE_LICENSE(x)
-#define MODULE_PARM(v, t)
-#define module_param(v, t, s)
-#define MODULE_PARM_DESC(v, s)
-
-enum {
-    GFP_USER,
-    GFP_ATOMIC,
-    GFP_KERNEL,
-};
-
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
-#include "allocate.h"
-
-#endif /* ! _VNET_SYS_KERNEL_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/timer.c
--- a/tools/vnet/vnetd/timer.c  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include "allocate.h"
-#include "timer.h"
-
-#define MODULE_NAME "TIMER"
-#undef DEBUG
-#define DEBUG 1
-#include "debug.h"
-
-static Timer *timers = NULL;
-
-/** Get the time now as a double (in seconds).
- * Returns zero if could not get the time.
- *
- * @return time now
- */
-double time_now(void){
-    struct timeval time;
-    if(gettimeofday(&time, NULL)) return 0.0;
-    return (double)time.tv_sec + (1.0e-6 * (double)time.tv_usec);
-}
-
-/** Set the process real-time timer to go off at a given expiry time.
- * The timer will not be set to go off in less than 10 ms
- * (even if the expiry time is sooner, or in the past).
- *
- * @param expiry time (in seconds)
- * @return 0 on success, error code otherwise
- */
-static int itimer_set(double expiry){
-    struct itimerval val = {};
-    struct itimerval old = {};
-    double now, delay;
-    int err = 0;
-
-    if(expiry == 0.0){
-        val.it_value.tv_sec = 0;
-        val.it_value.tv_usec = 0;
-    } else {
-        now = time_now();
-        delay = expiry - now;
-        if(delay < 0.01) delay = 0.01;
-        val.it_value.tv_sec = (long)delay;
-        val.it_value.tv_usec = (long)((delay - (double)(long)delay) * 1.0e6);
-    }
-    err = setitimer(ITIMER_REAL, &val, &old);
-    return err;
-}
-
-void Timer_free(Timer *z){
-#ifndef USE_GC
-    if(!z) return;
-    deallocate(z);
-#endif
-}
-
-/** Process any expired timers.
- * Calls the functions of expired timers and removes them
- * from the timer list.
- * Reschedules the interval timer for the earliest expiring timer
- * (if any).
- *
- * Should not be called from within the SIGALRM handler - set
- * a flag there and call it later.
- *
- * @return 0 on success, error code otherwise.
- */
-int process_timers(void){
-    double now = time_now();
-    Timer *curr, *next;
-    for(curr = timers; curr; curr = next){
-        next = curr->next;
-        if(curr->expiry > now) break;
-        if(curr->fn) curr->fn(curr->data);
-    }
-    timers = curr;
-    itimer_set((curr ? curr->expiry : 0));
-    return 0;
-}
-
-void Timer_add(Timer *timer){
-    // Insert timer in list ordered by (increasing) expiry time.
-    Timer *prev, *curr, *next;
-    prev = NULL;
-    for(curr = timers; curr; prev = curr, curr = next){
-        next = curr->next;
-        if(timer->expiry < curr->expiry) break;
-    }
-    if(prev){
-        prev->next = timer;
-    } else {
-        timers = timer;
-    }
-    timer->next = curr;
-
-    // Set interval timer to go off for earliest expiry time.
-    itimer_set(timer->expiry);
-}
-
-Timer * Timer_set(double delay, TimerFn *fn, unsigned long data){
-    // Get 'now'.
-    double now = time_now();
-    Timer *timer = NULL;
-    timer = ALLOCATE(Timer);
-    if(!timer) goto exit;
-    // Add delay to now to get expiry time.
-    timer->expiry = now + delay;
-    timer->fn = fn;
-    timer->data = data;
-
-    Timer_add(timer);
-  exit:
-    return timer;
-}
-
-int Timer_cancel(Timer *timer){
-    // Remove timer from list.
-    int err = -ENOENT;
-    Timer *prev, *curr, *next;
-    for(prev = NULL, curr = timers; curr; prev = curr, curr = next){
-        next = curr->next;
-        if(curr == timer){
-            err = 0;
-            if(prev){
-                prev->next = curr->next;
-            } else {
-                timers = curr->next;
-            }
-            curr->next = NULL;
-            break;
-        }
-    }
-    return err;
-}
-
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/timer.h
--- a/tools/vnet/vnetd/timer.h  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _VNET_TIMER_H_
-#define _VNET_TIMER_H_
-
-struct Timer;
-
-typedef void TimerFn(unsigned long);
-
-typedef struct Timer {
-    struct Timer *next;
-    TimerFn *fn;
-    unsigned long data;
-    double expiry;
-} Timer;
-
-extern void timer_alarm(void);
-extern double time_now(void);
-extern int process_timers(void);
-extern Timer * Timer_set(double delay, TimerFn *fn, unsigned long data);
-extern void Timer_add(Timer *timer);
-extern int Timer_cancel(Timer *timer);
-
-#endif /* ! _VNET_TIMER_H_ */
diff -r 223f61702bda -r 28f04a659506 tools/vnet/vnetd/vnetd.c
--- a/tools/vnet/vnetd/vnetd.c  Mon Mar 21 14:41:45 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1200 +0,0 @@
-/*
- * Copyright (C) 2005, 2006 Mike Wray <mike.wray@xxxxxx>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <getopt.h>
-#include <errno.h>
-#include <time.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <string.h>
-
-#include <signal.h>
-#include <sys/wait.h>
-#include <sys/select.h>
-
-#include <asm/types.h> // For __u32 etc.
-
-#include <linux/ip.h>  // For struct iphdr.
-#include <linux/udp.h> // For struct udphdr.
-
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/if_tun.h> 
-
-#include "sys_kernel.h"
-#include "skbuff.h"
-#include "spinlock.h"
-
-#include "allocate.h"
-
-#include "file_stream.h"
-#include "string_stream.h"
-#include "socket_stream.h"
-#include "sys_net.h"
-
-#include "enum.h"
-#include "sxpr.h"
-#include "sxpr_parser.h"
-
-#include "connection.h"
-#include "select.h"
-#include "timer.h"
-
-#include "if_etherip.h"
-#include "if_varp.h"
-#include "varp.h"
-#include "vnet.h"
-#include "vnet_dev.h"
-#include "vnet_eval.h"
-#include "vnet_forward.h"
-#include "tunnel.h"
-#include "etherip.h"
-#include "sxpr_util.h"
-
-#define MODULE_NAME "VNETD"
-#define DEBUG 1
-#undef DEBUG
-#include "debug.h"
-
-#define PROGRAM "vnetd"
-#define VERSION "1.0"
-
-typedef struct Vnetd {
-    unsigned long port;
-    int ttl;
-    int verbose;
-    int etherip;
-
-    int udp_sock;
-    struct sockaddr_in udp_sock_addr;
-    int mcast_sock;
-    struct sockaddr_in mcast_sock_addr;
-    int etherip_sock;
-    struct sockaddr_in etherip_sock_addr;
-    int unix_sock;
-    char *unix_path;
-
-    int raw_sock;
-
-    struct sockaddr_in ucast_addr;
-    struct sockaddr_in mcast_addr;
-
-    HashTable *vnet_table;
-
-    ConnList *conns;
-
-} Vnetd;
-
-Vnetd _vnetd = {}, *vnetd = &_vnetd;
-
-uint32_t vnetd_intf_addr(Vnetd *vnetd){
-    return vnetd->ucast_addr.sin_addr.s_addr;
-}
-
-uint32_t vnetd_mcast_addr(Vnetd *vnetd){
-    return vnetd->mcast_addr.sin_addr.s_addr;
-}
-
-void vnetd_set_mcast_addr(Vnetd *vnetd, uint32_t addr){
-    varp_mcast_addr = addr;
-    vnetd->mcast_addr.sin_addr.s_addr = addr;
-}
-
-uint16_t vnetd_mcast_port(Vnetd *vnetd){
-    return vnetd->mcast_addr.sin_port;
-}
-
-uint32_t vnetd_addr(void){
-    return vnetd_intf_addr(vnetd);
-}
-
-/** Open tap device.
- */
-int tap_open(struct net_device *dev){
-    int err;
-    /* IFF_TAP      : Ethernet tap device.
-     * IFF_NO_PI    : Don't add packet info struct when reading.
-     * IFF_ONE_QUEUE: Drop packets when the dev queue is full. The driver uses
-     *                the queue size from the device, which defaults to 1000 
for etherdev.
-     *                If not set the driver stops the device queue when it 
goes over
-     *                TUN_READQ_SIZE, which is 10. Broken - makes the device 
stall
-     *                under load.
-     */
-    struct ifreq ifr = { };
-    ifr.ifr_flags = (IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE);
-
-    dprintf(">\n");
-    dev->tapfd = open("/dev/net/tun", O_RDWR);
-    if(dev->tapfd < 0){
-        err = -errno;
-        perror("open");
-        goto exit;
-    }
-    strcpy(ifr.ifr_name, dev->name);
-    err = ioctl(dev->tapfd, TUNSETIFF, (void *)&ifr);
-    if(err < 0){
-        err = -errno;
-        perror("ioctl");
-        goto exit;
-    }
-    strcpy(dev->name, ifr.ifr_name);
-    dprintf("> dev=%s\n", dev->name);
-    // Make it non-blocking.
-    fcntl(dev->tapfd, F_SETFL, O_NONBLOCK);
-
-  exit:
-    if(err && (dev->tapfd >= 0)){
-        close(dev->tapfd);
-        dev->tapfd = -1;
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-/** Close tap device.
- */
-int tap_close(struct net_device *dev){
-    int err = 0;
-
-    if(dev->tapfd >= 0){
-        err = close(dev->tapfd);
-        dev->tapfd = -1;
-    }
-    return err;
-}
-
-/** Open vnif tap device for a vnet.
- */
-int vnet_dev_add(struct Vnet *vnet){
-    int err = 0;
-    struct net_device *dev = ALLOCATE(struct net_device);
-    strcpy(dev->name, vnet->device);
-    err = tap_open(dev);
-    if(err){
-        wprintf("> Unable to open tap device.\n"
-                "The tun module must be loaded and\n"
-                "the vnet kernel module must not be loaded.\n");
-        deallocate(dev);
-        goto exit;
-    }
-    vnet->dev = dev;
-  exit:
-    return err;
-}
-
-/** Close vnif tap device for a vnet.
- */
-void vnet_dev_remove(struct Vnet *vnet){
-    if(vnet->dev){
-        tap_close(vnet->dev);
-        deallocate(vnet->dev);
-        vnet->dev = NULL;
-    }
-}
-
-/** Receive decapsulated ethernet packet on skb->dev.
- * Always succeeds. The skb must not be referred to after
- * this is called.
- */
-int netif_rx(struct sk_buff *skb){
-    int err = 0, n, k;
-    struct net_device *dev = skb->dev;
-    if(!dev){
-        err = -ENODEV;
-        goto exit;
-    }
-    n = skb->tail - skb->mac.raw;
-    k = write(dev->tapfd, skb->mac.raw, n);
-    if(k < 0){
-        err = -errno;
-        perror("write");
-    } else if(k < n){
-        //todo: What?
-    }
-  exit:
-    kfree_skb(skb);
-    return err;
-}
-
-static const int SKB_SIZE = 1700;
-
-struct sk_buff *skb_new(void){
-    return alloc_skb(SKB_SIZE, GFP_ATOMIC);
-}
-
-/** Receive a packet and fill-in source and destination addresses.
- * Just like recvfrom() but adds the destination address.
- * The socket must have the IP_PKTINFO option set so that the
- * destination address information is available.
- *
- * @param sock socket
- * @param buf receive buffer
- * @param len size of buffer
- * @param flags receive flags
- * @param from source address
- * @param fromlen size of source address
- * @param dest destination address
- * @param destlen size of destination address
- * @return number of bytes read on success, negative otherwise
- */
-int recvfromdest(int sock, void *buf, size_t len, int flags,
-                 struct sockaddr *from, socklen_t *fromlen,
-                 struct sockaddr *dest, socklen_t *destlen){
-    int ret = 0;
-    struct iovec iov;
-    struct msghdr msg;
-    struct cmsghdr *cmsg;
-    char cbuf[1024];
-    struct in_pktinfo *info;
-    struct sockaddr_in *dest_in = (struct sockaddr_in *)dest;
-
-    //dest_in->sin_family = AF_INET;
-    //dest_in->sin_port   = 0;
-    getsockname(sock, dest, destlen);
-
-    iov.iov_base       = buf;
-    iov.iov_len        = len;
-    msg.msg_name       = from;
-    msg.msg_namelen    = *fromlen;
-    msg.msg_iov        = &iov;
-    msg.msg_iovlen     = 1;
-    msg.msg_control    = cbuf;
-    msg.msg_controllen = sizeof(cbuf);
-    
-    ret = recvmsg(sock, &msg, flags);
-    if(ret < 0) goto exit;
-    *fromlen = msg.msg_namelen;
-    
-    for(cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)){
-        if((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_PKTINFO)){
-            info = (void*)CMSG_DATA(cmsg);
-            dest_in->sin_addr = info->ipi_addr;
-            break;
-        }
-    }
-
-  exit:
-    return ret;
-}
-
-/** Read an skb from a udp socket and fill in its headers.
- */
-int skb_recv_udp(int sock, int flags,
-                 struct sockaddr_in *peer, socklen_t *peer_n,
-                 struct sockaddr_in *dest, socklen_t *dest_n,
-                 struct sk_buff **pskb){
-    int err = 0, n;
-    struct sk_buff *skb = skb_new();
-
-    skb->mac.raw = skb->data;
-    skb_reserve(skb, ETH_HLEN);
-    skb->nh.raw = skb->data;
-    skb_reserve(skb, sizeof(struct iphdr));
-    // Rcvr wants skb->data pointing at the udphdr.
-    skb->h.raw = skb_put(skb, sizeof(struct udphdr));
-    n = recvfromdest(sock, skb->tail, skb_tailroom(skb), flags,
-                     (struct sockaddr *)peer, peer_n,
-                     (struct sockaddr *)dest, dest_n);
-    if(n < 0){
-        err = -errno;
-        //perror("recvfrom");
-        goto exit;
-    }
-    dprintf("> peer=%s:%d\n", inet_ntoa(peer->sin_addr), 
ntohs(peer->sin_port));
-    dprintf("> dest=%s:%d\n", inet_ntoa(dest->sin_addr), 
ntohs(dest->sin_port));
-    skb_put(skb, n);
-    skb->protocol = skb->nh.iph->protocol = IPPROTO_UDP;
-    skb->nh.iph->saddr = peer->sin_addr.s_addr;
-    skb->h.uh->source  = peer->sin_port;
-    skb->nh.iph->daddr = dest->sin_addr.s_addr;
-    skb->h.uh->dest    = dest->sin_port;
-  exit:
-    if(err < 0){
-        kfree_skb(skb);
-        *pskb = NULL;
-    } else {
-        *pskb = skb;
-    }
-    return (err < 0 ? err : n);
-}
-
-/** Read an skb fom a raw socket and fill in its headers.
- */
-int skb_recv_raw(int sock, int flags,
-                 struct sockaddr_in *peer, socklen_t *peer_n,
-                 struct sockaddr_in *dest, socklen_t *dest_n,
-                 struct sk_buff **pskb){
-    int err = 0, n;
-    struct sk_buff *skb = skb_new();
-
-    skb->mac.raw = skb->data;
-    skb_reserve(skb, ETH_HLEN);
-    skb->nh.raw = skb->data;
-    skb_reserve(skb, sizeof(struct iphdr));
-    // Rcvr wants skb->data pointing after ip hdr, at raw protocol hdr.
-    n = recvfromdest(sock, skb->tail, skb_tailroom(skb), flags,
-                     (struct sockaddr *)peer, peer_n,
-                     (struct sockaddr *)dest, dest_n);
-    if(n < 0){
-        err = -errno;
-        //perror("recvfrom");
-        goto exit;
-    }
-    skb_put(skb, n);
-    // On a raw socket the port in the address is the protocol.
-    skb->protocol = skb->nh.iph->protocol = peer->sin_port;
-    skb->nh.iph->saddr = peer->sin_addr.s_addr;
-    skb->nh.iph->daddr = dest->sin_addr.s_addr;
-  exit:
-    if(err < 0){
-        kfree_skb(skb);
-        *pskb = NULL;
-    } else {
-        *pskb = skb;
-    }
-    return (err < 0 ? err : n);
-}
-
-/** Read an skb from a file descriptor.
- * Used for skbs coming to us from the tap device.
- * The skb content is an ethernet frame.
- */
-int skb_read(int fd, struct sk_buff **pskb){
-    int err = 0, n;
-    struct sk_buff *skb = skb_new();
-
-    // Reserve space for the headers we will add.
-    skb_reserve(skb, 100);
-    // Rcvr will want ethhdr on the skb.
-    skb->mac.raw = skb->tail;
-    n = read(fd, skb->tail, skb_tailroom(skb));
-    if(n < 0){
-        err = -errno;
-        //perror("read");
-        goto exit;
-    }
-    skb_put(skb, n);
-  exit:
-    if(err < 0){
-        kfree_skb(skb);
-        *pskb = NULL;
-    } else {
-        *pskb = skb;
-    }
-    return (err < 0 ? err : n);
-}
-
-/** Read an skb from the tap device for a vnet and send it.
- */
-int vnet_read(Vnet *vnet){
-    int err;
-    struct sk_buff *skb = NULL;
-
-    err = skb_read(vnet->dev->tapfd, &skb);
-    if(err < 0) goto exit;
-    err = vnet_skb_send(skb, &vnet->vnet);
-  exit:
-    if(skb) kfree_skb(skb);
-    return (err < 0 ? err : 0);
-}
-
-/** Transmit an skb to the network.
- */
-int _skb_xmit(struct sk_buff *skb, uint32_t saddr){
-    int err = 0;
-    int sock;
-    unsigned char *data;
-    struct sockaddr_in addr = { .sin_family = AF_INET };
-    int flags = 0;
-
-    if(saddr){
-        dprintf("> Raw IP send\n");
-        sock = vnetd->raw_sock;
-        skb->nh.iph->saddr = saddr;
-        addr.sin_addr.s_addr = skb->nh.iph->daddr;
-        // Should be the protocol, but is ignored. See raw(7) man page.
-        addr.sin_port        = 0;
-        // Data includes the ip header.
-        data = (void*)(skb->nh.iph);
-    } else {        
-        switch(skb->nh.iph->protocol){
-        case IPPROTO_UDP:
-            dprintf("> protocol=UDP\n");
-            sock = vnetd->udp_sock;
-            // Data comes after the udp header.
-            data = (void*)(skb->h.uh + 1);
-            addr.sin_addr.s_addr = skb->nh.iph->daddr;
-            addr.sin_port        = skb->h.uh->dest;
-            break;
-        case IPPROTO_ETHERIP:
-            dprintf("> protocol=ETHERIP\n");
-            if(vnetd->etherip_sock < 0){
-                err = -ENOSYS;
-                goto exit;
-            }
-            sock = vnetd->etherip_sock;
-            // Data comes after the ip header.
-            data = (void*)(skb->nh.iph + 1);
-            addr.sin_addr.s_addr = skb->nh.iph->daddr;
-            // Should be the protocol, but is ignored. See raw(7) man page.
-            addr.sin_port        = 0;
-            break;
-        default:
-            err = -ENOSYS;
-            wprintf("> protocol=%d, %d\n", skb->nh.iph->protocol, 
skb->protocol);
-            goto exit;
-        }
-    }
-
-    dprintf("> sending %d bytes to %s:%d protocol=%d\n",
-            skb->tail - data,
-            inet_ntoa(addr.sin_addr),
-            ntohs(addr.sin_port),
-            skb->nh.iph->protocol);
-
-    err = sendto(sock, data, skb->tail - data, flags,
-                 (struct sockaddr *)&addr, sizeof(addr));
-    if(err < 0){
-        err = -errno;
-        perror("sendto");
-    }
-  exit:    
-    if(err >= 0){
-        // Caller will assume skb freed if no error.
-        kfree_skb(skb);
-        err = 0;
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-int varp_open(uint32_t mcaddr, uint16_t port){
-    return 0;
-}
-
-void varp_close(void){
-}
-
-/** Create a raw socket.
- *
- * @param protocol protocol
- * @param flags flags (VSOCK_*)
- * @param mcaddr multicast addr used with flag VSOCK_MULTICAST
- * @param sock return value for the socket
- */
-int vnetd_raw_socket(Vnetd *vnetd, int protocol, int flags,
-                     uint32_t mcaddr, int *sock){
-    int err;
-    int bcast = (flags & VSOCK_BROADCAST);
-
-    err = *sock = socket(AF_INET, SOCK_RAW, protocol);
-    if(err < 0){
-        err = -errno;
-        perror("socket");
-        goto exit;
-    }
-    if(bcast){
-        err = setsock_broadcast(*sock, bcast);
-        if(err < 0) goto exit;
-    }
-    if(flags & VSOCK_MULTICAST){
-        err = setsock_multicast(*sock, INADDR_ANY, mcaddr);
-        if(err < 0) goto exit;
-    }
-    //todo ?? fcntl(*sock, F_SETFL, O_NONBLOCK);
-  exit:
-    return err;
-}
-
-int get_dev_address(char *dev, unsigned long *addr){
-    int err = 0;
-    int sock = -1;
-    struct ifreq ifreq = {};
-    struct sockaddr_in *in_addr;
-
-    sock = socket(AF_INET, SOCK_DGRAM, 0);
-    if(sock < 0){
-        err = -errno;
-        goto exit;
-    }
-    strncpy(ifreq.ifr_name, dev, IFNAMSIZ);
-    err = ioctl(sock, SIOCGIFADDR, &ifreq);
-    if(err){
-        err = -errno;
-        goto exit;
-    }
-    in_addr = (struct sockaddr_in *) &ifreq.ifr_addr;
-    *addr = in_addr->sin_addr.s_addr;
-    //iprintf("> dev=%s addr=%s\n", dev, inet_ntoa(in_addr->sin_addr));
-  exit:
-    if(sock >= 0) close(sock);
-    return err;
-}
-
-int get_intf_address(unsigned long *addr){
-    int err = 0;
-    char *devs[] = { "xen-br0", "eth0", "eth1", "eth2", NULL };
-    char **dev;
-
-    for(dev = devs; *dev; dev++){
-        err = get_dev_address(*dev, addr);
-        if(err == 0) goto exit;
-    }
-    err = -ENOSYS;
-  exit:
-    return err;
-}
-
-/** Get our own address. So we can ignore broadcast traffic
- * we sent ourselves.
- *
- * @param addr
- * @return 0 on success, error code otherwise
- */
-int get_self_addr(struct sockaddr_in *addr){
-    int err = 0;
-    char hostname[1024] = {};
-    unsigned long saddr;
- 
-    err = gethostname(hostname, sizeof(hostname) - 1);
-    if(err){
-        err = -errno;
-        perror("gethostname");
-        goto exit;
-    }
-    err = get_host_address(hostname, &saddr);
-    if(err) goto exit;
-    addr->sin_addr.s_addr = saddr;
-    if(saddr == htonl(INADDR_LOOPBACK)){
-        err = get_intf_address(&saddr);
-        if(err) goto exit;
-    }
-    addr->sin_addr.s_addr = saddr;
-    err = 0;
-  exit:
-    return err;
-}
-
-static int eval_vnetd_mcaddr(Sxpr exp, IOStream *out, void *data){
-    int err = 0;
-    Vnetd *vnetd = data;
-    Sxpr oaddr = intern("addr");
-    Sxpr ottl = intern("ttl");
-    uint32_t addr;
-    int ttl;
-
-    err = child_addr(exp, oaddr, &addr);
-    if(err < 0) goto exit;
-    vnetd_set_mcast_addr(vnetd, addr);
-    if(child_int(exp, ottl, &ttl) == 0){
-        vnetd->ttl = ttl;
-    }
-  exit:
-    return err;
-}
-
-static int vnetd_eval_io(Vnetd *vnetd, Parser *parser, SxprEval *defs,
-                         IOStream *in, IOStream *out){
-    int err = 0;
-    char buf[1024];
-    int k, n = sizeof(buf) - 1;
-
-    for( ; ; ){
-        k = IOStream_read(in, buf, n);
-        if(k < 0){
-            err = k;
-            goto exit;
-        }
-        err = Parser_input(parser, buf, k);
-        if(err < 0) goto exit;
-        while(Parser_ready(parser)){
-            Sxpr exp = Parser_get_val(parser);
-            if(NONEP(exp)) break;
-            err = vnet_eval_defs(defs, exp, out, vnetd);
-            if(err) goto exit;
-        }
-        if(Parser_at_eof(parser)) break;
-    }
-  exit:
-    return err;
-}
-
-static int vnetd_configure(Vnetd *vnetd, char *file){
-    int err = 0;
-    Parser *parser = NULL;    
-    IOStream *io = NULL;
-    SxprEval defs[] = {
-        { .name = intern("peer.add"),     .fn = eval_peer_add     },
-        { .name = intern("varp.mcaddr"),  .fn = eval_vnetd_mcaddr },
-        { .name = intern("vnet.add"),     .fn = eval_vnet_add     },
-        { .name = ONONE, .fn = NULL } };
-
-    parser = Parser_new(); 
-    io = file_stream_fopen(file, "rb");
-    if(!io){
-        err = -errno;
-        goto exit;
-    }
-    vnetd_eval_io(vnetd, parser, defs, io, iostdout);
-  exit:
-    if(io) IOStream_close(io);
-    Parser_free(parser);
-    return err;
-}
-
-#define OPT_MCADDR   'a'
-#define KEY_MCADDR   "varp_mcaddr"
-#define DOC_MCADDR   "<addr>\n\t VARP multicast address"
-
-#define OPT_FILE     'f'
-#define KEY_FILE     "file"
-#define DOC_FILE     "<file>\n\t Configuration file to load"
-
-#define OPT_HELP     'h'
-#define KEY_HELP     "help"
-#define DOC_HELP     "\n\tprint help"
-
-#define OPT_VERSION  'v'
-#define KEY_VERSION  "version"
-#define DOC_VERSION  "\n\tprint version"
-
-#define OPT_VERBOSE  'V'
-#define KEY_VERBOSE  "verbose"
-#define DOC_VERBOSE  "\n\tverbose flag"
-
-/** Print a usage message.
- * Prints to stdout if err is zero, and exits with 0.
- * Prints to stderr if err is non-zero, and exits with 1.
- *
- * @param err error code
- */
-static void usage(int err){
-    FILE *out = (err ? stderr : stdout);
-
-    fprintf(out, "Usage: %s [options]\n", PROGRAM);
-    fprintf(out, "-%c, --%s %s\n", OPT_MCADDR,   KEY_MCADDR,   DOC_MCADDR);
-    fprintf(out, "-%c, --%s %s\n", OPT_FILE,     KEY_FILE,     DOC_FILE);
-    fprintf(out, "-%c, --%s %s\n", OPT_VERBOSE,  KEY_VERBOSE,  DOC_VERBOSE);
-    fprintf(out, "-%c, --%s %s\n", OPT_VERSION,  KEY_VERSION,  DOC_VERSION);
-    fprintf(out, "-%c, --%s %s\n", OPT_HELP,     KEY_HELP,     DOC_HELP);
-    exit(err ? 1 : 0);
-}
-
-/** Short options. Options followed by ':' take an argument. */
-static char *short_opts = (char[]){
-    OPT_MCADDR,   ':',
-    OPT_FILE,     ':',
-    OPT_HELP,
-    OPT_VERSION,
-    OPT_VERBOSE,
-    0 };
-
-/** Long options. */
-static struct option const long_opts[] = {
-    { KEY_MCADDR,   required_argument, NULL, OPT_MCADDR   },
-    { KEY_FILE,     required_argument, NULL, OPT_FILE     },
-    { KEY_HELP,     no_argument,       NULL, OPT_HELP     },
-    { KEY_VERSION,  no_argument,       NULL, OPT_VERSION  },
-    { KEY_VERBOSE,  no_argument,       NULL, OPT_VERBOSE  },
-    { NULL,         0,                 NULL, 0            }
-};
-
-static int vnetd_getopts(Vnetd *vnetd, int argc, char *argv[]){
-    int err = 0;
-    int key = 0;
-    int long_index = 0;
-
-    while(1){
-       key = getopt_long(argc, argv, short_opts, long_opts, &long_index);
-       if(key == -1) break;
-       switch(key){
-        case OPT_MCADDR: {
-            unsigned long addr;
-            err = get_inet_addr(optarg, &addr);
-            if(err) goto exit;
-            vnetd_set_mcast_addr(vnetd, addr);
-            break; }
-        case OPT_FILE:
-            err = vnetd_configure(vnetd, optarg);
-            if(err) goto exit;
-            break;
-       case OPT_HELP:
-           usage(0);
-           break;
-       case OPT_VERBOSE:
-           vnetd->verbose = true;
-           break;
-       case OPT_VERSION:
-            iprintf("> %s %s\n", PROGRAM, VERSION);
-            exit(0);
-           break;
-       default:
-           usage(EINVAL);
-           break;
-       }
-    }
-  exit:
-    return err;
-}
-
-/** Initialise vnetd params.
- *
- * @param vnetd vnetd
- */
-static int vnetd_init(Vnetd *vnetd, int argc, char *argv[]){
-    int err = 0;
-
-    // Use etherip-in-udp encapsulation.
-    etherip_in_udp = true;
-
-    *vnetd = (Vnetd){};
-    vnetd->port = htons(VARP_PORT);
-    vnetd->verbose = false;
-    vnetd->ttl = 1; // Default multicast ttl.
-    vnetd->etherip = true;
-    vnetd->udp_sock = -1;
-    vnetd->mcast_sock = -1;
-    vnetd->etherip_sock = -1;
-    vnetd_set_mcast_addr(vnetd, htonl(VARP_MCAST_ADDR));
-    vnetd->mcast_addr.sin_port = vnetd->port;
-    vnetd->unix_path = "/tmp/vnetd";
-
-    vnetd_getopts(vnetd, argc, argv);
-    
-    err = get_self_addr(&vnetd->ucast_addr);
-    vnetd->ucast_addr.sin_port = vnetd->port;
-    dprintf("> mcaddr=%s\n", inet_ntoa(vnetd->mcast_addr.sin_addr));
-    dprintf("> addr  =%s\n", inet_ntoa(vnetd->ucast_addr.sin_addr));
-    return err;
-}
-
-static void vnet_select(Vnetd *vnetd, SelectSet *set){
-    HashTable_for_decl(entry);
-
-    HashTable_for_each(entry, vnetd->vnet_table){
-        Vnet *vnet = entry->value;
-        struct net_device *dev = vnet->dev;
-        if(!dev) continue;
-        if(dev->tapfd < 0) continue;
-        SelectSet_add(set, dev->tapfd, SELECT_READ);
-    }
-}
-
-static void vnet_handle(Vnetd *vnetd, SelectSet *set){
-    HashTable_for_decl(entry);
-
-    HashTable_for_each(entry, vnetd->vnet_table){
-        Vnet *vnet = entry->value;
-        struct net_device *dev = vnet->dev;
-        if(!dev) continue;
-        if(dev->tapfd < 0) continue;
-        if(SelectSet_in_read(set, dev->tapfd)){
-            int n;
-            for(n = 64; n > 0; --n){
-                if(vnet_read(vnet) < 0) break;
-            }
-        }
-    }
-}
-
-static int vnetd_handle_udp(Vnetd *vnetd, struct sockaddr_in *addr, int sock){
-    int err = 0, n = 0;
-    struct sockaddr_in peer, dest;
-    socklen_t peer_n = sizeof(peer), dest_n = sizeof(dest);
-    int flags = MSG_DONTWAIT;
-    struct sk_buff *skb = NULL;
-
-    dest = *addr;
-    n = skb_recv_udp(sock, flags, &peer, &peer_n, &dest, &dest_n, &skb);
-    if(n < 0){
-        err = n;
-        goto exit;
-    }
-    dprintf("> Received %d bytes from=%s:%d dest=%s:%d\n",
-            n,
-            inet_ntoa(peer.sin_addr), htons(peer.sin_port),
-            inet_ntoa(dest.sin_addr), htons(dest.sin_port));
-    if(peer.sin_addr.s_addr == vnetd_intf_addr(vnetd)){
-        dprintf("> Ignoring message from self.\n");
-        goto exit;
-    }
-    if(dest.sin_addr.s_addr == vnetd_mcast_addr(vnetd)){
-        vnet_forward_send(skb);
-    }
-    err = varp_handle_message(skb);
-
-  exit:
-    if(skb) kfree_skb(skb);
-    return err;
-}
-
-static int vnetd_handle_etherip(Vnetd *vnetd, struct sockaddr_in *addr, int 
sock){
-    int err = 0, n = 0;
-    struct sockaddr_in peer, dest;
-    socklen_t peer_n = sizeof(peer), dest_n = sizeof(dest);
-    int flags = 0;
-    struct sk_buff *skb = NULL;
-
-    dest = *addr;
-    n = skb_recv_raw(sock, flags, &peer, &peer_n, &dest, &dest_n, &skb);
-    if(n < 0){
-        err = n;
-        goto exit;
-    }
-    dprintf("> Received %d bytes from=%s:%d dest=%s:%d\n",
-            n,
-            inet_ntoa(peer.sin_addr), htons(peer.sin_port),
-            inet_ntoa(dest.sin_addr), htons(dest.sin_port));
-    if(peer.sin_addr.s_addr == vnetd_intf_addr(vnetd)){
-        dprintf("> Ignoring message from self.\n");
-        goto exit;
-    }
-    err = etherip_protocol_recv(skb);
-  exit:
-    if(skb) kfree_skb(skb);
-    return err;
-}
-
-typedef struct ConnClient {
-    Vnetd *vnetd;
-    Parser *parser;
-} ConnClient;
-
-static int conn_handle_fn(Conn *conn, int mode){
-    int err;
-    ConnClient *client = conn->data;
-    char data[1024] = {};
-    int k;
-    int done = false;
-
-    k = IOStream_read(conn->in, data, sizeof(data));
-    if(k < 0){
-        err = k;
-        goto exit;
-    }
-    if(!client->parser){
-        err = -ENOSYS;
-        goto exit;
-    }
-    if((k == 0) && Parser_at_eof(client->parser)){
-        err = -EINVAL;
-        goto exit;
-    }
-    err = Parser_input(client->parser, data, k);
-    if(err < 0) goto exit;
-    while(Parser_ready(client->parser)){
-        Sxpr sxpr = Parser_get_val(client->parser);
-        err = vnet_eval(sxpr, conn->out, NULL);
-        if(err) goto exit;
-        done = true;
-    }
-    if(done || Parser_at_eof(client->parser)){
-        // Close at EOF.
-        err = -EIO;
-    }
-  exit:
-    if(err < 0){
-        Parser_free(client->parser);
-        client->parser = NULL;
-    }
-    return (err < 0 ? err : 0);
-}
-
-static int vnetd_handle_unix(Vnetd *vnetd, int sock){
-    int err;
-    ConnClient *client = NULL;
-    Conn *conn = NULL;
-    struct sockaddr_un peer = {};
-    socklen_t peer_n = sizeof(peer);
-    int peersock;
-
-    peersock = accept(sock, (struct sockaddr *)&peer, &peer_n);
-    if(peersock < 0){
-        perror("accept");
-        err = -errno;
-        goto exit;
-    }
-    // We want non-blocking i/o.
-    fcntl(peersock, F_SETFL, O_NONBLOCK);
-    client = ALLOCATE(ConnClient);
-    client->vnetd = vnetd;
-    client->parser = Parser_new();
-    conn = Conn_new(conn_handle_fn, client);
-    err = Conn_init(conn, peersock, SOCK_STREAM, SELECT_READ,
-                    (struct sockaddr_in){});
-    if(err) goto exit;
-    vnetd->conns = ConnList_add(vnetd->conns, conn);
-  exit:
-    if(err){
-        Conn_close(conn);
-        close(peersock);
-    }
-    if(err < 0) wprintf("< err=%d\n", err);
-    return err;
-}
-
-static void vnetd_select(Vnetd *vnetd, SelectSet *set){
-    SelectSet_add(set, vnetd->unix_sock, SELECT_READ);
-    SelectSet_add(set, vnetd->udp_sock, SELECT_READ);
-    SelectSet_add(set, vnetd->mcast_sock, SELECT_READ);
-    if(vnetd->etherip_sock >= 0){
-        SelectSet_add(set, vnetd->etherip_sock, SELECT_READ);
-    }
-    vnet_select(vnetd, set);
-    ConnList_select(vnetd->conns, set);
-}
-
-static void vnetd_handle(Vnetd *vnetd, SelectSet *set){
-    if(SelectSet_in_read(set, vnetd->unix_sock)){
-        vnetd_handle_unix(vnetd, vnetd->unix_sock);
-    }
-    if(SelectSet_in_read(set, vnetd->udp_sock)){
-        int n;
-
-        for(n = 256; n > 0; --n){
-            if(vnetd_handle_udp(vnetd, &vnetd->udp_sock_addr, vnetd->udp_sock) 
< 0){
-                break;
-            }
-        }
-    }
-    if(SelectSet_in_read(set, vnetd->mcast_sock)){
-        vnetd_handle_udp(vnetd, &vnetd->mcast_sock_addr, vnetd->mcast_sock);
-    }
-    if((vnetd->etherip_sock >= 0) &&
-       SelectSet_in_read(set, vnetd->etherip_sock)){
-        vnetd_handle_etherip(vnetd, &vnetd->etherip_sock_addr, 
vnetd->etherip_sock);
-    }
-    vnet_handle(vnetd, set);
-    vnetd->conns = ConnList_handle(vnetd->conns, set);
-}
-
-/** Counter for timer alarms.
- */
-static unsigned timer_alarms = 0;
-
-static int vnetd_main(Vnetd *vnetd){
-    int err = 0;
-    SelectSet _set = {}, *set = &_set;
-    struct timeval _timeout = {}, *timeout = &_timeout;
-
-    vnetd->vnet_table = vnet_table;
-
-    for( ; ; ){
-        timeout->tv_sec = 0;
-        timeout->tv_usec = 500000;
-        SelectSet_zero(set);
-        vnetd_select(vnetd, set);
-        err = SelectSet_select(set, timeout);
-        if(err == 0) continue;
-        if(err < 0){
-            switch(errno){
-            case EINTR:
-                if(timer_alarms){
-                    timer_alarms = 0;
-                    process_timers();
-                }
-                continue;
-            case EBADF:
-                continue;
-            default:
-                perror("select");
-                goto exit;
-            }
-        }
-        vnetd_handle(vnetd, set);
-    }
-  exit:
-    return err;
-}
-
-static int getsockaddr(int sock, struct sockaddr_in *addr){
-    socklen_t addr_n = sizeof(struct sockaddr_in);
-    return getsockname(sock, (struct sockaddr*)addr, &addr_n);
-}
-
-static int vnetd_etherip_sock(Vnetd *vnetd){
-    int err = 0;
-
-    if(!vnetd->etherip) goto exit;
-    err = vnetd_raw_socket(vnetd, IPPROTO_ETHERIP,
-                           (VSOCK_BROADCAST | VSOCK_MULTICAST),
-                           vnetd_mcast_addr(vnetd),
-                           &vnetd->etherip_sock);
-    if(err < 0) goto exit;
-    err = setsock_pktinfo(vnetd->etherip_sock, true);
-    if(err < 0) goto exit;
-    getsockaddr(vnetd->etherip_sock, &vnetd->etherip_sock_addr);
-  exit:
-    return err;
-}
-
-static int vnetd_udp_sock(Vnetd *vnetd){
-    int err;
-    uint32_t mcaddr = vnetd_mcast_addr(vnetd);
-
-    err = create_socket(SOCK_DGRAM, INADDR_ANY, vnetd->port,
-                        (VSOCK_BIND | VSOCK_REUSE),
-                        &vnetd->udp_sock);
-    if(err < 0) goto exit;
-    err = setsock_pktinfo(vnetd->udp_sock, true);
-    if(err < 0) goto exit;
-    getsockaddr(vnetd->udp_sock, &vnetd->udp_sock_addr);
-    vnetd->mcast_sock_addr.sin_addr.s_addr = vnetd_intf_addr(vnetd);
-
-    err = create_socket(SOCK_DGRAM, mcaddr, vnetd_mcast_port(vnetd),
-                        (VSOCK_REUSE | VSOCK_BROADCAST | VSOCK_MULTICAST),
-                        &vnetd->mcast_sock);
-    if(err < 0) goto exit;
-    err = setsock_pktinfo(vnetd->udp_sock, true);
-    if(err < 0) goto exit;
-    err = setsock_multicast(vnetd->mcast_sock, INADDR_ANY, mcaddr);
-    if(err < 0) goto exit;
-    err = setsock_multicast_ttl(vnetd->mcast_sock, vnetd->ttl);
-    if(err < 0) goto exit;
-    getsockaddr(vnetd->mcast_sock, &vnetd->mcast_sock_addr);
-    vnetd->mcast_sock_addr.sin_addr.s_addr = mcaddr;
-
-  exit:
-    if(err < 0){
-        close(vnetd->udp_sock);
-        close(vnetd->mcast_sock);
-        vnetd->udp_sock = -1;
-        vnetd->mcast_sock = -1;
-    }
-    return err;
-}
-
-static int vnetd_raw_sock(Vnetd *vnetd){
-    int err;
-
-    err = vnetd_raw_socket(vnetd, IPPROTO_RAW,
-                           (VSOCK_BROADCAST),
-                           vnetd_mcast_addr(vnetd),
-                           &vnetd->raw_sock);
-    if(err){
-        close(vnetd->raw_sock);
-        vnetd->raw_sock = -1;
-    }
-    return err;
-}
-
-static int vnetd_unix_sock(Vnetd *vnetd){
-    int err = 0;
-    struct sockaddr_un addr = { .sun_family = AF_UNIX };
-    socklen_t addr_n;
-    
-    vnetd->unix_sock = socket(addr.sun_family, SOCK_STREAM, 0);
-    if(vnetd->unix_sock < 0){
-        err = -errno;
-        perror("unix socket");
-        goto exit;
-    }
-    unlink(vnetd->unix_path);
-    strcpy(addr.sun_path, vnetd->unix_path);
-    addr_n = sizeof(addr) - sizeof(addr.sun_path) + strlen(vnetd->unix_path) + 
1;
-    err = bind(vnetd->unix_sock, (struct sockaddr *)&addr, addr_n);
-    if(err < 0){
-        err = -errno;
-        perror("unix bind");
-        goto exit;
-    }
-    err = listen(vnetd->unix_sock, 5);
-    if(err < 0){
-        err = -errno;
-        perror("unix listen");
-    }
-  exit:
-    return err;
-}
-   
-/** Handle SIGPIPE.
- *
- * @param code signal code
- * @param info signal info
- * @param data
- */
-static void sigaction_SIGPIPE(int code, siginfo_t *info, void *data){
-    dprintf("> SIGPIPE\n");
-}
-
-/** Handle SIGALRM.
- *
- * @param code signal code
- * @param info signal info
- * @param data
- */
-static void sigaction_SIGALRM(int code, siginfo_t *info, void *data){
-    timer_alarms++;
-}
-
-/** Type for signal handling functions. */
-typedef void SignalAction(int code, siginfo_t *info, void *data);
-
-/** Install a handler for a signal.
- *
- * @param signum signal
- * @param action handler
- * @return 0 on success, error code otherwise
- */
-static int catch_signal(int signum, SignalAction *action){
-    int err = 0;
-    struct sigaction sig = {};
-    dprintf(">\n");
-    sig.sa_sigaction = action;
-    sig.sa_flags = SA_SIGINFO;
-    err = sigaction(signum, &sig, NULL);
-    if(err){
-        err = -errno;
-        perror("sigaction");
-    }
-    return err;
-}    
-
-int main(int argc, char *argv[]){
-    int err = 0;
-
-    err = tunnel_module_init();
-    if(err < 0) goto exit;
-    err = vnet_init();
-    if(err < 0) goto exit;
-    err = vnetd_init(vnetd, argc, argv);
-    if(err < 0) goto exit;
-    err = catch_signal(SIGPIPE, sigaction_SIGPIPE);
-    if(err < 0) goto exit;
-    err = catch_signal(SIGALRM, sigaction_SIGALRM); 
-    if(err < 0) goto exit;
-    err = vnetd_etherip_sock(vnetd);
-    if(err < 0) goto exit;
-    err = vnetd_udp_sock(vnetd);
-    if(err < 0) goto exit;
-    err = vnetd_raw_sock(vnetd);
-    if(err < 0) goto exit;
-    err = vnetd_unix_sock(vnetd);
-    if(err < 0) goto exit;
-    err = vnetd_main(vnetd);
-exit:
-    return (err ? 1 : 0);
-}

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel