This patch fixes the tools/vnet makefiles so that vnets will
compile and includes updates to the vnet implementation.
Vnet ids are increased to 128 bits. The vnet module will
insmod whether xen-br0 exists or not.
Signed-off-by: Mike Wray <mike.wray@xxxxxx>
diff -r 9fb0bad776dd tools/vnet/00INSTALL
--- a/tools/vnet/00INSTALL Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/00INSTALL Fri Aug 26 09:04:02 2005
@@ -1,14 +1,34 @@
-To compile and install run "make install"; if it fails or you need to
reinstall
-run "make clean" first or the build will fail, at least that is what I have
-found under 2.6.10.
+make
+ - compile in local dirs. The module is in vnet-module/vnet_module.ko.
-Other important items:
+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.
+
+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 alogorithms listed under
+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
@@ -23,9 +43,5 @@
802.1Q VLAN Support
-4) The module (vnet_module) will not properly load from the command line
- with a "modprobe vnet_module". Use network-vnet to properly configure
- your system and load the module for you.
-
Please refer to the additional documentation found in tools/vnet/doc for
proper syntax and config file parameters.
diff -r 9fb0bad776dd tools/vnet/Makefile
--- a/tools/vnet/Makefile Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/Makefile Fri Aug 26 09:04:02 2005
@@ -1,18 +1,21 @@
+# -*- mode: Makefile; -*-
-export LINUX_SERIES ?=2.6
+ifndef VNET_ROOT
+export VNET_ROOT = $(shell pwd)
+include $(VNET_ROOT)/Make.env
+endif
-# Root path to install in.
-# Set to '/' to install relative to filesystem root.
-export prefix?=$(shell cd ../../dist/install && pwd)
+.PHONY: all compile install dist clean pristine
+.PHONY: gc-all gc-install gc-clean
-.PHONY: all compile
-.PHONY: gc-install gc-clean gc-prstine
-.PHONY: libxutil vnetd vnet-module install dist clean pristine
+SUBDIRS:=
+SUBDIRS+= examples
+SUBDIRS+= gc
+SUBDIRS+= libxutil
+SUBDIRS+= vnetd
+SUBDIRS+= vnet-module
all: compile
-
-compile: libxutil vnetd vnet-module
-#compile: vnet-module
gc.tar.gz:
wget http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/$@
@@ -21,36 +24,39 @@
tar xfz gc.tar.gz
ln -sf gc?.? gc
-gc-install: gc
- (cd gc && make test && ./configure --prefix=`pwd`/install)
+$(GC_LIB_A): gc
+ (cd gc && ./configure --prefix=$(GC_DIR) )
make -C gc
- make -C gc install
+ DESTDIR="" make -C gc install
+
+gc-all: $(GC_LIB_A)
+
+gc-install:
gc-clean:
- -$(MAKE) -C gc clean
+ -@$(RM) -r gc?.? gc
-gc-pristine:
- -rm -rf gc?.? gc
+submak = $(MAKE) -C $(patsubst %-$(1),%,$(@)) $(1)
+subtgt = $(patsubst %,%-$(1),$(SUBDIRS))
-libxutil:
- $(MAKE) -C libxutil
+%-all:
+ $(call submak,all)
-vnetd: gc-install
- $(MAKE) -C vnetd
+%-clean:
+ -$(call submak,clean)
-vnet-module:
- $(MAKE) -C vnet-module
+%-install:
+ $(call submak,install)
-install: compile
- $(MAKE) -C libxutil install
- $(MAKE) -C vnetd install
- $(MAKE) -C vnet-module install
- $(MAKE) -C examples install
+compile: $(call subtgt,all)
-clean:
- -$(MAKE) -C libxutil clean
- -$(MAKE) -C vnetd clean
- -$(MAKE) -C vnet-module clean
- -rm -rf gc?.? gc
+install: DESTDIR=
+install: dist
-pristine: clean gc-pristine
+dist: compile $(call subtgt,install)
+
+clean: $(call subtgt,clean)
+ -@$(RM) -r build
+
+pristine: clean
+ -@$(RM) gc.tar.gz
diff -r 9fb0bad776dd tools/vnet/doc/vnet-module.txt
--- a/tools/vnet/doc/vnet-module.txt Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/doc/vnet-module.txt Fri Aug 26 09:04:02 2005
@@ -1,20 +1,33 @@
Vnet Module Command Interface
Mike Wray <mike.wray@xxxxxx>
-2004/09/17
+2005/08/25
When insmod the vnet-module creates /proc/vnet/policy which
can be used to control the module by writing commands into it.
The return code from the command should be returned by close.
+Xend uses these commands to implement its vnet interface.
The commands are:
-(vnet.add (id <id>) [(security { none | auth | conf } )] )
+(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>))
@@ -31,11 +44,17 @@
Remove the vif with MAC address <macaddr> from the vnet with id <vnetid>.
The vnet module will stop responding to VARP for the vif.
+(vif.print)
+
+Print the known vnets, vifs and varp cache on the console.
+
Examples:
To create vnet 10 with no security:
echo '(vnet.add (id 10))' > /proc/vnet/policy
+
+This creates a device vnif0010.
To create vnet 11 with message authentication:
diff -r 9fb0bad776dd tools/vnet/doc/vnet-xend.txt
--- a/tools/vnet/doc/vnet-xend.txt Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/doc/vnet-xend.txt Fri Aug 26 09:04:02 2005
@@ -3,11 +3,13 @@
Mike Wray <mike.wray@xxxxxx>
+2005/08/25
+
0) Introduction
---------------
Vnets provide virtual private LANs for virtual machines.
-This is done using bridging and tunneling. A virtual interface
+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.
@@ -32,13 +34,16 @@
Restart xend.
+Alternatively insert the vnet module using vnet-insert,
+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 call vnet_add <vnet config file>
+xm vnet-create <vnet config file>
For example, if vnet97.sxp contains:
@@ -46,7 +51,7 @@
do
-xm call vnet_add vnet97.sxp
+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 vnetif97.
@@ -64,31 +69,35 @@
Once configured, vnets are persistent in the xend database.
To remove a vnet use
-xm call vnet_delete <vnet id>
+xm vnet-delete <vnet id>
To list vnets use
-xm call vnets
+xm vnet-list
To get information on a vnet id use
-xm call vnet <vnet id>
+xm vnet-list <vnet id>
3) Troubleshooting
------------------
The vnet module should appear in 'lsmod'.
-If a vnet has been configured it should appear in the output of 'xm call
vnets'.
+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.
+You can 'see into' a vnet from dom0 if you put an IP address on the bridge
+and configure its MAC address as a vif.
For example, if you have vnet97 with a vm with ip addr 10.0.0.12 on it,
-then
+and <mac> is the MAC address of vnet97 (use ifconfig), then
+echo '(vif.add (vnet 97) (vmac <mac>))' >/proc/vnet/policy
ifconfig vnet97 10.0.0.20 up
should let you ping 10.0.0.12 via the vnet97 bridge.
+This works even if the vm with vif 10.0.0.12 is on another
+machine (it only works locally if you don't use vif.add).
4) Examples
-----------
@@ -104,11 +113,11 @@
(linux
(kernel /boot/vmlinuz-2.6-xenU)
(ip 10.0.0.12:1.2.3.4::::eth0:off)
- (root /dev/hda1)
+ (root /dev/sda1)
(args 'rw fastboot 4')
)
)
- (device (vbd (uname phy:hda2) (dev hda1) (mode w)))
+ (device (vbd (uname phy:hda2) (dev sda1) (mode w)))
(device (vif (mac aa:00:00:11:00:12) (bridge vnet97)))
)
@@ -123,11 +132,11 @@
(linux
(kernel /boot/vmlinuz-2.6-xenU)
(ip 10.0.0.11:1.2.3.4::::eth0:off)
- (root /dev/hda1)
+ (root /dev/sda1)
(args 'rw fastboot 4')
)
)
- (device (vbd (uname phy:hda3) (dev hda1) (mode w)))
+ (device (vbd (uname phy:hda3) (dev sda1) (mode w)))
(device (vif (mac aa:00:00:11:00:11) (bridge vnet97)))
)
diff -r 9fb0bad776dd tools/vnet/examples/Makefile
--- a/tools/vnet/examples/Makefile Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/examples/Makefile Fri Aug 26 09:04:02 2005
@@ -2,11 +2,14 @@
#============================================================================
XEN_SCRIPT_DIR:=/etc/xen/scripts
+
+.PHONY: all install clean
all:
install:
install -m 0755 -d $(DESTDIR)$(XEN_SCRIPT_DIR)
install -m 0554 network-vnet $(DESTDIR)$(XEN_SCRIPT_DIR)
+ install -m 0554 vnet-insert $(DESTDIR)$(XEN_SCRIPT_DIR)
clean:
\ No newline at end of file
diff -r 9fb0bad776dd tools/vnet/examples/network-vnet
--- a/tools/vnet/examples/network-vnet Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/examples/network-vnet Fri Aug 26 09:04:02 2005
@@ -1,218 +1,10 @@
#!/bin/sh
-#============================================================================
-# Default Xen network start/stop script.
-# Xend calls a network script when it starts.
-# The script name to use is defined in /etc/xen/xend-config.sxp
-# in the network-script field.
-#
-# This script creates a bridge (default xen-br0), adds a device
-# (default eth0) to it, copies the IP addresses from the device
-# to the bridge and adjusts the routes accordingly.
-#
-# If all goes well, this should ensure that networking stays up.
-# However, some configurations are upset by this, especially
-# NFS roots. If the bridged setup does not meet your needs,
-# configure a different script, for example using routing instead.
-#
-# Usage:
-#
-# network (start|stop|status) {VAR=VAL}*
-#
-# Vars:
-#
-# bridge The bridge to use (default xen-br0).
-# netdev The interface to add to the bridge (default eth0).
-# antispoof Whether to use iptables to prevent spoofing (default yes).
-#
-# start:
-# Creates the bridge and enslaves netdev to it.
-# Copies the IP addresses from netdev to the bridge.
-# Deletes the routes to netdev and adds them on bridge.
-#
-# stop:
-# Removes netdev from the bridge.
-# Deletes the routes to bridge and adds them to netdev.
-#
-# status:
-# Print ifconfig for netdev and bridge.
-# Print routes.
-#
-#============================================================================
+scriptdir=/etc/xen/scripts/
-# Exit if anything goes wrong.
-set -e
+case ${1} in
+ start)
+ ${scriptdir}/vnet-insert
+ ;;
+esac
-# First arg is the operation.
-OP=$1
-shift
-
-# Pull variables in args in to environment.
-for arg ; do export "${arg}" ; done
-
-bridge=${bridge:-xen-br0}
-netdev=${netdev:-eth0}
-antispoof=${antispoof:-yes}
-
-echo "network $OP bridge=$bridge netdev=$netdev antispoof=$antispoof"
-
-# Usage: transfer_addrs src dst
-# Copy all IP addresses (including aliases) from device $src to device $dst.
-transfer_addrs () {
- local src=$1
- local dst=$2
- # Don't bother if $dst already has IP addresses.
- if ip addr show dev ${dst} | egrep -q '^ *inet' ; then
- return
- fi
- # Address lines start with 'inet' and have the device in them.
- # Replace 'inet' with 'ip addr add' and change the device name $src
- # to 'dev $src'. Remove netmask as we'll add routes later.
- ip addr show dev ${src} | egrep '^ *inet' | sed -e "
-s/inet/ip addr add/
-s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)/[0-9]\+@\1@
-s/${src}/dev ${dst}/
-" | sh -e
-}
-
-# Usage: transfer_routes src dst
-# Get all IP routes to device $src, delete them, and
-# add the same routes to device $dst.
-# The original routes have to be deleted, otherwise adding them
-# for $dst fails (duplicate routes).
-transfer_routes () {
- local src=$1
- local dst=$2
- # List all routes and grep the ones with $src in.
- # Stick 'ip route del' on the front to delete.
- # Change $src to $dst and use 'ip route add' to add.
- ip route list | grep ${src} | sed -e "
-h
-s/^/ip route del /
-P
-g
-s/${src}/${dst}/
-s/^/ip route add /
-P
-d
-" | sh -e
-}
-
-# Usage: create_bridge dev bridge
-# Create bridge $bridge and add device $dev to it.
-create_bridge () {
- local dev=$1
- local bridge=$2
-
- # Don't create the bridge if it already exists.
- if ! brctl show | grep -q ${bridge} ; then
- brctl addbr ${bridge}
- brctl stp ${bridge} off
- brctl setfd ${bridge} 0
- fi
- ifconfig ${bridge} up
-}
-
-# Usage: antispoofing dev bridge
-# Set the default forwarding policy for $dev to drop.
-# Allow forwarding to the bridge.
-antispoofing () {
- local dev=$1
- local bridge=$2
-
- iptables -P FORWARD DROP
- iptables -A FORWARD -m physdev --physdev-in ${dev} -j ACCEPT
-}
-
-# Usage: show_status dev bridge
-# Print ifconfig and routes.
-show_status () {
- local dev=$1
- local bridge=$2
-
- echo '============================================================'
- ifconfig ${dev}
- ifconfig ${bridge}
- echo ' '
- ip route list
- echo ' '
- route -n
- echo '============================================================'
-}
-
-# 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)/kernel
- local mod_path="${mod_dir}/${module}"
- local mod_obj=""
-
- for ext in ".o" ".ko" ; do
- f=${mod_path}${ext}
- if [ -f ${f} ] ; then
- mod_obj=$f
- break
- fi
- done
- if [ "${mod_obj}" == "" ] ; then
- return
- fi
- if lsmod | grep -q ${module} ; then
- echo "VNET: ${module} loaded"
- else
- echo "VNET: Loading ${module}..."
- insmod ${mod_obj}
- fi
-}
-
-op_start () {
- if [ "${bridge}" == "null" ] ; then
- return
- fi
- # Create the bridge and give it the interface IP addresses.
- # Move the interface routes onto the bridge.
- create_bridge ${netdev} ${bridge}
- transfer_addrs ${netdev} ${bridge}
- transfer_routes ${netdev} ${bridge}
- # Don't add $dev to $bridge if it's already on a bridge.
- if ! brctl show | grep -q ${netdev} ; then
- brctl addif ${bridge} ${netdev}
- fi
-
- if [ ${antispoof} == 'yes' ] ; then
- antispoofing ${netdev} ${bridge}
- fi
-
- vnet_insert
-}
-
-op_stop () {
- if [ "${bridge}" == "null" ] ; then
- return
- fi
- # Remove the interface from the bridge.
- # Move the routes back to the interface.
- brctl delif ${bridge} ${netdev}
- transfer_routes ${bridge} ${netdev}
-
- # It's not our place to be enabling forwarding...
-}
-
-case ${OP} in
- start)
- op_start
- ;;
-
- stop)
- op_stop
- ;;
-
- status)
- show_status ${netdev} ${bridge}
- ;;
-
- *)
- echo 'Unknown command: ' ${OP}
- echo 'Valid commands are: start, stop, status'
- exit 1
-esac
+${scriptdir}/network-bridge "$@"
diff -r 9fb0bad776dd tools/vnet/examples/vnet97.sxp
--- a/tools/vnet/examples/vnet97.sxp Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/examples/vnet97.sxp Fri Aug 26 09:04:02 2005
@@ -1,3 +1,2 @@
# Vnet configuration for a vnet with id 97 and no security.
-# Configure using 'xm call vnet_add vnet97.sxp'.
(vnet (id 97) (bridge vnet97) (vnetif vnetif97) (security none))
diff -r 9fb0bad776dd tools/vnet/examples/vnet98.sxp
--- a/tools/vnet/examples/vnet98.sxp Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/examples/vnet98.sxp Fri Aug 26 09:04:02 2005
@@ -1,3 +1,2 @@
# Vnet configuration for a vnet with id 98 and message authentication.
-# Configure using 'xm call vnet_add vnet98.sxp'.
(vnet (id 98) (bridge vnet98) (vnetif vnetif98) (security auth))
diff -r 9fb0bad776dd tools/vnet/examples/vnet99.sxp
--- a/tools/vnet/examples/vnet99.sxp Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/examples/vnet99.sxp Fri Aug 26 09:04:02 2005
@@ -1,3 +1,2 @@
# Vnet configuration for a vnet with id 99 and message confidentiality.
-# Configure using 'xm call vnet_add vnet99.sxp'.
(vnet (id 99) (bridge vnet99) (vnetif vnetif99) (security conf))
diff -r 9fb0bad776dd tools/vnet/libxutil/Makefile
--- a/tools/vnet/libxutil/Makefile Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/libxutil/Makefile Fri Aug 26 09:04:02 2005
@@ -1,5 +1,8 @@
+ifndef VNET_ROOT
+export VNET_ROOT = $(shell cd .. && pwd)
+include $(VNET_ROOT)/Make.env
+endif
-XEN_ROOT = ../../..
INSTALL = install
INSTALL_DATA = $(INSTALL) -m0644
INSTALL_PROG = $(INSTALL) -m0755
@@ -15,6 +18,7 @@
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
@@ -26,6 +30,7 @@
PIC_OBJS := $(LIB_SRCS:.c=.opic)
CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing
+CFLAGS += -g
# Get gcc to generate the dependencies for us.
CFLAGS += -Wp,-MD,.$(@F).d
@@ -39,6 +44,7 @@
LIB += libxutil.a
all: build
+
build: check-for-zlib
$(MAKE) $(LIB)
@@ -70,8 +76,8 @@
ln -sf libxutil.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxutil.so
clean:
- $(RM) *.a *.so* *.o *.opic *.rpm
- $(RM) *~
- $(RM) $(DEPS)
+ -@$(RM) *.a *.so* *.o *.opic *.rpm
+ -@$(RM) *~
+ -@$(RM) $(DEPS)
-include $(DEPS)
diff -r 9fb0bad776dd tools/vnet/libxutil/debug.h
--- a/tools/vnet/libxutil/debug.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/libxutil/debug.h Fri Aug 26 09:04:02 2005
@@ -49,9 +49,9 @@
#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)
+#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
diff -r 9fb0bad776dd tools/vnet/libxutil/sxpr.c
--- a/tools/vnet/libxutil/sxpr.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/libxutil/sxpr.c Fri Aug 26 09:04:02 2005
@@ -405,7 +405,6 @@
#endif /* USE_GC */
/** Create a new atom with the given name.
- * Makes an integer sxpr if the name can be parsed as an int.
*
* @param name the name
* @return new atom
@@ -414,7 +413,8 @@
Sxpr n, obj = ONOMEM;
long v;
- if(convert_atol(name, &v) == 0){
+ // Don't always want to do this.
+ if(0 && convert_atol(name, &v) == 0){
obj = OINT(v);
} else {
n = string_new(name);
diff -r 9fb0bad776dd tools/vnet/libxutil/sxpr.h
--- a/tools/vnet/libxutil/sxpr.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/libxutil/sxpr.h Fri Aug 26 09:04:02 2005
@@ -228,7 +228,9 @@
*
* @param val pointer
*/
-#define PTR(val) OBJP(T_UINT, (void*)(val))
+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.
@@ -237,7 +239,9 @@
* @param ty typecode
* @return sxpr
*/
-#define halloc(_n, _ty) OBJP(_ty, allocate(_n))
+static inline Sxpr halloc(int n, int ty){
+ return OBJP(ty, allocate(n));
+}
/** Allocate an sxpr containing a pointer to the given type.
*
diff -r 9fb0bad776dd tools/vnet/libxutil/sxpr_parser.c
--- a/tools/vnet/libxutil/sxpr_parser.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/libxutil/sxpr_parser.c Fri Aug 26 09:04:02 2005
@@ -472,7 +472,14 @@
}
int Parser_atom(Parser *p){
- Sxpr obj = atom_new(peek_token(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);
}
diff -r 9fb0bad776dd tools/vnet/libxutil/sxpr_parser.h
--- a/tools/vnet/libxutil/sxpr_parser.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/libxutil/sxpr_parser.h Fri Aug 26 09:04:02 2005
@@ -89,15 +89,17 @@
/** Parser flags. */
-//enum {
-//};
+enum {
+ /** Convert integer atoms to ints. */
+ PARSE_INT=1,
+};
/** Raise some parser flags.
*
* @param in parser
* @param flags flags mask
*/
-inline static void Parser_flags_raise(Parser *in, int flags){
+static inline void Parser_flags_raise(Parser *in, int flags){
in->flags |= flags;
}
@@ -106,7 +108,7 @@
* @param in parser
* @param flags flags mask
*/
-inline static void Parser_flags_lower(Parser *in, int flags){
+static inline void Parser_flags_lower(Parser *in, int flags){
in->flags &= ~flags;
}
@@ -114,8 +116,12 @@
*
* @param in parser
*/
-inline static void Parser_flags_clear(Parser *in){
+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);
diff -r 9fb0bad776dd tools/vnet/libxutil/sys_string.c
--- a/tools/vnet/libxutil/sys_string.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/libxutil/sys_string.c Fri Aug 26 09:04:02 2005
@@ -27,6 +27,31 @@
#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.
diff -r 9fb0bad776dd tools/vnet/libxutil/sys_string.h
--- a/tools/vnet/libxutil/sys_string.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/libxutil/sys_string.h Fri Aug 26 09:04:02 2005
@@ -31,6 +31,8 @@
#include <linux/types.h>
#include <stdarg.h>
#include "allocate.h"
+
+extern char *strerror(int err);
#if 0
static inline int tolower(int c){
diff -r 9fb0bad776dd tools/vnet/vnet-module/00README
--- a/tools/vnet/vnet-module/00README Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/00README Fri Aug 26 09:04:02 2005
@@ -6,11 +6,11 @@
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 (default), or 2.6.
-XEN_ROOT: root of the xen tree containing kernel source.
+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_MINOR: kernel minor version, default -xen0.
-KERNEL_SRC: path to kernel source, default linux-<VERSION> under XEN_ROOT.
+KERNEL_MINOR: kernel minor version, default -xen0.
+KERNEL_SRC: path to kernel source, default linux-<VERSION> under XEN_ROOT.
*) For 2.4 kernel
diff -r 9fb0bad776dd tools/vnet/vnet-module/Makefile
--- a/tools/vnet/vnet-module/Makefile Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/Makefile Fri Aug 26 09:04:02 2005
@@ -18,9 +18,13 @@
# 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),)
-LINUX_SERIES ?=2.6
include Makefile-$(LINUX_SERIES)
@@ -45,7 +49,7 @@
# Setup explicit rules for them using the kbuild C compile rule.
# File names in the lib dir.
-remote_srcs = $(foreach file,$(VNET_LIB_SRC),$(LIB_DIR)/$(file))
+remote_srcs = $(foreach file,$(VNET_LIB_SRC),$(LIBXUTIL_DIR)/$(file))
# Equivalent file names here.
local_srcs = $(foreach file,$(VNET_LIB_SRC),$(src)/$(file))
@@ -54,12 +58,12 @@
local_objs = $(local_srcs:.c=.o)
# Make the local objects depend on compiling the remote sources.
-$(local_objs): $(src)/%.o: $(LIB_DIR)/%.c
+$(local_objs): $(src)/%.o: $(LIBXUTIL_DIR)/%.c
$(call if_changed_rule,cc_o_c)
#----------------------------------------------------------------------------
-vpath %.h $(LIB_DIR)
-EXTRA_CFLAGS += -I $(LIB_DIR)
+vpath %.h $(LIBXUTIL_DIR)
+EXTRA_CFLAGS += -I $(LIBXUTIL_DIR)
EXTRA_CFLAGS += -I $(src)
endif
diff -r 9fb0bad776dd tools/vnet/vnet-module/Makefile-2.4
--- a/tools/vnet/vnet-module/Makefile-2.4 Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/Makefile-2.4 Fri Aug 26 09:04:02 2005
@@ -21,7 +21,7 @@
#============================================================================
# Vnet module makefile for 2.4 series kernels.
-LINUX_SERIES ?=2.4
+LINUX_SERIES =2.4
include Makefile.ver
KERNEL_MODULE := vnet_module.o
@@ -37,9 +37,9 @@
vpath %.h $(KERNEL_SRC)/include
INCLUDES+= -I $(KERNEL_SRC)/include
-vpath %.h $(LIB_DIR)
-vpath %.c $(LIB_DIR)
-INCLUDES += -I $(LIB_DIR)
+vpath %.h $(LIBXUTIL_DIR)
+vpath %.c $(LIBXUTIL_DIR)
+INCLUDES += -I $(LIBXUTIL_DIR)
INCLUDES+= -I .
@@ -61,6 +61,7 @@
CFLAGS += -Wno-unused-function
CFLAGS += -Wno-unused-parameter
+CFLAGS += -g
CFLAGS += -O2
CFLAGS += -fno-strict-aliasing
CFLAGS += -fno-common
@@ -90,8 +91,8 @@
.PHONY: clean
clean:
- @rm -f *.a *.o *.ko *~
- @rm -f $(VNET_DEP) .*.cmd *.mod.?
- @rm -rf .tmp_versions
+ -@$(RM) *.a *.o *.ko *~
+ -@$(RM) $(VNET_DEP) .*.cmd *.mod.?
+ -@$(RM) -r .tmp_versions
-include $(VNET_DEP)
diff -r 9fb0bad776dd tools/vnet/vnet-module/Makefile-2.6
--- a/tools/vnet/vnet-module/Makefile-2.6 Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/Makefile-2.6 Fri Aug 26 09:04:02 2005
@@ -21,7 +21,7 @@
#============================================================================
# Vnet module makefile for 2.6 series kernels.
-LINUX_SERIES ?=2.6
+LINUX_SERIES =2.6
include Makefile.ver
KERNEL_MODULE = vnet_module.ko
@@ -38,13 +38,14 @@
.PHONY: install install-module modules_install
install install-module modules_install: module
- install -m 0755 -d $(DESTDIR)$(KERNEL_MODULE_DIR)/xen
- install -m 0554 $(KERNEL_MODULE) $(DESTDIR)$(KERNEL_MODULE_DIR)/xen
+ 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 -f *.a *.o *.ko *~ .*.d .*.cmd *.mod.?
+ -@$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
+ -@$(RM) *.a *.o *.ko *~ .*.d .*.cmd *.mod.?
+ -@$(RM) -r .tmp_versions
TAGS:
etags *.c *.h
diff -r 9fb0bad776dd tools/vnet/vnet-module/Makefile.ver
--- a/tools/vnet/vnet-module/Makefile.ver Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/Makefile.ver Fri Aug 26 09:04:02 2005
@@ -18,22 +18,11 @@
# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
#============================================================================
-#----------------------------------------------------------------------------
-# Xeno/xen.
-
-# Root of xen tree.
-XEN_ROOT ?=../../..
-
-# Path to relativize the install. Set to /
-# to install relative to filesystem root.
-prefix ?=$(XEN_ROOT)/install/
-#----------------------------------------------------------------------------
-
LINUX_SERIES ?=2.6
KERNEL_MINOR ?=-xen0
-LINUX_VERSION ?= $(shell ( /bin/ls -ld
$(XEN_ROOT)/linux-$(LINUX_SERIES).*-xen-sparse ) 2>/dev/null | \
- sed -e 's!^.*linux-\(.\+\)-xen-sparse!\1!' )
+LINUX_VERSION ?= $(shell ( /bin/ls -ld
$(XEN_ROOT)/linux-$(LINUX_SERIES).*-xen0 ) 2>/dev/null | \
+ sed -e 's!^.*linux-\(.\+\)-xen0!\1!' )
ifeq ($(LINUX_VERSION),)
$(error Kernel source for linux $(LINUX_SERIES) not found)
diff -r 9fb0bad776dd tools/vnet/vnet-module/Makefile.vnet
--- a/tools/vnet/vnet-module/Makefile.vnet Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/Makefile.vnet Fri Aug 26 09:04:02 2005
@@ -23,8 +23,6 @@
else
SRC_DIR=$(src)/
endif
-
-LIB_DIR := $(SRC_DIR)../libxutil
VNET_SRC :=
VNET_SRC += esp.c
diff -r 9fb0bad776dd tools/vnet/vnet-module/etherip.c
--- a/tools/vnet/vnet-module/etherip.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/etherip.c Fri Aug 26 09:04:02 2005
@@ -42,6 +42,7 @@
#include <vnet.h>
#include <varp.h>
#include <if_varp.h>
+#include <varp.h>
#include <skb_util.h>
#define MODULE_NAME "VNET"
@@ -53,22 +54,18 @@
* The etherip protocol is used to transport Ethernet frames in IP packets.
*/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#define MAC_ETH(_skb) ((struct ethhdr *)(_skb)->mac.raw)
+/** 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
-#define MAC_ETH(_skb) ((_skb)->mac.ethernet)
-#endif
-
-/** Get the vnet label from an etherip header.
- *
- * @param hdr header
- * @return vnet (in host order)
- */
-int etheriphdr_get_vnet(struct etheriphdr *hdr){
-#ifdef CONFIG_ETHERIP_EXT
- return ntohl(hdr->vnet);
-#else
- return hdr->reserved;
+ *vnet = (VnetId){};
+ vnet->u.vnet16[7] = (unsigned short)hdr->reserved;
+
#endif
}
@@ -76,15 +73,15 @@
* Also sets the etherip version.
*
* @param hdr header
- * @param vnet vnet label (in host order)
- */
-void etheriphdr_set_vnet(struct etheriphdr *hdr, int vnet){
+ * @param vnet vnet label (in net order)
+ */
+void etheriphdr_set_vnet(struct etheriphdr *hdr, VnetId *vnet){
#ifdef CONFIG_ETHERIP_EXT
- hdr->version = 4;
- hdr->vnet = htonl(vnet);
+ hdr->version = ETHERIP_VERSION;
+ *(VnetId*)hdr->vnet = *vnet;
#else
- hdr->version = 3;
- hdr->reserved = vnet & 0x0fff;
+ hdr->version = ETHERIP_VERSION;
+ hdr->reserved = (vnet->u.vnet16[7] & 0x0fff);
#endif
}
@@ -119,12 +116,12 @@
const int ip_n = sizeof(struct iphdr);
const int eth_n = ETH_HLEN;
int head_n = 0;
- int vnet = tunnel->key.vnet;
+ VnetId *vnet = &tunnel->key.vnet;
struct etheriphdr *etheriph;
struct ethhdr *ethh;
u32 saddr = 0;
- dprintf("> skb=%p vnet=%d\n", skb, vnet);
+ //dprintf("> skb=%p vnet=%d\n", skb, vnet);
head_n = etherip_n + ip_n + eth_n;
err = skb_make_room(&skb, skb, head_n, 0);
if(err) goto exit;
@@ -133,7 +130,7 @@
//if(err) goto exit;
// The original ethernet header.
- ethh = MAC_ETH(skb);
+ ethh = eth_hdr(skb);
//print_skb_data(__FUNCTION__, 0, skb, skb->mac.raw, skb->len);
// Null the pointer as we are pushing a new IP header.
skb->mac.raw = NULL;
@@ -155,7 +152,7 @@
skb->nh.iph->ttl = 64; // Linux default
time-to-live.
skb->nh.iph->protocol = IPPROTO_ETHERIP; // IP protocol number.
skb->nh.iph->saddr = saddr; // Source address.
- skb->nh.iph->daddr = tunnel->key.addr; // Destination address.
+ skb->nh.iph->daddr = tunnel->key.addr.u.ip4.s_addr; // Destination
address.
skb->nh.iph->check = 0;
// Ethernet header will be filled-in by device.
@@ -213,15 +210,18 @@
struct etheriphdr *etheriph;
struct ethhdr *ethhdr;
Vnet *vinfo = NULL;
- u32 vnet;
-
- ethhdr = MAC_ETH(skb);
- if(MULTICAST(skb->nh.iph->daddr) &&
- (skb->nh.iph->daddr != varp_mcast_addr)){
+ VnetId vnet = {};
+ u32 saddr, daddr;
+ char vnetbuf[VNET_ID_BUF];
+
+ saddr = skb->nh.iph->saddr;
+ daddr = skb->nh.iph->daddr;
+ ethhdr = eth_hdr(skb);
+ if(MULTICAST(daddr) && (daddr != varp_mcast_addr)){
// Ignore multicast packets not addressed to us.
- dprintf("> dst=%u.%u.%u.%u varp_mcast_addr=%u.%u.%u.%u\n",
- NIPQUAD(skb->nh.iph->daddr),
- NIPQUAD(varp_mcast_addr));
+ dprintf("> 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;
}
ip_n = (skb->nh.iph->ihl << 2);
@@ -229,7 +229,8 @@
// skb->data points at ethernet header.
//dprintf("> len=%d\n", skb->len);
if (!pskb_may_pull(skb, eth_n + ip_n)){
- wprintf("> Malformed skb\n");
+ wprintf("> Malformed skb (eth+ip) src=%u.%u.%u.%u\n",
+ NIPQUAD(saddr));
err = -EINVAL;
goto exit;
}
@@ -237,18 +238,30 @@
}
// Assume skb->data points at etherip header.
etheriph = (void*)skb->data;
- if(!pskb_may_pull(skb, etherip_n)){
- wprintf("> Malformed skb\n");
+ if(etheriph->version != ETHERIP_VERSION){
+ wprintf("> Bad etherip version=%d src=%u.%u.%u.%u\n",
+ etheriph->version,
+ NIPQUAD(saddr));
err = -EINVAL;
goto exit;
}
- vnet = etheriphdr_get_vnet(etheriph);
- dprintf("> Rcvd skb=%p vnet=%d\n", skb, vnet);
+ 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);
+ dprintf("> Rcvd skb vnet=%s src=%u.%u.%u.%u\n",
+ VnetId_ntoa(&vnet, vnetbuf),
+ NIPQUAD(saddr));
// If vnet is secure, context must include IPSEC ESP.
- err = vnet_check_context(vnet, SKB_CONTEXT(skb), &vinfo);
+ err = vnet_check_context(&vnet, SKB_CONTEXT(skb), &vinfo);
Vnet_decref(vinfo);
if(err){
- wprintf("> Failed security check\n");
+ wprintf("> Failed security check vnet=%s src=%u.%u.%u.%u\n",
+ VnetId_ntoa(&vnet, vnetbuf),
+ NIPQUAD(saddr));
goto exit;
}
mine = 1;
@@ -258,19 +271,29 @@
// Know source ip, vnet, vmac, so could update varp cache.
// But if traffic comes to us over a vnetd tunnel this points the coa
// at the vnetd rather than the endpoint. So don't do it.
- //varp_update(htonl(vnet), MAC_ETH(skb)->h_source, skb->nh.iph->saddr);
+ //varp_update(vnet, eth_hdr(skb)->h_source, skb->nh.iph->saddr);
// Assuming a standard Ethernet frame.
+ // Should check for protocol? Support ETH_P_8021Q too.
skb->nh.raw = skb_pull(skb, ETH_HLEN);
+
+ dprintf("> Unpacked vnet=%s srcmac=" MACFMT " dstmac=" MACFMT "\n",
+ VnetId_ntoa(&vnet, vnetbuf),
+ MAC6TUPLE(eth_hdr(skb)->h_source),
+ MAC6TUPLE(eth_hdr(skb)->h_dest));
#ifdef CONFIG_NETFILTER
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
// This stops our new pkt header being clobbered by a subsequent
- // call to nf_bridge_maybe_copy_header. Just replicate the
- // corresponding nf_bridge_save_header.
+ // call to nf_bridge_maybe_copy_header.
+ // Code from nf_bridge_save_header() modidifed to use h_proto
+ // instead of skb->protocol.
if(skb->nf_bridge){
+ // Hmm. Standard ethernet header is ETH_HLEN (14),
+ // VLAN header (802.1q) is VLAN_ETH_HLEN (18).
+ // Where does 16 come from?
int header_size = 16;
- if(MAC_ETH(skb)->h_proto == __constant_htons(ETH_P_8021Q)) {
+ if(eth_hdr(skb)->h_proto == __constant_htons(ETH_P_8021Q)) {
header_size = 18;
}
memcpy(skb->nf_bridge->data, skb->data - header_size, header_size);
@@ -279,7 +302,7 @@
#endif
if(1){
- struct ethhdr *eth = MAC_ETH(skb);
+ struct ethhdr *eth = eth_hdr(skb);
// Devices use eth_type_trans() to set skb->pkt_type and skb->protocol.
// Set them from contained ethhdr, or leave as received?
// 'Ware use of hard_header_len in eth_type_trans().
@@ -310,6 +333,7 @@
}
dst_release(skb->dst);
skb->dst = NULL;
+
#ifdef CONFIG_NETFILTER
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
@@ -321,7 +345,7 @@
//print_skb_data(__FUNCTION__, 0, skb, skb->mac.raw, skb->len + ETH_HLEN);
- err = vnet_skb_recv(skb, vnet, (Vmac*)MAC_ETH(skb)->h_dest);
+ err = vnet_skb_recv(skb, &vnet, (Vmac*)eth_hdr(skb)->h_dest);
exit:
if(mine) err = 1;
dprintf("< skb=%p err=%d\n", skb, err);
diff -r 9fb0bad776dd tools/vnet/vnet-module/if_etherip.h
--- a/tools/vnet/vnet-module/if_etherip.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/if_etherip.h Fri Aug 26 09:04:02 2005
@@ -18,15 +18,30 @@
*/
#ifndef _VNET_IF_ETHERIP_H_
#define _VNET_IF_ETHERIP_H_
-/*----------------------------------------------------------------------------*/
+
+#define CONFIG_ETHERIP_EXT
+
#ifdef CONFIG_ETHERIP_EXT
+
+#define ETHERIP_VERSION 4
+
struct etheriphdr {
- __u8 version;
- __u32 vnet;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u16 reserved:12,
+ version:4;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+ __u16 version:4,
+ reserved:12;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 vnet[16];
} __attribute__ ((packed));
-/*----------------------------------------------------------------------------*/
#else
+
+#define ETHERIP_VERSION 3
+
struct etheriphdr
{
#if defined(__LITTLE_ENDIAN_BITFIELD)
@@ -42,10 +57,9 @@
};
#endif
+
#ifndef IPPROTO_ETHERIP
#define IPPROTO_ETHERIP 97
#endif
-/*----------------------------------------------------------------------------*/
-
#endif /* ! _VNET_IF_ETHERIP_H_ */
diff -r 9fb0bad776dd tools/vnet/vnet-module/if_varp.h
--- a/tools/vnet/vnet-module/if_varp.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/if_varp.h Fri Aug 26 09:04:02 2005
@@ -20,6 +20,14 @@
#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 <netinet/in.h>
+#endif
+
typedef struct Vmac {
unsigned char mac[ETH_ALEN];
} Vmac;
@@ -30,17 +38,35 @@
VARP_OP_ANNOUNCE = 2,
};
+typedef struct VnetId {
+ union {
+ uint8_t vnet8[16];
+ uint16_t vnet16[8];
+ uint32_t vnet32[4];
+ } 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;
+} __attribute__((packed)) VarpAddr;
+
typedef struct VnetMsgHdr {
uint16_t id;
uint16_t opcode;
} __attribute__((packed)) VnetMsgHdr;
typedef struct VarpHdr {
- VnetMsgHdr vnetmsghdr;
- uint32_t vnet;
- Vmac vmac;
- uint32_t addr;
+ 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
@@ -48,6 +74,4 @@
/** UDP port to use for varp protocol. */
#define VARP_PORT 1798
-
-
-#endif /* ! _VNET_IF_VARP_H */
+#endif /* ! _VNET_IF_VARP_H */
diff -r 9fb0bad776dd tools/vnet/vnet-module/skb_util.h
--- a/tools/vnet/vnet-module/skb_util.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/skb_util.h Fri Aug 26 09:04:02 2005
@@ -19,7 +19,9 @@
#ifndef _VNET_SKB_UTIL_H_
#define _VNET_SKB_UTIL_H_
-struct sk_buff;
+#include <net/route.h>
+#include <linux/skbuff.h>
+
struct scatterlist;
extern int skb_make_room(struct sk_buff **pskb, struct sk_buff *skb, int
head_n, int tail_n);
@@ -40,4 +42,53 @@
extern void print_skb_data(char *msg, int count, struct sk_buff *skb, u8
*data, int len);
+/* The mac.ethernet field went away in 2.6 in favour of eth_hdr().
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#else
+static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
+{
+ return (struct ethhdr *)skb->mac.raw;
+}
#endif
+
+
+#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
diff -r 9fb0bad776dd tools/vnet/vnet-module/tunnel.c
--- a/tools/vnet/vnet-module/tunnel.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/tunnel.c Fri Aug 26 09:04:02 2005
@@ -36,7 +36,7 @@
#include "hash_table.h"
#define MODULE_NAME "VNET"
-//#define DEBUG 1
+#define DEBUG 1
#undef DEBUG
#include "debug.h"
@@ -56,11 +56,9 @@
}
}
-int Tunnel_create(TunnelType *type, u32 vnet, u32 addr, Tunnel *base, Tunnel
**val){
+int Tunnel_create(TunnelType *type, VnetId *vnet, VarpAddr *addr, Tunnel
*base, Tunnel **val){
int err = 0;
Tunnel *tunnel = NULL;
- dprintf("> type=%s vnet=%d addr=" IPFMT " base=%s\n",
- type->name, vnet, NIPQUAD(addr), (base ? base->type->name : "ip"));
if(!type || !type->open || !type->send || !type->close){
err = -EINVAL;
goto exit;
@@ -71,8 +69,8 @@
goto exit;
}
atomic_set(&tunnel->refcount, 1);
- tunnel->key.vnet = vnet;
- tunnel->key.addr = addr;
+ tunnel->key.vnet = *vnet;
+ tunnel->key.addr = *addr;
tunnel->type = type;
tunnel->data = NULL;
tunnel->send_stats = (TunnelStats){};
@@ -89,7 +87,7 @@
return err;
}
-int Tunnel_open(TunnelType *type, u32 vnet, u32 addr, Tunnel *base, Tunnel
**tunnel){
+int Tunnel_open(TunnelType *type, VnetId *vnet, VarpAddr *addr, Tunnel *base,
Tunnel **tunnel){
int err = 0;
dprintf(">\n");
@@ -123,15 +121,16 @@
static inline Hashcode tunnel_table_key_hash_fn(void *k){
TunnelKey *key = k;
Hashcode h = 0;
- h = hash_2ul(key->vnet, key->addr);
+ h = VnetId_hash(h, &key->vnet);
+ h = VarpAddr_hash(h, &key->addr);
return h;
}
static int tunnel_table_key_equal_fn(void *k1, void *k2){
TunnelKey *key1 = k1;
TunnelKey *key2 = k2;
- return (key1->vnet == key2->vnet)
- && (key1->addr == key2->addr);
+ return VnetId_eq(&key1->vnet, &key2->vnet) &&
+ VarpAddr_eq(&key1->addr, &key2->addr);
}
static void tunnel_table_entry_free_fn(HashTable *table, HTEntry *entry){
@@ -165,9 +164,9 @@
* @param addr destination address
* @return tunnel state or NULL
*/
-Tunnel * Tunnel_lookup(u32 vnet, u32 addr){
+Tunnel * Tunnel_lookup(VnetId *vnet, VarpAddr *addr){
Tunnel *tunnel = NULL;
- TunnelKey key = {.vnet = vnet, .addr = addr };
+ TunnelKey key = {.vnet = *vnet, .addr = *addr };
dprintf(">\n");
tunnel = HashTable_get(tunnel_table, &key);
Tunnel_incref(tunnel);
@@ -199,23 +198,16 @@
*/
int Tunnel_send(Tunnel *tunnel, struct sk_buff *skb){
int err = 0;
- int len;
dprintf("> tunnel=%p skb=%p\n", tunnel, skb);
- len = skb->len;
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);
- // Must not refer to skb after sending - might have been freed.
TunnelStats_update(&tunnel->send_stats, len, err);
} else {
- struct net_device *dev = NULL;
- err = vnet_get_device(DEVICE, &dev);
- if(err) goto exit;
- skb->dev = dev;
err = skb_xmit(skb);
- dev_put(dev);
- }
- exit:
+ }
dprintf("< err=%d\n", err);
return err;
}
@@ -225,4 +217,8 @@
}
void __exit tunnel_module_exit(void){
-}
+ if(tunnel_table){
+ HashTable_free(tunnel_table);
+ tunnel_table = NULL;
+ }
+}
diff -r 9fb0bad776dd tools/vnet/vnet-module/tunnel.h
--- a/tools/vnet/vnet-module/tunnel.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/tunnel.h Fri Aug 26 09:04:02 2005
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <asm/atomic.h>
+#include <if_varp.h>
struct sk_buff;
struct Tunnel;
@@ -41,8 +42,8 @@
} TunnelStats;
typedef struct TunnelKey {
- u32 vnet;
- u32 addr;
+ VnetId vnet;
+ VarpAddr addr;
} TunnelKey;
typedef struct Tunnel {
@@ -87,13 +88,15 @@
}
extern int Tunnel_init(void);
-extern Tunnel * Tunnel_lookup(u32 vnet, u32 addr);
+extern Tunnel * Tunnel_lookup(struct VnetId *vnet, struct VarpAddr *addr);
extern int Tunnel_add(Tunnel *tunnel);
extern int Tunnel_del(Tunnel *tunnel);
extern int Tunnel_send(Tunnel *tunnel, struct sk_buff *skb);
-extern int Tunnel_create(TunnelType *type, u32 vnet, u32 addr, Tunnel *base,
Tunnel **tunnelp);
-extern int Tunnel_open(TunnelType *type, u32 vnet, u32 addr, Tunnel *base,
Tunnel **tunnelp);
+extern int Tunnel_create(TunnelType *type, struct VnetId *vnet, struct
VarpAddr *addr,
+ Tunnel *base, Tunnel **tunnelp);
+extern int Tunnel_open(TunnelType *type, struct VnetId *vnet, struct VarpAddr
*addr,
+ Tunnel *base, Tunnel **tunnelp);
extern int tunnel_module_init(void);
extern void tunnel_module_exit(void);
diff -r 9fb0bad776dd tools/vnet/vnet-module/varp.c
--- a/tools/vnet/vnet-module/varp.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/varp.c Fri Aug 26 09:04:02 2005
@@ -40,26 +40,20 @@
#include <tunnel.h>
#include <vnet.h>
#include <vif.h>
+#include <if_varp.h>
#include <varp.h>
-#include <if_varp.h>
+#include <vnet.h>
#include "allocate.h"
#include "hash_table.h"
#include "sys_net.h"
#include "sys_string.h"
+#include "skb_util.h"
#define MODULE_NAME "VARP"
-//#define DEBUG 1
+#define DEBUG 1
#undef DEBUG
#include "debug.h"
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-// The 'ethernet' field in the skb->mac union went away.
-#define MAC_ETH(_skb) ((struct ethhdr *)(_skb)->mac.raw)
-#else
-#define MAC_ETH(_skb) ((_skb)->mac.ethernet)
-#endif
/** @file VARP: Virtual ARP.
*
@@ -121,8 +115,8 @@
/** Key for varp entries. */
typedef struct VarpKey {
- /** Vnet id (host order). */
- u32 vnet;
+ /** Vnet id (network order). */
+ VnetId vnet;
/** Virtual MAC address. */
Vmac vmac;
} VarpKey;
@@ -132,7 +126,7 @@
/** Key for the entry. */
VarpKey key;
/** Care-of address for the key. */
- u32 addr;
+ VarpAddr addr;
/** Last-updated timestamp. */
unsigned long timestamp;
/** State. */
@@ -152,8 +146,6 @@
struct sk_buff_head queue;
/** Maximum size of the queue. */
int queue_max;
-
- int locks;
} VarpEntry;
/** The varp cache. Varp entries indexed by VarpKey. */
@@ -181,14 +173,10 @@
/** Multicast address (network order). */
u32 varp_mcast_addr = 0;
-/** Unicast address (network order). */
-u32 varp_ucast_addr = 0;
-
/** UDP port (network order). */
u16 varp_port = 0;
-/** Network device to use. */
-char *varp_device = DEVICE;
+char *varp_device = "xen-br0";
#define VarpTable_read_lock(z, flags) do{ (flags) = 0; down(&(z)->lock); }
while(0)
#define VarpTable_read_unlock(z, flags) do{ (flags) = 0; up(&(z)->lock); }
while(0)
@@ -199,7 +187,10 @@
#define VarpEntry_unlock(ventry, flags)
write_unlock_irqrestore(&(ventry)->lock, (flags))
void VarpTable_sweep(VarpTable *z, int all);
+void VarpTable_flush(VarpTable *z);
void VarpTable_print(VarpTable *z);
+
+#include "./varp_util.c"
/** Print the varp cache (if debug on).
*/
@@ -209,14 +200,53 @@
#endif
}
+/** Flush the varp cache.
+ */
+void varp_flush(void){
+ VarpTable_flush(varp_table);
+}
+
+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;
+}
+
/** Print varp info and the varp cache.
*/
void varp_print(void){
+ uint32_t addr = 0;
+ varp_ucast_addr(&addr);
+
printk(KERN_INFO "=== VARP
===============================================================\n");
printk(KERN_INFO "varp_device %s\n", varp_device);
printk(KERN_INFO "varp_mcast_addr " IPFMT "\n", NIPQUAD(varp_mcast_addr));
- printk(KERN_INFO "varp_ucast_addr " IPFMT "\n", NIPQUAD(varp_ucast_addr));
+ printk(KERN_INFO "varp_ucast_addr " IPFMT "\n", NIPQUAD(addr));
printk(KERN_INFO "varp_port %d\n", ntohs(varp_port));
+ vnet_print();
+ vif_print();
VarpTable_print(varp_table);
printk(KERN_INFO
"========================================================================\n");
}
@@ -246,18 +276,43 @@
int err = 0;
struct in_device *in_dev;
- //printk("%s>\n", __FUNCTION__);
in_dev = in_dev_get(dev);
if(!in_dev){
- err = -EIO;
+ err = -ENODEV;
goto exit;
}
*addr = in_dev->ifa_list->ifa_address;
in_dev_put(in_dev);
exit:
- //printk("%s< err=%d\n", __FUNCTION__, err);
- return err;
-}
+ return err;
+}
+
+#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
#ifndef LL_RESERVED_SPACE
#define HH_DATA_MOD 16
@@ -270,12 +325,12 @@
* @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 host order)
+ * @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,
- u32 vnet, Vmac *vmac){
+ VnetId *vnet, Vmac *vmac){
int err = 0;
int link_n = 0;
int ip_n = sizeof(struct iphdr);
@@ -285,45 +340,53 @@
struct in_device *in_dev = NULL;
VarpHdr *varph = NULL;
u8 macbuf[6] = {};
- u8 *smac, *dmac;
+ u8 *smac, *dmac = macbuf;
u32 saddr, daddr;
u16 sport, dport;
-
- dmac = macbuf;
- dprintf("> opcode=%d vnet=%d vmac=" MACFMT "\n",
- opcode, ntohl(vnet), MAC6TUPLE(vmac->mac));
- if(!dev){
- //todo: should use routing for daddr to get device.
- err = vnet_get_device(varp_device, &dev);
- if(err) goto exit;
- }
- link_n = LL_RESERVED_SPACE(dev);
- in_dev = in_dev_get(dev);
- if(!in_dev) goto exit;
-
- smac = dev->dev_addr;
- saddr = in_dev->ifa_list->ifa_address;
-
+#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){
- dmac = MAC_ETH(skbin)->h_source;
+ daddr = skbin->nh.iph->saddr;
+ dmac = eth_hdr(skbin)->h_source;
sport = skbin->h.uh->dest;
- daddr = skbin->nh.iph->saddr;
- //dport = skbin->h.uh->source;
- dport = varp_port;
} else {
- if(!in_dev) goto exit;
if(MULTICAST(varp_mcast_addr)){
daddr = varp_mcast_addr;
ip_eth_mc_map(daddr, dmac);
} else {
- daddr = in_dev->ifa_list->ifa_broadcast;
- dmac = dev->broadcast;
+ daddr = INADDR_BROADCAST;
}
sport = varp_port;
- dport = varp_port;
+ }
+
+ 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);
+ dprintf("> dev=%s\n", dev->name);
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));
@@ -368,11 +431,12 @@
// Varp header.
varph = (void*)skb_put(skbout, varp_n);
*varph = (VarpHdr){};
- varph->vnetmsghdr.id = htons(VARP_ID);
- varph->vnetmsghdr.opcode = htons(opcode);
- varph->vnet = htonl(vnet);
+ varph->hdr.id = htons(VARP_ID);
+ varph->hdr.opcode = htons(opcode);
+ varph->vnet = *vnet;
varph->vmac = *vmac;
- varph->addr = saddr;
+ varph->addr.family = AF_INET;
+ varph->addr.u.ip4.s_addr = saddr;
err = skb_xmit(skbout);
@@ -385,16 +449,13 @@
/** Send a varp request for the vnet and destination mac of a packet.
*
* @param skb packet
- * @param vnet vnet (in host order)
+ * @param vnet vnet (in network order)
* @return 0 on success, error code otherwise
*/
-int varp_solicit(struct sk_buff *skb, int vnet){
- int err = 0;
- dprintf("> skb=%p\n", skb);
- varp_dprint();
+int varp_solicit(struct sk_buff *skb, VnetId *vnet){
+ int err = 0;
err = varp_send(VARP_OP_REQUEST, NULL, NULL,
- vnet, (Vmac*)MAC_ETH(skb)->h_dest);
- dprintf("< err=%d\n", err);
+ vnet, (Vmac*)eth_hdr(skb)->h_dest);
return err;
}
@@ -430,22 +491,26 @@
*/
void VarpEntry_print(VarpEntry *ventry){
if(ventry){
- char *c, *d;
+ char *state, *flags;
+ char vnetbuf[VNET_ID_BUF];
+ char addrbuf[VARP_ADDR_BUF];
+
switch(ventry->state){
- case VARP_STATE_INCOMPLETE: c = "INC"; break;
- case VARP_STATE_REACHABLE: c = "RCH"; break;
- case VARP_STATE_FAILED: c = "FLD"; break;
- default: c = "UNK"; break;
+ case VARP_STATE_INCOMPLETE: state = "INC"; break;
+ case VARP_STATE_REACHABLE: state = "RCH"; break;
+ case VARP_STATE_FAILED: state = "FLD"; break;
+ default: state = "UNK"; break;
}
- d = (VarpEntry_get_flags(ventry, VARP_FLAG_PROBING) ? "P" : " ");
-
- printk(KERN_INFO "VENTRY(%p ref=%1d %s %s vnet=%d vmac=" MACFMT "
addr=" IPFMT " q=%d t=%lu)\n",
+ flags = (VarpEntry_get_flags(ventry, VARP_FLAG_PROBING) ? "P" : " ");
+
+ printk(KERN_INFO "VENTRY(%p ref=%1d %s %s vnet=%s vmac=" MACFMT
+ " addr=%s q=%3d t=%lu)\n",
ventry,
atomic_read(&ventry->refcount),
- c, d,
- ventry->key.vnet,
+ state, flags,
+ VnetId_ntoa(&ventry->key.vnet, vnetbuf),
MAC6TUPLE(ventry->key.vmac.mac),
- NIPQUAD(ventry->addr),
+ VarpAddr_ntoa(&ventry->addr, addrbuf),
skb_queue_len(&ventry->queue),
ventry->timestamp);
} else {
@@ -469,7 +534,6 @@
void VarpEntry_incref(VarpEntry *z){
if(!z) return;
atomic_inc(&z->refcount);
- //dprintf("> "); VarpEntry_print(z);
}
/** Decrement reference count, freeing if zero.
@@ -478,9 +542,7 @@
*/
void VarpEntry_decref(VarpEntry *z){
if(!z) return;
- //dprintf("> "); VarpEntry_print(z);
if(atomic_dec_and_test(&z->refcount)){
- //dprintf("> freeing %p...\n", z);
VarpEntry_free(z);
}
}
@@ -499,7 +561,7 @@
/** Schedule the varp entry timer.
* Must increment the reference count before doing
- * this the first time, so the ventry won' be freed
+ * this the first time, so the ventry won't be freed
* before the timer goes off.
*
* @param ventry varp entry
@@ -538,7 +600,7 @@
atomic_inc(&ventry->probes);
VarpEntry_unlock(ventry, flags);
locked = 0;
- varp_solicit(skb, ventry->key.vnet);
+ varp_solicit(skb, &ventry->key.vnet);
} else {
dprintf("> empty queue.\n");
}
@@ -568,7 +630,7 @@
* @param vmac virtual MAC address (copied)
* @return ventry or null
*/
-VarpEntry * VarpEntry_new(u32 vnet, Vmac *vmac){
+VarpEntry * VarpEntry_new(VnetId *vnet, Vmac *vmac){
VarpEntry *z = ALLOCATE(VarpEntry);
if(z){
unsigned long now = jiffies;
@@ -584,7 +646,7 @@
z->timestamp = now;
z->error = varp_error_fn;
- z->key.vnet = vnet;
+ z->key.vnet = *vnet;
z->key.vmac = *vmac;
}
return z;
@@ -598,15 +660,9 @@
*/
Hashcode varp_key_hash_fn(void *k){
VarpKey *key = k;
- Hashcode h;
- h = hash_2ul(key->vnet,
- (key->vmac.mac[0] << 24) |
- (key->vmac.mac[1] << 16) |
- (key->vmac.mac[2] << 8) |
- (key->vmac.mac[3] ));
- h = hash_hul(h,
- (key->vmac.mac[4] << 8) |
- (key->vmac.mac[5] ));
+ Hashcode h = 0;
+ h = VnetId_hash(h, &key->vnet);
+ h = Vmac_hash(h, &key->vmac);
return h;
}
@@ -620,8 +676,8 @@
int varp_key_equal_fn(void *k1, void *k2){
VarpKey *key1 = k1;
VarpKey *key2 = k2;
- return (key1->vnet == key2->vnet)
- && (memcmp(key1->vmac.mac, key2->vmac.mac, ETH_ALEN) == 0);
+ return (VnetId_eq(&key1->vnet, &key2->vnet) &&
+ Vmac_eq(&key1->vmac, &key2->vmac));
}
/** Free an entry in the varp cache.
@@ -670,12 +726,10 @@
*/
static void varp_table_timer_fn(unsigned long arg){
VarpTable *z = (VarpTable *)arg;
- //dprintf("> z=%p\n", z);
if(z){
VarpTable_sweep(z, 0);
VarpTable_schedule(z);
}
- //dprintf("<\n");
}
/** Print a varp table.
@@ -687,7 +741,6 @@
VarpEntry *ventry;
unsigned long flags, vflags;
- //dprintf(">\n");
VarpTable_read_lock(z, flags);
HashTable_for_each(entry, varp_table->table){
ventry = entry->value;
@@ -696,7 +749,6 @@
VarpEntry_unlock(ventry, vflags);
}
VarpTable_read_unlock(z, flags);
- //dprintf("<\n");
}
/** Create a varp table.
@@ -735,7 +787,7 @@
* @param vmac virtual MAC address (copied)
* @return new entry or null
*/
-VarpEntry * VarpTable_add(VarpTable *z, u32 vnet, Vmac *vmac){
+VarpEntry * VarpTable_add(VarpTable *z, VnetId *vnet, Vmac *vmac){
int err = -ENOMEM;
VarpEntry *ventry;
HTEntry *entry;
@@ -743,7 +795,6 @@
ventry = VarpEntry_new(vnet, vmac);
if(!ventry) goto exit;
- //dprintf("> "); VarpEntry_print(ventry);
VarpTable_write_lock(z, flags);
entry = HashTable_add(z->table, ventry, ventry);
VarpTable_write_unlock(z, flags);
@@ -775,19 +826,20 @@
* @param vmac virtual MAC addres
* @return entry found or null
*/
-VarpEntry * VarpTable_lookup(VarpTable *z, u32 vnet, Vmac *vmac){
+VarpEntry * VarpTable_lookup(VarpTable *z, VnetId *vnet, Vmac *vmac){
unsigned long flags;
- VarpKey key = { .vnet = vnet, .vmac = *vmac };
+ VarpKey key = { .vnet = *vnet, .vmac = *vmac };
VarpEntry *ventry;
VarpTable_read_lock(z, flags);
ventry = HashTable_get(z->table, &key);
+ if(ventry) VarpEntry_incref(ventry);
VarpTable_read_unlock(z, flags);
- if(ventry) VarpEntry_incref(ventry);
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
@@ -796,12 +848,12 @@
int VarpEntry_send(VarpEntry *ventry, struct sk_buff *skb){
int err = 0;
unsigned long flags = 0;
- u32 addr;
+ VarpAddr addr;
dprintf("> skb=%p\n", skb);
addr = ventry->addr;
VarpEntry_unlock(ventry, flags);
- err = vnet_tunnel_send(ventry->key.vnet, addr, skb);
+ err = vnet_tunnel_send(&ventry->key.vnet, &addr, skb);
VarpEntry_lock(ventry, flags);
dprintf("< err=%d\n", err);
return err;
@@ -811,6 +863,7 @@
* 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
@@ -820,7 +873,7 @@
int err = 0;
unsigned long flags = 0;
- dprintf("> skb=%p\n", skb); //VarpEntry_print(ventry);
+ dprintf("> skb=%p\n", skb);
ventry->state = VARP_STATE_INCOMPLETE;
atomic_set(&ventry->probes, 1);
if(!VarpEntry_get_flags(ventry, VARP_FLAG_PROBING)){
@@ -829,7 +882,7 @@
VarpEntry_schedule(ventry);
}
VarpEntry_unlock(ventry, flags);
- varp_solicit(skb, ventry->key.vnet);
+ varp_solicit(skb, &ventry->key.vnet);
VarpEntry_lock(ventry, flags);
if(ventry->state == VARP_STATE_INCOMPLETE){
@@ -837,7 +890,7 @@
struct sk_buff *oldskb;
oldskb = ventry->queue.next;
__skb_unlink(oldskb, &ventry->queue);
- dprintf("> purging skb=%p\n", oldskb);
+ dprintf("> dropping skb=%p\n", oldskb);
kfree_skb(oldskb);
}
__skb_queue_tail(&ventry->queue, skb);
@@ -893,33 +946,39 @@
* @param state state
* @return 0 on success, error code otherwise
*/
-int VarpEntry_update(VarpEntry *ventry, u32 addr, int state){
+int VarpEntry_update(VarpEntry *ventry, VarpAddr *addr, int state){
int err = 0;
unsigned long now = jiffies;
unsigned long flags;
dprintf("> addr=" IPFMT " state=%d\n", NIPQUAD(addr), state);
- //VarpEntry_print(ventry);
VarpEntry_lock(ventry, flags);
if(VarpEntry_get_flags(ventry, VARP_FLAG_PERMANENT)) goto exit;
- ventry->addr = addr;
+ ventry->addr = *addr;
ventry->timestamp = now;
ventry->state = state;
VarpEntry_process_queue(ventry);
exit:
- //dprintf("> "); VarpEntry_print(ventry);
VarpEntry_unlock(ventry, flags);
dprintf("< err=%d\n", err);
return err;
}
-int VarpTable_update(VarpTable *z, int vnet, Vmac *vmac, u32 addr,
+int VarpTable_update(VarpTable *z, VnetId *vnet, Vmac *vmac, VarpAddr *addr,
int state, int force){
int err = 0;
VarpEntry *ventry;
+#ifdef DEBUG
+ char vnetbuf[VNET_ID_BUF];
+ char addrbuf[VARP_ADDR_BUF];
+#endif
- dprintf("> vnet=%d mac=" MACFMT " addr=" IPFMT " state=%d force=%d\n",
- vnet, MAC6TUPLE(vmac->mac), NIPQUAD(addr), state, force);
+ dprintf("> vnet=%s mac=" MACFMT " addr=%s state=%d force=%d\n",
+ VnetId_ntoa(vnet, vnetbuf),
+ MAC6TUPLE(vmac->mac),
+ VarpAddr_ntoa(addr, addrbuf),
+ state,
+ force);
ventry = VarpTable_lookup(z, vnet, vmac);
if(force && !ventry){
dprintf("> No entry, adding\n");
@@ -945,10 +1004,10 @@
* @return 0 on success, -ENOENT if no entry found
*/
int VarpTable_update_entry(VarpTable *z, VarpHdr *varph, int state){
- return VarpTable_update(z, ntohl(varph->vnet), &varph->vmac, varph->addr,
state, 0);
-}
-
-int varp_update(int vnet, unsigned char *vmac, u32 addr){
+ return VarpTable_update(z, &varph->vnet, &varph->vmac, &varph->addr,
state, 0);
+}
+
+int varp_update(VnetId *vnet, unsigned char *vmac, VarpAddr *addr){
if(!varp_table){
return -ENOSYS;
}
@@ -971,7 +1030,6 @@
unsigned long old = now - VARP_ENTRY_TTL;
unsigned long flags, vflags;
- //dprintf(">\n");
VarpTable_read_lock(z, flags);
HashTable_for_each(entry, varp_table->table){
ventry = entry->value;
@@ -984,7 +1042,36 @@
VarpEntry_unlock(ventry, vflags);
}
VarpTable_read_unlock(z, flags);
- //dprintf("<\n");
+}
+
+/** Flush the varp table.
+ * Remove old unreachable varp entries with empty queues.
+ * Permanent entries are not removed.
+ *
+ * @param z table
+ */
+void VarpTable_flush(VarpTable *z){
+ HashTable_for_decl(entry);
+ VarpEntry *ventry;
+ unsigned long now = jiffies;
+ unsigned long old = now - VARP_ENTRY_TTL;
+ unsigned long flags, vflags;
+ int flush;
+
+ VarpTable_write_lock(z, flags);
+ HashTable_for_each(entry, varp_table->table){
+ ventry = entry->value;
+ VarpEntry_lock(ventry, vflags);
+ flush = (!VarpEntry_get_flags(ventry, VARP_FLAG_PERMANENT) &&
+ (ventry->timestamp < old) &&
+ (ventry->state != VARP_STATE_REACHABLE) &&
+ (skb_queue_len(&ventry->queue) == 0));
+ VarpEntry_unlock(ventry, vflags);
+ if(flush){
+ VarpTable_remove(z, ventry);
+ }
+ }
+ VarpTable_write_unlock(z, flags);
}
/** Handle a varp request. Look for a vif with the requested
@@ -997,14 +1084,13 @@
*/
int varp_handle_request(struct sk_buff *skb, VarpHdr *varph){
int err = -ENOENT;
- u32 vnet;
+ VnetId *vnet;
Vmac *vmac;
Vif *vif = NULL;
dprintf(">\n");
- vnet = ntohl(varph->vnet);
+ vnet = &varph->vnet;
vmac = &varph->vmac;
- dprintf("> vnet=%d vmac=" MACFMT "\n", vnet, MAC6TUPLE(vmac->mac));
if(vif_lookup(vnet, vmac, &vif)) goto exit;
varp_send(VARP_OP_ANNOUNCE, skb->dev, skb, vnet, vmac);
vif_decref(vif);
@@ -1026,7 +1112,7 @@
err = -ENOSYS;
goto exit;
}
- err = varp_send(VARP_OP_ANNOUNCE, dev, NULL, vif->vnet, &vif->vmac);
+ err = varp_send(VARP_OP_ANNOUNCE, dev, NULL, &vif->vnet, &vif->vmac);
exit:
dprintf("< err=%d\n", err);
return err;
@@ -1067,7 +1153,7 @@
(skb->nh.iph->daddr != varp_mcast_addr)){
// Ignore multicast packets not addressed to us.
err = 0;
- dprintf("> daddr=" IPFMT " mcaddr=" IPFMT "\n",
+ dprintf("> Ignoring daddr=" IPFMT " mcaddr=" IPFMT "\n",
NIPQUAD(skb->nh.iph->daddr), NIPQUAD(varp_mcast_addr));
goto exit;
}
@@ -1076,23 +1162,29 @@
goto exit;
}
mine = 1;
- if(varph->vnetmsghdr.id != htons(VARP_ID)){
+ if(varph->hdr.id != htons(VARP_ID)){
// It's not varp at all - ignore it.
- wprintf("> Unknown id: %d \n", ntohs(varph->vnetmsghdr.id));
+ wprintf("> Invalid varp id: %d, expected %d \n",
+ ntohs(varph->hdr.id),
+ VARP_ID);
goto exit;
}
- if(1){
+#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=%u vmac=" MACFMT " addr=" IPFMT "\n",
- ntohs(varph->vnetmsghdr.opcode),
- ntohl(varph->vnet),
+ dprintf("> opcode=%d vnet=%s vmac=" MACFMT " addr=%s\n",
+ ntohs(varph->hdr.opcode),
+ VnetId_ntoa(&varph->vnet, vnetbuf),
MAC6TUPLE(varph->vmac.mac),
- NIPQUAD(varph->addr));
+ VarpAddr_ntoa(&varph->addr, addrbuf));
varp_dprint();
}
- switch(ntohs(varph->vnetmsghdr.opcode)){
+#endif
+ switch(ntohs(varph->hdr.opcode)){
case VARP_OP_REQUEST:
err = varp_handle_request(skb, varph);
break;
@@ -1100,8 +1192,8 @@
err = varp_handle_announce(skb, varph);
break;
default:
- wprintf("> Unknown opcode: %d \n", ntohs(varph->vnetmsghdr.opcode));
- break;
+ wprintf("> Unknown opcode: %d \n", ntohs(varph->hdr.opcode));
+ break;
}
exit:
if(mine) err = 1;
@@ -1112,30 +1204,32 @@
/** Send an outgoing packet on the appropriate vnet tunnel.
*
* @param skb outgoing message
- * @param vnet vnet (host order)
+ * @param vnet vnet (network order)
* @return 0 on success, error code otherwise
*/
-int varp_output(struct sk_buff *skb, u32 vnet){
+int varp_output(struct sk_buff *skb, VnetId *vnet){
int err = 0;
unsigned char *mac = NULL;
Vmac *vmac = NULL;
VarpEntry *ventry = NULL;
- dprintf("> skb=%p vnet=%u\n", skb, vnet);
+ dprintf(">\n");
if(!varp_table){
err = -ENOSYS;
goto exit;
}
- dprintf("> skb.mac=%p\n", skb->mac.raw);
if(!skb->mac.raw){
wprintf("> No ethhdr in skb!\n");
err = -EINVAL;
goto exit;
}
- mac = MAC_ETH(skb)->h_dest;
+ mac = eth_hdr(skb)->h_dest;
vmac = (Vmac*)mac;
if(mac_is_multicast(mac)){
- err = vnet_tunnel_send(vnet, varp_mcast_addr, skb);
+ VarpAddr addr = {};
+ addr.family = AF_INET;
+ addr.u.ip4.s_addr = varp_mcast_addr;
+ err = vnet_tunnel_send(vnet, &addr, skb);
} else {
ventry = VarpTable_lookup(varp_table, vnet, vmac);
if(!ventry){
@@ -1165,7 +1259,7 @@
int err = 0;
varp_close();
varp_mcast_addr = addr;
- err = varp_open(varp_mcast_addr, varp_ucast_addr, varp_port);
+ err = varp_open(varp_mcast_addr, varp_port);
return err;
}
@@ -1191,7 +1285,6 @@
*/
int varp_init(void){
int err = 0;
- struct net_device *dev = NULL;
dprintf(">\n");
varp_table = VarpTable_new();
@@ -1200,18 +1293,10 @@
goto exit;
}
varp_init_mcast_addr(varp_mcaddr);
- err = vnet_get_device(varp_device, &dev);
- dprintf("> vnet_get_device(%s)=%d\n", varp_device, err);
- if(err) goto exit;
- err = vnet_get_device_address(dev, &varp_ucast_addr);
- dprintf("> vnet_get_device_address()=%d\n", err);
- if(err) goto exit;
varp_port = htons(VARP_PORT);
- err = varp_open(varp_mcast_addr, varp_ucast_addr, varp_port);
- dprintf("> varp_open()=%d\n", err);
+ err = varp_open(varp_mcast_addr, varp_port);
exit:
- if(dev) dev_put(dev);
dprintf("< err=%d\n", err);
return err;
}
diff -r 9fb0bad776dd tools/vnet/vnet-module/varp.h
--- a/tools/vnet/vnet-module/varp.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/varp.h Fri Aug 26 09:04:02 2005
@@ -19,6 +19,10 @@
#ifndef _VNET_VARP_H
#define _VNET_VARP_H
+#include "hash_table.h"
+#include "if_varp.h"
+#include "varp_util.h"
+
#define CONFIG_VARP_GRATUITOUS 1
@@ -26,29 +30,26 @@
struct sk_buff;
struct Vif;
-#define DEVICE "xen-br0"
-
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_handle_message(struct sk_buff *skb);
-extern int varp_output(struct sk_buff *skb, u32 vnet);
-extern int varp_update(int vnet, unsigned char *vmac, u32 addr);
+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, u32 addr, u16 port);
+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(void);
+extern void varp_flush(void);
extern int varp_announce_vif(struct net_device *dev, struct Vif *vif);
-//extern int varp_announce_vifs(struct net_device *dev, struct task_struct
*domain);
extern u32 varp_mcast_addr;
-
/* 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.
diff -r 9fb0bad776dd tools/vnet/vnet-module/varp_socket.c
--- a/tools/vnet/vnet-module/varp_socket.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/varp_socket.c Fri Aug 26 09:04:02 2005
@@ -177,7 +177,7 @@
/*============================================================================*/
/** Socket flags. */
-enum {
+enum VsockFlag {
VSOCK_REUSE = 1,
VSOCK_BIND = 2,
VSOCK_CONNECT = 4,
@@ -256,28 +256,13 @@
*/
int setsock_multicast(int sock, uint32_t saddr){
int err = 0;
- struct net_device *dev = NULL;
- u32 addr = 0;
struct ip_mreqn mreq = {};
int mloop = 0;
- err = vnet_get_device(DEVICE, &dev);
- if(err){
- eprintf("> error getting device: %d %d\n", err, errno);
- goto exit;
- }
- err = vnet_get_device_address(dev, &addr);
- if(err){
- eprintf("> error getting device address: %d %d\n", err, errno);
- goto exit;
- }
// See 'man 7 ip' for these options.
mreq.imr_multiaddr.s_addr = saddr; // IP multicast address.
- //mreq.imr_address.s_addr = addr; // Interface IP address.
mreq.imr_address.s_addr = INADDR_ANY; // Interface IP address.
mreq.imr_ifindex = 0; // Interface index (0 means any).
- dprintf("> saddr=%u.%u.%u.%u addr=%u.%u.%u.%u ifindex=%d\n",
- NIPQUAD(saddr), NIPQUAD(addr), mreq.imr_ifindex);
err = setsockopt(sock, SOL_IP, IP_MULTICAST_LOOP, &mloop, sizeof(mloop));
if(err < 0){
eprintf("> setsockopt IP_MULTICAST_LOOP: %d %d\n", err, errno);
@@ -305,7 +290,7 @@
}
/** Create a socket.
- * The flags can include VSOCK_REUSE, VSOCK_BROADCAST, VSOCK_CONNECT.
+ * The flags can include values from enum VsockFlag.
*
* @param socktype socket type
* @param saddr address
@@ -368,19 +353,15 @@
/** Open the varp multicast socket.
*
* @param mcaddr multicast address
- * @param saddr 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, uint32_t saddr, uint16_t port, int *val){
+int varp_mcast_open(uint32_t mcaddr, uint16_t port, int *val){
int err = 0;
int flags = VSOCK_REUSE;
int multicast = MULTICAST(mcaddr);
int sock = 0;
- struct sockaddr_in addr_in;
- struct sockaddr *addr = (struct sockaddr *)&addr_in;
- int addr_n = sizeof(addr_in);
dprintf(">\n");
flags |= VSOCK_MULTICAST;
@@ -392,23 +373,6 @@
err = setsock_multicast_ttl(sock, 1);
if(err < 0) goto exit;
}
- if(0){
- addr_in.sin_family = AF_INET;
- addr_in.sin_addr.s_addr = saddr;
- addr_in.sin_port = port;
- err = bind(sock, addr, addr_n);
- if(err < 0){
- eprintf("> bind: %d %d\n", err, errno);
- goto exit;
- }
- }
- if(0){
- struct sockaddr_in self = {};
- int self_n;
- getsockname(sock, (struct sockaddr *)&self, &self_n);
- dprintf("> sockname sock=%d addr=%u.%u.%u.%u port=%d\n",
- sock, NIPQUAD(saddr), ntohs(port));
- }
exit:
if(err){
shutdown(sock, 2);
@@ -427,7 +391,7 @@
*/
int varp_ucast_open(uint32_t addr, u16 port, int *val){
int err = 0;
- int flags = VSOCK_BIND | VSOCK_REUSE;
+ 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);
@@ -536,7 +500,6 @@
err = sock_add_wait_queue(varp_mcast_sock, &mcast_wait);
err = sock_add_wait_queue(varp_ucast_sock, &ucast_wait);
for(n = 1; atomic_read(&varp_run) == 1; n++){
- //dprintf("> n=%d\n", n);
count = 0;
count += handle_sock_skb(varp_mcast_sock);
count += handle_sock_skb(varp_ucast_sock);
@@ -609,20 +572,18 @@
/** Open the varp sockets and start the thread handling them.
*
* @param mcaddr multicast address
- * @param addr unicast address
* @param port port
* @return 0 on success, error code otherwise
*/
-int varp_open(u32 mcaddr, u32 addr, u16 port){
+int varp_open(u32 mcaddr, u16 port){
int err = 0;
mm_segment_t oldfs;
//MOD_INC_USE_COUNT;
- dprintf("> mcaddr=%u.%u.%u.%u addr=%u.%u.%u.%u port=%u\n",
- NIPQUAD(mcaddr), NIPQUAD(addr), ntohs(port));
- //MOD_INC_USE_COUNT;
+ dprintf("> mcaddr=%u.%u.%u.%u port=%u\n",
+ NIPQUAD(mcaddr), ntohs(port));
oldfs = change_fs(KERNEL_DS);
- err = varp_mcast_open(mcaddr, addr, port, &varp_mcast_sock);
+ 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;
diff -r 9fb0bad776dd tools/vnet/vnet-module/vif.c
--- a/tools/vnet/vnet-module/vif.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/vif.c Fri Aug 26 09:04:02 2005
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
+#include <linux/version.h>
#include <linux/net.h>
#include <linux/in.h>
@@ -33,11 +34,14 @@
#include <net/protocol.h>
#include <net/route.h>
#include <linux/skbuff.h>
+#include <linux/spinlock.h>
#include <etherip.h>
#include <if_varp.h>
#include <vnet_dev.h>
#include <vif.h>
+#include <varp.h>
+
#include "allocate.h"
#include "hash_table.h"
#include "sys_net.h"
@@ -50,6 +54,27 @@
/** Table of vifs indexed by VifKey. */
HashTable *vif_table = NULL;
+rwlock_t vif_table_lock = RW_LOCK_UNLOCKED;
+
+#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_print(void){
+ HashTable_for_decl(entry);
+ Vif *vif;
+ unsigned long flags;
+ char vnetbuf[VNET_ID_BUF];
+
+ vif_read_lock(flags);
+ HashTable_for_each(entry, vif_table){
+ vif = entry->value;
+ printk(KERN_INFO "VIF(vnet=%s vmac=" MACFMT ")\n",
+ VnetId_ntoa(&vif->vnet, vnetbuf), MAC6TUPLE(vif->vmac.mac));
+ }
+ vif_read_unlock(flags);
+}
void vif_decref(Vif *vif){
if(!vif) return;
@@ -71,18 +96,11 @@
*/
Hashcode vif_key_hash_fn(void *k){
VifKey *key = k;
- Hashcode h;
- h = hash_2ul(key->vnet,
- (key->vmac.mac[0] << 24) |
- (key->vmac.mac[1] << 16) |
- (key->vmac.mac[2] << 8) |
- (key->vmac.mac[3] ));
- h = hash_hul(h,
- (key->vmac.mac[4] << 8) |
- (key->vmac.mac[5] ));
+ Hashcode h = 0;
+ h = VnetId_hash(h, &key->vnet);
+ h = Vmac_hash(h, &key->vmac);
return h;
}
-
/** Test equality for keys in the vif table.
* Compares vnet and mac.
@@ -94,7 +112,8 @@
int vif_key_equal_fn(void *k1, void *k2){
VifKey *key1 = k1;
VifKey *key2 = k2;
- return (key1->vnet == key2->vnet) && (memcmp(key1->vmac.mac,
key2->vmac.mac, ETH_ALEN) == 0);
+ return (VnetId_eq(&key1->vnet , &key2->vnet) &&
+ Vmac_eq(&key1->vmac, &key2->vmac));
}
/** Free an entry in the vif table.
@@ -118,13 +137,13 @@
* @param mac MAC address
* @return 0 on success, -ENOENT otherwise
*/
-int vif_lookup(int vnet, Vmac *vmac, Vif **vif){
- int err = 0;
- VifKey key = {};
+int vif_lookup(VnetId *vnet, Vmac *vmac, Vif **vif){
+ int err = 0;
+ VifKey key = { .vnet = *vnet, .vmac = *vmac };
HTEntry *entry = NULL;
+ unsigned long flags;
- key.vnet = vnet;
- key.vmac = *vmac;
+ vif_read_lock(flags);
entry = HashTable_get_entry(vif_table, &key);
if(entry){
*vif = entry->value;
@@ -133,7 +152,7 @@
*vif = NULL;
err = -ENOENT;
}
- //dprintf("< err=%d addr=" IPFMT "\n", err, NIPQUAD(*coaddr));
+ vif_read_unlock(flags);
return err;
}
@@ -143,10 +162,12 @@
* @param mac MAC address
* @return 0 on success, negative error code otherwise
*/
-int vif_add(int vnet, Vmac *vmac, Vif **val){
+int vif_add(VnetId *vnet, Vmac *vmac, Vif **val){
int err = 0;
Vif *vif = NULL;
HTEntry *entry;
+ unsigned long flags;
+
dprintf("> vnet=%d\n", vnet);
vif = ALLOCATE(Vif);
if(!vif){
@@ -154,9 +175,11 @@
goto exit;
}
atomic_set(&vif->refcount, 1);
- vif->vnet = vnet;
+ vif->vnet = *vnet;
vif->vmac = *vmac;
+ vif_write_lock(flags);
entry = HashTable_add(vif_table, vif, vif);
+ vif_write_unlock(flags);
if(!entry){
err = -ENOMEM;
deallocate(vif);
@@ -177,22 +200,14 @@
* @param coaddr return parameter for care-of address
* @return number of entries deleted, or negative error code
*/
-int vif_remove(int vnet, Vmac *vmac){
- int err = 0;
- VifKey key = { .vnet = vnet, .vmac = *vmac };
- //dprintf("> vnet=%d addr=%u.%u.%u.%u\n", vnet, NIPQUAD(coaddr));
+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);
- //dprintf("< err=%d\n", err);
- return err;
-}
-
-int vif_find(int vnet, Vmac *vmac, int create, Vif **vif){
- int err = 0;
-
- err = vif_lookup(vnet, vmac, vif);
- if(err && create){
- err = vif_add(vnet, vmac, vif);
- }
+ vif_write_unlock(flags);
return err;
}
@@ -200,15 +215,15 @@
HashTable_clear(vif_table);
}
-int vif_create(int vnet, Vmac *vmac, Vif **vif){
+int vif_create(VnetId *vnet, Vmac *vmac, Vif **vif){
int err = 0;
dprintf(">\n");
- if(!vif_lookup(vnet, vmac, vif)){
+ if(vif_lookup(vnet, vmac, vif) == 0){
+ vif_decref(*vif);
err = -EEXIST;
goto exit;
}
- dprintf("> vif_add...\n");
err = vif_add(vnet, vmac, vif);
exit:
if(err){
@@ -218,25 +233,6 @@
return err;
}
-/** Create a vif.
- *
- * @param vnet vnet id
- * @param mac mac address (as a string)
- * @return 0 on success, error code otherwise
- */
-int mkvif(int vnet, char *mac){
- int err = 0;
- Vmac vmac = {};
- Vif *vif = NULL;
- dprintf("> vnet=%d mac=%s\n", vnet, mac);
- err = mac_aton(mac, vmac.mac);
- if(err) goto exit;
- err = vif_create(vnet, &vmac, &vif);
- exit:
- dprintf("< err=%d\n", err);
- return err;
-}
-
/** Initialize the vif table.
*
* @return 0 on success, error code otherwise
@@ -250,12 +246,9 @@
goto exit;
}
vif_table->entry_free_fn = vif_entry_free_fn;
- vif_table->key_hash_fn = vif_key_hash_fn;
- vif_table->key_equal_fn = vif_key_equal_fn;
-
- // Some vifs for testing.
- //mkvif(1, "aa:00:00:00:20:11");
- //mkvif(2, "aa:00:00:00:20:12");
+ vif_table->key_hash_fn = vif_key_hash_fn;
+ vif_table->key_equal_fn = vif_key_equal_fn;
+
exit:
if(err < 0) wprintf("< err=%d\n", err);
dprintf("< err=%d\n", err);
diff -r 9fb0bad776dd tools/vnet/vnet-module/vif.h
--- a/tools/vnet/vnet-module/vif.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/vif.h Fri Aug 26 09:04:02 2005
@@ -24,12 +24,12 @@
/** Key for entries in the vif table. */
typedef struct VifKey {
- int vnet;
+ VnetId vnet;
Vmac vmac;
} VifKey;
typedef struct Vif {
- int vnet;
+ VnetId vnet;
Vmac vmac;
struct net_device *dev;
atomic_t refcount;
@@ -38,15 +38,17 @@
struct HashTable;
extern struct HashTable *vif_table;
+extern void vif_print(void);
+
extern void vif_decref(Vif *vif);
extern void vif_incref(Vif *vif);
-extern int vif_create(int vnet, Vmac *vmac, Vif **vif);
+extern int vif_create(struct VnetId *vnet, Vmac *vmac, Vif **vif);
-extern int vif_add(int vnet, Vmac *vmac, Vif **vif);
-extern int vif_lookup(int vnet, Vmac *vmac, Vif **vif);
-extern int vif_remove(int vnet, Vmac *vmac);
-extern int vif_find(int vnet, Vmac *vmac, int create, Vif **vif);
+extern int vif_create(VnetId *vnet, Vmac *vmac, Vif **vif);
+extern int vif_add(struct VnetId *vnet, Vmac *vmac, Vif **vif);
+extern int vif_lookup(struct VnetId *vnet, Vmac *vmac, Vif **vif);
+extern int vif_remove(struct VnetId *vnet, Vmac *vmac);
extern void vif_purge(void);
extern int vif_init(void);
diff -r 9fb0bad776dd tools/vnet/vnet-module/vnet.c
--- a/tools/vnet/vnet-module/vnet.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/vnet.c Fri Aug 26 09:04:02 2005
@@ -47,6 +47,7 @@
#include <random.h>
#include <tunnel.h>
+#include <skb_util.h>
#include <vnet_dev.h>
#include <vnet.h>
#include <vif.h>
@@ -70,7 +71,7 @@
/** Key for entries in the vnet address table. */
typedef struct VnetAddrKey {
/** Vnet id. */
- int vnet;
+ VnetId vnet;
/** MAC address. */
unsigned char mac[ETH_ALEN];
} VnetAddrKey;
@@ -88,7 +89,6 @@
void Vnet_decref(Vnet *info){
if(!info) return;
if(atomic_dec_and_test(&info->refcount)){
- dprintf("> free vnet=%u\n", info->vnet);
vnet_dev_remove(info);
deallocate(info);
}
@@ -101,6 +101,28 @@
void Vnet_incref(Vnet *info){
if(!info) return;
atomic_inc(&info->refcount);
+}
+
+void Vnet_print(Vnet *info)
+{
+ char vnetbuf[VNET_ID_BUF];
+
+ printk(KERN_INFO "VNET(vnet=%s device=%s security=%c%c)\n",
+ VnetId_ntoa(&info->vnet, vnetbuf),
+ info->device,
+ ((info->security & SA_AUTH) ? 'a' : '-'),
+ ((info->security & SA_CONF) ? 'c' : '-'));
+}
+
+void vnet_print(void)
+{
+ HashTable_for_decl(entry);
+ Vnet *info;
+
+ HashTable_for_each(entry, vnet_table){
+ info = entry->value;
+ Vnet_print(info);
+ }
}
/** Allocate a vnet, setting reference count to 1.
@@ -129,7 +151,7 @@
HTEntry *entry = NULL;
// Vnet_del(info->vnet); //todo: Delete existing vnet info?
Vnet_incref(info);
- entry = HashTable_add(vnet_table, HKEY(info->vnet), info);
+ entry = HashTable_add(vnet_table, &info->vnet, info);
if(!entry){
err = -ENOMEM;
Vnet_decref(info);
@@ -142,8 +164,8 @@
* @param vnet id of vnet to remove
* @return number of vnets removed
*/
-int Vnet_del(vnetid_t vnet){
- return HashTable_remove(vnet_table, HKEY(vnet));
+int Vnet_del(VnetId *vnet){
+ return HashTable_remove(vnet_table, vnet);
}
/** Lookup a vnet by id.
@@ -153,17 +175,14 @@
* @param info return parameter for vnet
* @return 0 on sucess, -ENOENT if no vnet found
*/
-int Vnet_lookup(vnetid_t vnet, Vnet **info){
- int err = 0;
- dprintf("> vnet=%u info=%p\n", vnet, info);
- dprintf("> vnet_table=%p\n",vnet_table);
- *info = HashTable_get(vnet_table, HKEY(vnet));
+int Vnet_lookup(VnetId *vnet, Vnet **info){
+ int err = 0;
+ *info = HashTable_get(vnet_table, vnet);
if(*info){
Vnet_incref(*info);
} else {
err = -ENOENT;
}
- dprintf("< err=%d\n", err);
return err;
}
@@ -191,22 +210,33 @@
*/
static int vnet_setup(void){
int err = 0;
- int i, n = 5; //20;
+ int i, n = 3;
int security = vnet_security_default;
+ uint32_t vnetid;
Vnet *vnet;
- dprintf(">\n");
for(i=0; i<n; i++){
err = Vnet_alloc(&vnet);
if(err) break;
- vnet->vnet = VNET_VIF + i;
- vnet->security = (vnet->vnet > 10 ? security : 0);
- //err = Vnet_add(vnet);
+ vnetid = VNET_VIF + i;
+ vnet->vnet = toVnetId(vnetid);
+ sprintf(vnet->device, "vnif%04x", vnetid);
+ vnet->security = (vnetid > 10 ? security : 0);
err = Vnet_create(vnet);
if(err) break;
}
- dprintf("< err=%d\n", err);
- return err;
+ return err;
+}
+
+int vnet_key_equal_fn(void *k1, void *k2){
+ VnetId *key1 = k1;
+ VnetId *key2 = k2;
+ return VnetId_eq(key1, key2);
+}
+
+Hashcode vnet_key_hash_fn(void *k){
+ VnetId *key = k;
+ return VnetId_hash(0, key);
}
/** Initialize the vnet table and the physical vnet.
@@ -216,18 +246,18 @@
int vnet_init(void){
int err = 0;
- dprintf(">\n");
vnet_table = HashTable_new(0);
- dprintf("> vnet_table=%p\n", vnet_table);
if(!vnet_table){
err = -ENOMEM;
goto exit;
}
+ 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 = VNET_PHYS;
+ vnet_physical->vnet = toVnetId(VNET_PHYS);
vnet_physical->security = 0;
err = Vnet_add(vnet_physical);
if(err) goto exit;
@@ -237,7 +267,6 @@
if(err) goto exit;
err = vif_init();
exit:
- if(err < 0) wprintf("< err=%d\n", err);
return err;
}
@@ -248,50 +277,28 @@
vnet_table = NULL;
}
-#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 = {
- .oif = skb->dev->ifindex,
- .nl_u = {
- .ip4_u = {
- .daddr = skb->nh.iph->daddr,
- .saddr = skb->nh.iph->saddr,
- .tos = skb->nh.iph->tos,
- }
- }
- };
-
- 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;
- key.oif = skb->dev->ifindex;
- err = ip_route_output_key(prt, &key);
- return err;
-}
-
-#endif
-
inline int skb_xmit(struct sk_buff *skb){
int err = 0;
struct rtable *rt = NULL;
- dprintf("> skb=%p dev=%s\n", skb, skb->dev->name);
-
+ dprintf(">\n");
skb->protocol = htons(ETH_P_IP);
err = skb_route(skb, &rt);
- if(err) goto exit;
+ 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;
+ }
skb->dst = &rt->u.dst;
+ if(!skb->dev){
+ skb->dev = rt->u.dst.dev;
+ }
ip_select_ident(skb->nh.iph, &rt->u.dst, NULL);
@@ -317,39 +324,27 @@
*
* @todo fixme
*/
-int vnet_skb_send(struct sk_buff *skb, u32 vnet){
- int err = 0;
- Vif *vif = NULL;
-
- dprintf("> skb=%p vnet=%u\n", skb, vnet);
- if(vnet == VNET_PHYS || !vnet){
- // For completeness, send direct to the network.
- if(skb->dev){
- err = skb_xmit(skb);
- } else {
- // Can't assume eth0 - might be nbe-br or other. Need to route.
- struct net_device *dev = NULL;
- err = vnet_get_device(DEVICE, &dev);
- if(err) goto exit;
- skb->dev = dev;
- err = skb_xmit(skb);
- dev_put(dev);
- }
+int vnet_skb_send(struct sk_buff *skb, VnetId *vnet){
+ int err = 0;
+ VnetId vnet_phys = toVnetId(VNET_PHYS);
+
+ 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 {
- dprintf("> varp_output\n");
err = varp_output(skb, vnet);
}
- //dprintf("< err=%d\n", err);
- exit:
- if(vif) vif_decref(vif);
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.
* If the dest is broadcast, goes to all vifs on the vnet.
- * If the dest is unicast, goes to addressed vif on vnet.
- * For each vif we set the packet dev and receive the packet.
+ * If the dest is unicast, goes to the addressed vif on the vnet.
*
* The packet must have skb->mac.raw set and skb->data must point
* after the device (ethernet) header.
@@ -359,139 +354,19 @@
* @param vmac packet vmac
* @return 0 on success, error code otherwise
*/
-#if 1
-int vnet_skb_recv(struct sk_buff *skb, u32 vnet, Vmac *vmac){
- // Receive the 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.
+int vnet_skb_recv(struct sk_buff *skb, VnetId *vnet, Vmac *vmac){
int err = 0;
Vnet *info = NULL;
- dprintf("> vnet=%u mac=%s\n", vnet, mac_ntoa(vmac->mac));
err = Vnet_lookup(vnet, &info);
if(err) goto exit;
skb->dev = info->dev;
- dprintf("> netif_rx dev=%s\n", skb->dev->name);
netif_rx(skb);
exit:
if(info) Vnet_decref(info);
if(err){
- kfree_skb(skb);
- }
- dprintf("< err=%d\n", err);
- return err;
-}
-
-#else
-int vnet_skb_recv(struct sk_buff *skb, u32 vnet, Vmac *vmac){
- int err = 0;
- Vif *vif = NULL;
-
- dprintf("> vnet=%u mac=%s\n", vnet, mac_ntoa(vmac->mac));
- if(mac_is_multicast(vmac->mac)){
- HashTable_for_decl(entry);
- int count = 0;
- struct sk_buff *new_skb;
-
- HashTable_for_each(entry, vif_table){
- vif = entry->value;
- if(vif->vnet != vnet) continue;
- count++;
- new_skb = skb_copy(skb, GFP_ATOMIC);
- if(!new_skb) break;
- new_skb->dev = vif->dev;
- dprintf("> %d] netif_rx dev=%s\n", count, new_skb->dev->name);
- netif_rx(new_skb);
- }
kfree_skb(skb);
- } else {
- err = vif_lookup(vnet, vmac, &vif);
- if(err){
- kfree_skb(skb);
- goto exit;
- }
- skb->dev = vif->dev;
- dprintf("> netif_rx dev=%s\n", skb->dev->name);
- netif_rx(skb);
- }
- exit:
- dprintf("< err=%d\n", err);
- return err;
-}
-#endif
-
-/** Check validity of an incoming IP frame.
- *
- * @param skb frame
- * @return 0 if ok, error code otherwise
- *
- * @todo fixme Can prob skip most of this because linux will have done it.
- * @todo Only need the vnet skb context check.
- */
-int check_ip_frame(struct sk_buff *skb){
- int err = -EINVAL;
- struct iphdr* iph;
- struct net_device *dev;
- __u32 len;
- __u16 check;
-
-#if 0
- if(skb->context){
- // Todo: After ESP want to skip most checks (including checksum),
- // Todo: but in general may not want to skip all checks on detunnel.
- //dprintf("> Skip check, has context\n");
- err = 0;
- goto exit;
- }
-#endif
- // Check we have enough for an ip header - the skb passed should
- // have data pointing at the eth header and skb->len should include
- // that. skb->nh should already have been set. Let the indvidual
- // protocol handlers worry about the exact ip header len
- // (i.e. whether any ip options are set).
- dev = skb->dev;
-
- if(skb->len < ETH_HLEN + sizeof(struct iphdr)){
- wprintf("> packet too short for ip header\n");
- goto exit;
- }
-
- iph = skb->nh.iph;
- /*
- * RFC1122: 3.1.2.2 MUST silently discard any IP frame that fails the
checksum.
- *
- * Is the datagram acceptable?
- *
- * 1. Length at least the size of an ip header
- * 2. Version of 4
- * 3. Checksums correctly. [Speed optimisation for later, skip
loopback checksums]
- * 4. Doesn't have a bogus length
- */
- if (iph->ihl < 5 || iph->version != 4){
- wprintf("> len and version check failed\n");
- goto exit;
- }
- if(skb->len < ETH_HLEN + (iph->ihl << 2)){
- wprintf("> packet too short for given ihl\n");
- goto exit;
- }
-
- check = iph->check;
- //iph->check = 0;
- //iph->check = compute_cksum((__u16 *)iph, (iph->ihl << 1));
- if(iph->check != check){
- wprintf("> invalid checksum\n");
- goto exit;
- }
-
- len = ntohs(iph->tot_len);
- if (skb->len < len + ETH_HLEN || len < (iph->ihl << 2)){
- wprintf("> packet too short for tot_len\n");
- goto exit;
- }
- skb->h.raw = skb->nh.raw + (iph->ihl << 2);
- err = 0;
- exit:
+ }
return err;
}
@@ -539,14 +414,13 @@
*
* @todo Need to check that the sa provides the correct security level.
*/
-int vnet_check_context(int vnet, SkbContext *context, Vnet **val){
+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){
- wprintf("> No vnet %d\n", vnet);
goto exit;
}
if(!info->security) goto exit;
@@ -556,7 +430,8 @@
goto exit;
}
if(context->protocol != IPPROTO_ESP){
- wprintf("> Invalid protocol: wanted %d, got %d\n", IPPROTO_ESP,
context->protocol);
+ wprintf("> Invalid protocol: wanted %d, got %d\n",
+ IPPROTO_ESP, context->protocol);
goto exit;
}
sa = context->data;
@@ -586,13 +461,11 @@
*/
static void sa_tunnel_close(Tunnel *tunnel){
SAState *sa;
- dprintf(">\n");
if(!tunnel) return;
sa = tunnel->data;
if(!sa) return;
SAState_decref(sa);
tunnel->data = NULL;
- dprintf("<\n");
}
/** Packet send function for SA tunnels.
@@ -604,7 +477,6 @@
static int sa_tunnel_send(Tunnel *tunnel, struct sk_buff *skb){
int err = -EINVAL;
SAState *sa;
- //dprintf("> tunnel=%p\n", tunnel);
if(!tunnel){
wprintf("> Null tunnel!\n");
goto exit;
@@ -616,7 +488,6 @@
}
err = SAState_send(sa, skb, tunnel->base);
exit:
- //dprintf("< err=%d\n", err);
return err;
}
@@ -638,7 +509,7 @@
* @param tunnel return parameter
* @return 0 on success, error code otherwise
*/
-int vnet_tunnel_open(u32 vnet, u32 addr, Tunnel **tunnel){
+int vnet_tunnel_open(VnetId *vnet, VarpAddr *addr, Tunnel **tunnel){
extern TunnelType *etherip_tunnel_type;
int err = 0;
Vnet *info = NULL;
@@ -646,20 +517,17 @@
Tunnel *sa_tunnel = NULL;
Tunnel *etherip_tunnel = NULL;
- dprintf("> vnet=%u addr=" IPFMT "\n", vnet, NIPQUAD(addr));
err = Vnet_lookup(vnet, &info);
- dprintf("> Vnet_lookup=%d\n", err);
if(err) goto exit;
if(info->security){
SAState *sa = NULL;
- dprintf("> security=%d\n", info->security);
+ //FIXME: Assuming IPv4 for now.
+ u32 ipaddr = addr->u.ip4.s_addr;
err = Tunnel_create(sa_tunnel_type, vnet, addr, base_tunnel,
&sa_tunnel);
if(err) goto exit;
- dprintf("> sa_tunnel=%p\n", sa_tunnel);
- err = sa_create(info->security, 0, IPPROTO_ESP, addr, &sa);
+ err = sa_create(info->security, 0, IPPROTO_ESP, ipaddr, &sa);
if(err) goto exit;
sa_tunnel->data = sa;
- dprintf("> sa=%p\n", sa);
base_tunnel = sa_tunnel;
}
err = Tunnel_create(etherip_tunnel_type, vnet, addr, base_tunnel,
ðerip_tunnel);
@@ -673,7 +541,6 @@
} else {
*tunnel = etherip_tunnel;
}
- dprintf("< err=%d\n", err);
return err;
}
@@ -685,14 +552,12 @@
* @param tunnel return parameter
* @return 0 on success, error code otherwise
*/
-int vnet_tunnel_lookup(u32 vnet, u32 addr, Tunnel **tunnel){
- int err = 0;
- dprintf("> vnet=%d addr=" IPFMT "\n", vnet, NIPQUAD(addr));
+int vnet_tunnel_lookup(VnetId *vnet, VarpAddr *addr, Tunnel **tunnel){
+ int err = 0;
*tunnel = Tunnel_lookup(vnet, addr);
if(!*tunnel){
err = vnet_tunnel_open(vnet, addr, tunnel);
}
- dprintf("< err=%d\n", err);
return err;
}
@@ -703,16 +568,14 @@
* @param skb packet
* @return 0 on success, error code otherwise
*/
-int vnet_tunnel_send(vnetid_t vnet, vnetaddr_t addr, struct sk_buff *skb){
+int vnet_tunnel_send(VnetId *vnet, VarpAddr *addr, struct sk_buff *skb){
int err = 0;
Tunnel *tunnel = NULL;
- dprintf("> vnet=%u addr=" IPFMT "\n", vnet, NIPQUAD(addr));
err = vnet_tunnel_lookup(vnet, addr, &tunnel);
if(err) goto exit;
err = Tunnel_send(tunnel, skb);
Tunnel_decref(tunnel);
exit:
- dprintf("< err=%d\n", err);
return err;
}
@@ -722,7 +585,7 @@
vnet_exit();
esp_module_exit();
etherip_module_exit();
- tunnel_module_init();
+ tunnel_module_exit();
random_module_exit();
}
@@ -753,12 +616,13 @@
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();
- }
- if(err < 0) wprintf("< err=%d\n", err);
+ wprintf("< err=%d\n", err);
+ }
return err;
}
diff -r 9fb0bad776dd tools/vnet/vnet-module/vnet.h
--- a/tools/vnet/vnet-module/vnet.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/vnet.h Fri Aug 26 09:04:02 2005
@@ -29,17 +29,15 @@
struct Vif;
struct net_device;
-typedef uint32_t vnetid_t;
-typedef uint32_t vnetaddr_t;
-
/** Vnet property record. */
typedef struct Vnet {
/** Reference count. */
atomic_t refcount;
/** Vnet id. */
- vnetid_t vnet;
+ struct VnetId vnet;
/** Security flag. If true the vnet requires ESP. */
int security;
+ char device[IFNAMSIZ];
struct net_device *dev;
struct net_device *bridge;
@@ -51,30 +49,28 @@
int recursion;
} Vnet;
-extern int Vnet_lookup(vnetid_t id, Vnet **vnet);
-extern int Vnet_add(Vnet *vnet);
-extern int Vnet_del(vnetid_t vnet);
-extern void Vnet_incref(Vnet *);
-extern void Vnet_decref(Vnet *);
-extern int Vnet_alloc(Vnet **vnet);
+extern void vnet_print(void);
+extern void Vnet_print(Vnet *info);
+
+extern int Vnet_lookup(struct VnetId *vnet, 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 Vnet *vnet_physical;
extern int skb_xmit(struct sk_buff *skb);
-extern int vnet_skb_send(struct sk_buff *skb, u32 vnet);
-extern int vnet_skb_recv(struct sk_buff *skb, u32 vnet, struct Vmac *vmac);
+extern int vnet_skb_send(struct sk_buff *skb, struct VnetId *vnet);
+extern int vnet_skb_recv(struct sk_buff *skb, struct VnetId *vnet, struct Vmac
*vmac);
-extern int vnet_check_context(int vnet, SkbContext *context, Vnet **vinfo);
+extern int vnet_check_context(struct VnetId *vnet, SkbContext *context, Vnet
**vinfo);
-extern int vnet_tunnel_open(vnetid_t vnet, vnetaddr_t addr, Tunnel **tunnel);
-extern int vnet_tunnel_lookup(vnetid_t vnet, vnetaddr_t addr, Tunnel **tunnel);
-extern int vnet_tunnel_send(vnetid_t vnet, vnetaddr_t addr, struct sk_buff
*skb);
+extern int vnet_tunnel_open(struct VnetId *vnet, struct VarpAddr *addr, Tunnel
**tunnel);
+extern int vnet_tunnel_lookup(struct VnetId *vnet, struct VarpAddr *addr,
Tunnel **tunnel);
+extern int vnet_tunnel_send(struct VnetId *vnet, struct VarpAddr *addr, struct
sk_buff *skb);
extern int vnet_init(void);
-
-enum {
- HANDLE_OK = 1,
- HANDLE_NO = 0,
-};
extern int vnet_sa_security(u32 spi, int protocol, u32 addr);
struct SAState;
diff -r 9fb0bad776dd tools/vnet/vnet-module/vnet_dev.c
--- a/tools/vnet/vnet-module/vnet_dev.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/vnet_dev.c Fri Aug 26 09:04:02 2005
@@ -48,15 +48,9 @@
#undef DEBUG
#include "debug.h"
-#define VNETIF_FMT "vnetif%u"
-#define VNETBR_FMT "vnet%u"
-
#ifndef CONFIG_BRIDGE
#error Must configure ethernet bridging in Network Options
#endif
-
-#include <linux/../../net/bridge/br_private.h>
-#define dev_bridge(_dev) ((struct net_bridge *)(_dev)->priv)
static void vnet_dev_destructor(struct net_device *dev){
dprintf(">\n");
@@ -113,135 +107,16 @@
Vnet *vnet = (void*)dev->priv;
dprintf(">\n");
- dprintf("> vnet=%d\n", vnet->vnet);
- snprintf(dev->name, IFNAMSIZ - 1, VNETIF_FMT, vnet->vnet);
- if(__dev_get_by_name(dev->name)){
+ if(__dev_get_by_name(vnet->device)){
err = -ENOMEM;
- }
+ wprintf("> vnet device name in use: %s\n", vnet->device);
+ }
+ strcpy(dev->name, vnet->device);
dprintf("< err=%d\n", err);
return err;
}
-//============================================================================
-#ifdef CONFIG_VNET_BRIDGE
-
-#define BRIDGE DEVICE
-
-void vnet_bridge_fini(Vnet *vnet){
- if(!vnet) return;
- if(vnet->bridge){
- br_del_bridge(vnet->bridge->name);
- vnet->bridge = NULL;
- }
-}
-
-/** Create the bridge for a vnet, and add the
- * vnet interface to it.
- *
- * @param vnet vnet
- * @return 0 on success, error code otherwise
- */
-int vnet_bridge_init(Vnet *vnet){
- int err = 0;
- char bridge[IFNAMSIZ] = {};
- struct net_bridge *br;
- vnet->bridge = NULL;
- snprintf(bridge, IFNAMSIZ - 1, VNETBR_FMT, vnet->vnet);
- rtnl_lock();
- err = br_add_bridge(bridge);
- rtnl_unlock();
- if(err){
- dprintf("> Error creating vnet bridge %s: err=%d\n", bridge, err);
- goto exit;
- }
- vnet->bridge = __dev_get_by_name(bridge);
- if(!vnet->bridge){
- wprintf("> Vnet bridge %s is null!\n", bridge);
- err = -EINVAL;
- goto exit;
- }
- br = dev_bridge(vnet->bridge);
- br->stp_enabled = 0;
- br->bridge_hello_time = 0;
- br->hello_time = 0;
- br->bridge_forward_delay = 0;
- br->forward_delay = 0;
- rtnl_lock();
- err = br_add_if(br, vnet->dev);
- rtnl_unlock();
- if(err){
- dprintf("> Error adding vif %s to vnet bridge %s: err=%d\n",
- vnet->dev->name, bridge, err);
- goto exit;
- }
- rtnl_lock();
- dev_open(vnet->dev);
- dev_open(vnet->bridge);
- rtnl_unlock();
- exit:
- if(err){
- if(vnet->bridge){
- rtnl_lock();
- br_del_bridge(bridge);
- rtnl_unlock();
- vnet->bridge = NULL;
- }
- }
- return err;
-}
-
-
-/** Add an interface to the bridge for a vnet.
- *
- * @param vnet vnet
- * @param dev interface
- * @return 0 on success, error code otherwise
- */
-int vnet_add_if(Vnet *vnet, struct net_device *dev){
- int err = 0;
- struct net_device *brdev;
-
- dprintf(">\n");
- if(!vnet->bridge){
- err = -EINVAL;
- goto exit;
- }
- // Delete the interface from the default bridge.
- // todo: Really want to delete it from any bridge it's in.
- if(!vnet_get_device(BRIDGE, &brdev)){
- rtnl_lock();
- br_del_if(dev_bridge(brdev), dev);
- rtnl_unlock();
- }
- dprintf("> br_add_if %s %s\n", vnet->bridge->name, dev->name);
- rtnl_lock();
- dev_open(dev);
- dev_open(vnet->bridge);
- err = br_add_if(dev_bridge(vnet->bridge), dev);
- rtnl_unlock();
- exit:
- dprintf("< err=%d\n", err);
- return err;
-}
-
-int vnet_del_if(Vnet *vnet, struct net_device *dev){
- int err = 0;
-
- dprintf(">\n");
- if(!vnet->bridge){
- err = -EINVAL;
- goto exit;
- }
- rtnl_lock();
- br_del_if(dev_bridge(vnet->bridge), dev);
- rtnl_unlock();
- exit:
- dprintf("< err=%d\n", err);
- return err;
-}
-
-
-/** Create the bridge and virtual interface for a vnet.
+/** Create the virtual interface for a vnet.
*
* @param info vnet
* @return 0 on success, error code otherwise
@@ -249,25 +124,13 @@
int Vnet_create(Vnet *info){
int err = 0;
- dprintf("> %u\n", info->vnet);
err = vnet_dev_add(info);
if(err) goto exit;
- dprintf("> vnet_bridge_init\n");
- err = vnet_bridge_init(info);
- if(err) goto exit;
- dprintf("> Vnet_add...\n");
err = Vnet_add(info);
exit:
- if(err){
- dprintf("> vnet_bridge_fini...\n");
- vnet_bridge_fini(info);
- }
- dprintf("< err=%d\n", err);
return err;
}
-
-
/** Remove the net device for a vnet.
* Clears the dev field of the vnet.
* Safe to call if the vnet or its dev are null.
@@ -276,75 +139,13 @@
*/
void vnet_dev_remove(Vnet *vnet){
if(!vnet) return;
- dprintf("> vnet=%u\n", vnet->vnet);
- if(vnet->bridge){
- dprintf("> br_del_bridge(%s)\n", vnet->bridge->name);
- rtnl_lock();
- br_del_bridge(vnet->bridge->name);
- rtnl_unlock();
- vnet->bridge = NULL;
- }
if(vnet->dev){
//dev_put(vnet->dev);
dprintf("> unregister_netdev(%s)\n", vnet->dev->name);
unregister_netdev(vnet->dev);
vnet->dev = NULL;
}
- dprintf("<\n");
-}
-
-//============================================================================
-#else
-//============================================================================
-
-/** 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;
-
- dprintf("> %u\n", info->vnet);
- err = vnet_dev_add(info);
- if(err) goto exit;
- dprintf("> Vnet_add...\n");
- err = Vnet_add(info);
- exit:
- dprintf("< err=%d\n", err);
- return err;
-}
-
-int vnet_add_if(Vnet *vnet, struct net_device *dev){
- int err = -ENOSYS;
- return err;
-}
-
-
-int vnet_del_if(Vnet *vnet, struct net_device *dev){
- int err = 0;
- return err;
-}
-
-/** Remove the net device for a vnet.
- * Clears the dev field of the vnet.
- * Safe to call if the vnet or its dev are null.
- *
- * @param vnet vnet
- */
-void vnet_dev_remove(Vnet *vnet){
- if(!vnet) return;
- dprintf("> vnet=%u\n", vnet->vnet);
- if(vnet->dev){
- //dev_put(vnet->dev);
- dprintf("> unregister_netdev(%s)\n", vnet->dev->name);
- unregister_netdev(vnet->dev);
- vnet->dev = NULL;
- }
- dprintf("<\n");
-}
-#endif
-//============================================================================
+}
static int vnet_dev_open(struct net_device *dev){
int err = 0;
@@ -365,6 +166,7 @@
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;
dprintf("> skb=%p\n", skb);
if(vnet->recursion++) {
@@ -385,12 +187,14 @@
skb->mac.raw = skb->data;
}
//dev->trans_start = jiffies;
- err = vnet_skb_send(skb, vnet->vnet);
+ 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 += skb->len;
+ vnet->stats.tx_bytes += len;
}
exit:
vnet->recursion--;
@@ -416,43 +220,48 @@
struct net_device *dev, unsigned short type,
void *daddr, void *saddr, unsigned len){
int err = 0;
- dprintf("> skb=%p ethhdr=%p dev=%s len=%u\n",
- skb, skb->mac.raw, dev->name, len);
- if(saddr){
- dprintf("> saddr=" MACFMT "\n", MAC6TUPLE((unsigned char*)saddr));
- } else {
- dprintf("> saddr=NULL\n");
- }
- if(daddr){
- dprintf("> daddr=" MACFMT "\n", MAC6TUPLE((unsigned char*)daddr));
- } else {
- dprintf("> daddr=NULL\n");
- }
+
err = eth_hard_header(skb, dev, type, daddr, saddr, len);
- dprintf("> eth_hard_header=%d\n", err);
+ if(err) goto exit;
skb->mac.raw = skb->data;
- dprintf("> src=" MACFMT " dst=" MACFMT "\n",
- MAC6TUPLE(skb->mac.ethernet->h_source),
- MAC6TUPLE(skb->mac.ethernet->h_dest));
- dprintf("< err=%d\n", err);
+ exit:
+ return err;
+}
+
+void vnet_default_mac(unsigned char *mac)
+{
+ static unsigned val = 1;
+ mac[0] = 0xAA;
+ mac[1] = 0xFF;
+ mac[2] = (unsigned char)((val >> 24) & 0xff);
+ mac[3] = (unsigned char)((val >> 16) & 0xff);
+ mac[4] = (unsigned char)((val >> 8) & 0xff);
+ mac[5] = (unsigned char)((val ) & 0xff);
+ val++;
+}
+
+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){
- static unsigned val = 1;
- struct net_device *dev;
-
- if(vnet_get_device(DEVICE, &dev)){
- mac[0] = 0xAA;
- mac[1] = 0xFF;
- mac[2] = (unsigned char)((val >> 24) & 0xff);
- mac[3] = (unsigned char)((val >> 16) & 0xff);
- mac[4] = (unsigned char)((val >> 8) & 0xff);
- mac[5] = (unsigned char)((val ) & 0xff);
- val++;
- } else {
- memcpy(mac, dev->dev_addr, ETH_ALEN);
- dev_put(dev);
+ const char *devices[] = { "eth0", "eth1", "eth2", NULL };
+ const char **pdev;
+ int err = -ENODEV;
+
+ for(pdev = devices; err && *pdev; pdev++){
+ err = vnet_device_mac(*pdev, mac);
+ }
+ if(err){
+ vnet_default_mac(mac);
}
}
@@ -463,7 +272,9 @@
dprintf(">\n");
ether_setup(dev);
- if(!eth_hard_header) eth_hard_header = dev->hard_header;
+ if(!eth_hard_header){
+ eth_hard_header = dev->hard_header;
+ }
dev->hard_header = vnet_dev_hard_header;
dev->open = vnet_dev_open;
@@ -507,7 +318,10 @@
if(vnet->dev) goto exit;
vnet->header_n = sizeof(struct iphdr) + sizeof(struct etheriphdr);
dev = kmalloc(sizeof(struct net_device), GFP_ATOMIC);
- if(!dev){ err = -ENOMEM; goto exit; }
+ if(!dev){
+ err = -ENOMEM;
+ goto exit;
+ }
*dev = (struct net_device){};
dev->priv = vnet;
vnet->dev = dev;
@@ -515,9 +329,10 @@
err = vnet_dev_set_name(dev);
if(err) goto exit;
vnet_dev_init(dev);
- dprintf("> name=%s, register_netdev...\n", dev->name);
err = register_netdev(dev);
- dprintf("> register_netdev=%d\n", err);
+ if(err){
+ wprintf("> register_netdev(%s) = %d\n", dev->name, err);
+ }
if(err) goto exit;
rtnl_lock();
dev_open(dev);
diff -r 9fb0bad776dd tools/vnet/vnet-module/vnet_dev.h
--- a/tools/vnet/vnet-module/vnet_dev.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/vnet_dev.h Fri Aug 26 09:04:02 2005
@@ -20,12 +20,9 @@
#define _VNET_VNET_DEV_H_
struct Vnet;
-struct net_device;
extern int vnet_dev_add(struct Vnet *vnet);
extern void vnet_dev_remove(struct Vnet *vnet);
extern int Vnet_create(struct Vnet *info);
-extern int vnet_add_if(struct Vnet *vnet, struct net_device *dev);
-extern int vnet_del_if(struct Vnet *vnet, struct net_device *dev);
#endif
diff -r 9fb0bad776dd tools/vnet/vnet-module/vnet_ioctl.c
--- a/tools/vnet/vnet-module/vnet_ioctl.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnet-module/vnet_ioctl.c Fri Aug 26 09:04:02 2005
@@ -59,7 +59,7 @@
on the kernel interface being available to us (it's not exported @!$"%!).
Create a vnet N:
-- create the vnet device vnetifN: using commands to /proc, kernel api
+- create the vnet device vnifN: using commands to /proc, kernel api
- create the vnet bridge vnetN: using brctl in user-space
- for best results something should keep track of the mapping vnet id <->
bridge name
@@ -312,7 +312,6 @@
err = Parser_input(parser, NULL, 0);
if(err) goto exit;
obj = parser->val;
- objprint(iostdout, obj, 0); IOStream_print(iostdout, "\n");
for(l = obj; CONSP(l); l = CDR(l)){
err = eval(CAR(l));
if(err) break;
@@ -451,6 +450,7 @@
return err;
}
+#if 0
static int intof(Sxpr exp, int *v){
int err = 0;
char *s;
@@ -473,6 +473,24 @@
err = intof(val, v);
return err;
}
+#endif
+
+static 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;
+}
+
+static 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;
+}
static int macof(Sxpr exp, unsigned char *v){
int err = 0;
@@ -515,20 +533,27 @@
* 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(int vnet, int security){
+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, &vnetinfo) == 0){
err = -EEXIST;
goto exit;
}
err = Vnet_alloc(&vnetinfo);
if(err) goto exit;
- vnetinfo->vnet = vnet;
+ vnetinfo->vnet = *vnet;
vnetinfo->security = security;
+ strcpy(vnetinfo->device, device);
err = Vnet_create(vnetinfo);
exit:
if(vnetinfo) Vnet_decref(vnetinfo);
@@ -540,9 +565,15 @@
* @param vnet vnet id
* @return 0 on success, error code otherwise
*/
-static int ctrl_vnet_del(int vnet){
+static int ctrl_vnet_del(VnetId *vnet){
int err = -ENOSYS;
// Can't delete if there are any vifs on the vnet.
+
+ // Need to flush vif entries for the deleted vnet.
+ // Need to flush varp entries for the deleted vnet.
+ // Note that (un)register_netdev() hold rtnl_lock() around
+ // (un)register_netdevice().
+
//Vnet_del(vnet);
return err;
}
@@ -553,7 +584,7 @@
* @param vmac mac address
* @return 0 on success, error code otherwise
*/
-static int ctrl_vif_add(int vnet, Vmac *vmac){
+static int ctrl_vif_add(VnetId *vnet, Vmac *vmac){
int err = 0;
Vnet *vnetinfo = NULL;
Vif *vif = NULL;
@@ -561,7 +592,7 @@
dprintf(">\n");
err = Vnet_lookup(vnet, &vnetinfo);
if(err) goto exit;
- err = vif_add(vnet, vmac, &vif);
+ err = vif_create(vnet, vmac, &vif);
exit:
if(vnetinfo) Vnet_decref(vnetinfo);
if(vif) vif_decref(vif);
@@ -569,46 +600,13 @@
return err;
}
-/** Add net device 'vifname' to the bridge for 'vnet' and
- * create an entry for a vif with the given vnet and vmac.
- * This is used when device 'vifname' is a virtual device
- * connected to a vif in a vm.
- *
- * @param vifname name of device to bridge
+/** Delete a vif.
+ *
* @param vnet vnet id
* @param vmac mac address
* @return 0 on success, error code otherwise
*/
-static int ctrl_vif_conn(char *vifname, int vnet, Vmac *vmac){
- int err = 0;
- Vnet *vnetinfo = NULL;
- struct net_device *vifdev = NULL;
- Vif *vif = NULL;
-
- dprintf("> %s\n", vifname);
- err = Vnet_lookup(vnet, &vnetinfo);
- if(err) goto exit;
- err = vif_add(vnet, vmac, &vif);
- if(err) goto exit;
- err = vnet_get_device(vifname, &vifdev);
- if(err) goto exit;
- vif->dev = vifdev;
- err = vnet_add_if(vnetinfo, vifdev);
- exit:
- if(vnetinfo) Vnet_decref(vnetinfo);
- if(vif) vif_decref(vif);
- if(vifdev) dev_put(vifdev);
- dprintf("< err=%d\n", err);
- 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(int vnet, Vmac *vmac){
+static int ctrl_vif_del(VnetId *vnet, Vmac *vmac){
int err = 0;
Vnet *vnetinfo = NULL;
Vif *vif = NULL;
@@ -618,10 +616,6 @@
if(err) goto exit;
err = vif_lookup(vnet, vmac, &vif);
if(err) goto exit;
- if(vif->dev){
- vnet_del_if(vnetinfo, vif->dev);
- vif->dev = NULL;
- }
vif_remove(vnet, vmac);
exit:
if(vnetinfo) Vnet_decref(vnetinfo);
@@ -652,21 +646,37 @@
return err;
}
-/** (vnet.add (id <id>) [(security { none | auth | conf } )] )
+/** (varp.flush)
+ */
+static int eval_varp_flush(Sxpr exp){
+ int err = 0;
+ varp_flush();
+ return err;
+}
+
+/** (vnet.add (id <id>)
+ * [(vnetif <name>)]
+ * [(security { none | auth | conf } )]
+ * )
*/
static int eval_vnet_add(Sxpr exp){
int err = 0;
Sxpr oid = intern("id");
Sxpr osecurity = intern("security");
+ Sxpr ovnetif = intern("vnetif");
Sxpr csecurity;
- int id;
- char *security;
+ VnetId vnet = {};
+ char *device = NULL;
+ char dev[IFNAMSIZ] = {};
+ char *security = NULL;
int sec;
- err = child_int(exp, oid, &id);
- if(err) goto exit;
- if(id < VNET_VIF){
- err = -EINVAL;
- goto exit;
+
+ 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[7]));
+ device = dev;
}
csecurity = sxpr_child_value(exp, osecurity, intern("none"));
err = stringof(csecurity, &security);
@@ -681,8 +691,7 @@
err = -EINVAL;
goto exit;
}
- dprintf("> vnet id=%d\n", id);
- err = ctrl_vnet_add(id, sec);
+ err = ctrl_vnet_add(&vnet, device, sec);
exit:
dprintf("< err=%d\n", err);
return err;
@@ -698,11 +707,11 @@
static int eval_vnet_del(Sxpr exp){
int err = 0;
Sxpr oid = intern("id");
- int id;
-
- err = child_int(exp, oid, &id);
- if(err) goto exit;
- err = ctrl_vnet_del(id);
+ VnetId vnet = {};
+
+ err = child_vnet(exp, oid, &vnet);
+ if(err) goto exit;
+ err = ctrl_vnet_del(&vnet);
exit:
return err;
}
@@ -713,55 +722,32 @@
int err = 0;
Sxpr ovnet = intern("vnet");
Sxpr ovmac = intern("vmac");
- int vnet;
+ VnetId vnet = {};
Vmac vmac = {};
- err = child_int(exp, ovnet, &vnet);
+ 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.conn (vif <name>) (vnet <id>) (vmac <mac>))
- */
-static int eval_vif_conn(Sxpr exp){
- int err = 0;
- Sxpr ovif = intern("vif");
+ err = ctrl_vif_add(&vnet, &vmac);
+ exit:
+ return err;
+}
+
+/** (vif.del (vnet <vnet>) (vmac <macaddr>))
+ */
+static int eval_vif_del(Sxpr exp){
+ int err = 0;
Sxpr ovnet = intern("vnet");
Sxpr ovmac = intern("vmac");
- char *vif = NULL;
- int vnet = 0;
+ VnetId vnet = {};
Vmac vmac = {};
- err = child_string(exp, ovif, &vif);
- if(err) goto exit;
- err = child_int(exp, ovnet, &vnet);
+ err = child_vnet(exp, ovnet, &vnet);
if(err) goto exit;
err = child_mac(exp, ovmac, vmac.mac);
- dprintf("> connect vif=%s vnet=%d\n", vif, vnet);
- err = ctrl_vif_conn(vif, vnet, &vmac);
- exit:
- dprintf("< err=%d\n", err);
- return err;
-}
-
-/** (vif.del (vnet <vnet>) (vmac <macaddr>))
- */
-static int eval_vif_del(Sxpr exp){
- int err = 0;
- Sxpr ovnet = intern("vnet");
- Sxpr ovmac = intern("vmac");
- int vnet;
- Vmac vmac = {};
-
- err = child_int(exp, ovnet, &vnet);
- if(err) goto exit;
- err = child_mac(exp, ovmac, vmac.mac);
- if(err) goto exit;
- err = ctrl_vif_del(vnet, &vmac);
+ if(err) goto exit;
+ err = ctrl_vif_del(&vnet, &vmac);
exit:
return err;
}
@@ -776,23 +762,23 @@
SxprEval defs[] = {
{ intern("varp.print"), eval_varp_print },
{ intern("varp.mcaddr"), eval_varp_mcaddr },
+ { intern("varp.flush"), eval_varp_flush },
{ intern("vif.add"), eval_vif_add },
- { intern("vif.conn"), eval_vif_conn },
{ intern("vif.del"), eval_vif_del },
{ intern("vnet.add"), eval_vnet_add },
{ intern("vnet.del"), eval_vnet_del },
{ ONONE, NULL } };
SxprEval *def;
- dprintf(">\n");
- err = -EINVAL;
+ iprintf("> "); objprint(iostdout, exp, 0); IOStream_print(iostdout, "\n");
+ err = -ENOSYS;
for(def = defs; !NONEP(def->elt); def++){
if(sxpr_elementp(exp, def->elt)){
err = def->fn(exp);
break;
}
}
- dprintf("< err=%d\n", err);
+ iprintf("< err=%d\n", err);
return err;
}
diff -r 9fb0bad776dd tools/vnet/vnetd/Makefile
--- a/tools/vnet/vnetd/Makefile Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnetd/Makefile Fri Aug 26 09:04:02 2005
@@ -16,32 +16,29 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#----------------------------------------------------------------------------
+VNET_ROOT = $(shell cd .. && pwd)
+include $(VNET_ROOT)/Make.env
+
all: vnetd
#----------------------------------------------------------------------------
-XEN_ROOT = ../../..
include $(XEN_ROOT)/tools/Rules.mk
VNETD_INSTALL_DIR = /usr/sbin
-LIB_DIR = ../libxutil
-VNET_DIR = ../vnet-module
-
-INCLUDES += -I$(LIB_DIR)
-INCLUDES += -I$(VNET_DIR)
+INCLUDES += -I$(LIBXUTIL_DIR)
+INCLUDES += -I$(VNET_MODULE_DIR)
#----------------------------------------------------------------------------
# GC.
-GC_DIR:=../gc/install
-GC_INCLUDE:= $(GC_DIR)/include
-GC_LIB_DIR:=$(GC_DIR)/lib
INCLUDES += -I$(GC_INCLUDE)
#LIBS += -L$(GC_LIB_DIR)
CPPFLAGS += -D USE_GC
#----------------------------------------------------------------------------
+CFLAGS += -g
CFLAGS += -Wall
CFLAGS += $(INCLUDES) $(LIBS)
@@ -51,7 +48,7 @@
CFLAGS += -Wp,-MD,.$(@F).d
PROG_DEP = .*.d
-vpath %.c $(LIB_DIR)
+vpath %.c $(LIBXUTIL_DIR)
IPATHS:=$(INCLUDES:-I=)
vpath %.h $(IPATHS)
@@ -83,9 +80,9 @@
VNETD_OBJ := $(VNETD_SRC:.c=.o)
-#VNETD_LIBS:= $(GC_LIB_DIR)/libgc.so.1.0.2
+#VNETD_LIBS:= $(GC_LIB_SO)
#VNETD_LIBS:= -lgc
-VNETD_LIBS:= $(GC_LIB_DIR)/libgc.a
+VNETD_LIBS:= $(GC_LIB_A)
vnetd: $(VNETD_OBJ)
$(CC) $(CFLAGS) -o $@ $^ $(VNETD_LIBS) -ldl -lpthread
@@ -95,8 +92,8 @@
install -m 0755 vnetd $(DESTDIR)$(VNETD_INSTALL_DIR)
clean:
- -rm -f *.a *.o *~
- -rm -f vnetd
- -rm -f $(PROG_DEP)
+ -@$(RM) *.a *.o *~
+ -@$(RM) vnetd
+ -@$(RM) $(PROG_DEP)
-include $(PROG_DEP)
diff -r 9fb0bad776dd tools/vnet/vnetd/vcache.c
--- a/tools/vnet/vnetd/vcache.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnetd/vcache.c Fri Aug 26 09:04:02 2005
@@ -44,6 +44,8 @@
#undef DEBUG
#include "debug.h"
+#include "varp_util.c"
+
static VarpCache *vcache = NULL;
void IPMessageQueue_init(IPMessageQueue *queue, int maxlen){
@@ -97,16 +99,20 @@
* @param vmac vmac (in network order)
* @return 0 on success, error code otherwise
*/
-int varp_send(Conn *conn, uint16_t opcode, uint32_t vnet, Vmac *vmac, uint32_t
addr){
+int varp_send(Conn *conn, uint16_t opcode, VnetId *vnet, Vmac *vmac, VarpAddr
*addr){
int err = 0;
int varp_n = sizeof(VarpHdr);
VarpHdr varph = {};
-
- varph.vnetmsghdr.id = htons(VARP_ID);
- varph.vnetmsghdr.opcode = htons(opcode);
- varph.vnet = vnet;
- varph.vmac = *vmac;
- varph.addr = addr;
+#ifdef DEBUG
+ char vnetbuf[VNET_ID_BUF];
+ char addrbuf[VARP_ADDR_BUF];
+#endif
+
+ varph.hdr.id = htons(VARP_ID);
+ varph.hdr.opcode = htons(opcode);
+ varph.vnet = *vnet;
+ varph.vmac = *vmac;
+ varph.addr = *addr;
if(0){
struct sockaddr_in self;
@@ -117,8 +123,10 @@
}
dprintf("> addr=%s opcode=%d\n",
inet_ntoa(conn->addr.sin_addr), opcode);
- dprintf("> vnet=%d vmac=" MACFMT " addr=" IPFMT "\n",
- ntohl(vnet), MAC6TUPLE(vmac->mac), NIPQUAD(addr));
+ dprintf("> vnet=%s vmac=" MACFMT " addr=%s\n",
+ VnetId_ntoa(vnet, vnetbuf),
+ MAC6TUPLE(vmac->mac),
+ VarpAddr_ntoa(addr, addrbuf));
err = marshal_bytes(conn->out, &varph, varp_n);
marshal_flush(conn->out);
dprintf("< err=%d\n", err);
@@ -157,21 +165,24 @@
*/
void VCEntry_print(VCEntry *ventry){
if(ventry){
- char *c, *d;
+ char *state, *flags;
+ char vnetbuf[VNET_ID_BUF];
+ char addrbuf[VARP_ADDR_BUF];
+
switch(ventry->state){
- case VCACHE_STATE_INCOMPLETE: c = "INC"; break;
- case VCACHE_STATE_REACHABLE: c = "RCH"; break;
- case VCACHE_STATE_FAILED: c = "FLD"; break;
- default: c = "UNK"; break;
- }
- d = (VCEntry_get_flags(ventry, VCACHE_FLAG_PROBING) ? "P" : " ");
-
- printf("VENTRY(%p %s %s vnet=%d vmac=" MACFMT " addr=" IPFMT "
time=%g)\n",
+ case VCACHE_STATE_INCOMPLETE: state = "INC"; break;
+ case VCACHE_STATE_REACHABLE: state = "RCH"; break;
+ case VCACHE_STATE_FAILED: state = "FLD"; break;
+ default: state = "UNK"; break;
+ }
+ flags = (VCEntry_get_flags(ventry, VCACHE_FLAG_PROBING) ? "P" : " ");
+
+ printf("VENTRY(%p %s %s vnet=%s vmac=" MACFMT " addr=%s time=%g)\n",
ventry,
- c, d,
- ntohl(ventry->key.vnet),
+ state, flags,
+ VnetId_ntoa(&ventry->key.vnet, vnetbuf),
MAC6TUPLE(ventry->key.vmac.mac),
- NIPQUAD(ventry->addr),
+ VarpAddr_ntoa(&ventry->addr, addrbuf),
ventry->timestamp);
} else {
printf("VENTRY: Null!\n");
@@ -239,11 +250,11 @@
* @param vmac virtual MAC address (copied)
* @return ventry or null
*/
-VCEntry * VCEntry_new(uint32_t vnet, Vmac *vmac){
+VCEntry * VCEntry_new(VnetId *vnet, Vmac *vmac){
VCEntry *z = ALLOCATE(VCEntry);
z->state = VCACHE_STATE_INCOMPLETE;
z->timestamp = time_now();
- z->key.vnet = vnet;
+ z->key.vnet = *vnet;
z->key.vmac = *vmac;
return z;
}
@@ -256,15 +267,9 @@
*/
Hashcode vcache_key_hash_fn(void *k){
VCKey *key = k;
- Hashcode h;
- h = hash_2ul(key->vnet,
- (key->vmac.mac[0] << 24) |
- (key->vmac.mac[1] << 16) |
- (key->vmac.mac[2] << 8) |
- (key->vmac.mac[3] ));
- h = hash_hul(h,
- (key->vmac.mac[4] << 8) |
- (key->vmac.mac[5] ));
+ Hashcode h = 0;
+ h = VnetId_hash(h, &key->vnet);
+ h = Vmac_hash(h, &key->vmac);
return h;
}
@@ -278,8 +283,8 @@
int vcache_key_equal_fn(void *k1, void *k2){
VCKey *key1 = k1;
VCKey *key2 = k2;
- return (key1->vnet == key2->vnet)
- && (memcmp(key1->vmac.mac, key2->vmac.mac, ETH_ALEN) == 0);
+ return (VnetId_eq(&key1->vnet , &key2->vnet) &&
+ Vmac_eq(&key1->vmac, &key2->vmac));
}
void VarpCache_schedule(VarpCache *z);
@@ -351,7 +356,7 @@
* @param vmac virtual MAC address (copied)
* @return new entry or null
*/
-VCEntry * VarpCache_add(VarpCache *z, uint32_t vnet, Vmac *vmac){
+VCEntry * VarpCache_add(VarpCache *z, VnetId *vnet, Vmac *vmac){
VCEntry *ventry;
HTEntry *entry;
@@ -378,8 +383,8 @@
* @param vmac virtual MAC addres
* @return entry found or null
*/
-VCEntry * VarpCache_lookup(VarpCache *z, uint32_t vnet, Vmac *vmac){
- VCKey key = { .vnet = vnet, .vmac = *vmac };
+VCEntry * VarpCache_lookup(VarpCache *z, VnetId *vnet, Vmac *vmac){
+ VCKey key = { .vnet = *vnet, .vmac = *vmac };
VCEntry *ventry;
ventry = HashTable_get(z->table, &key);
return ventry;
@@ -389,13 +394,15 @@
dprintf(">\n");
if(VCEntry_get_flags(ventry, VCACHE_FLAG_LOCAL_PROBE)){
dprintf("> local probe\n");
- varp_send(vnetd->bcast_conn, VARP_OP_REQUEST, ventry->key.vnet,
&ventry->key.vmac, ventry->addr);
+ varp_send(vnetd->bcast_conn, VARP_OP_REQUEST,
+ &ventry->key.vnet, &ventry->key.vmac, &ventry->addr);
}
if(VCEntry_get_flags(ventry, VCACHE_FLAG_REMOTE_PROBE)){
ConnList *l;
dprintf("> remote probe\n");
for(l = vnetd->connections; l; l = l->next){
- varp_send(l->conn, VARP_OP_REQUEST, ventry->key.vnet,
&ventry->key.vmac, ventry->addr);
+ varp_send(l->conn, VARP_OP_REQUEST,
+ &ventry->key.vnet, &ventry->key.vmac, &ventry->addr);
}
}
@@ -440,7 +447,8 @@
IPMessage *msg;
while((msg = IPMessageQueue_pop(&ventry->queue))){
dprintf("> announce\n");
- varp_send(msg->conn, VARP_OP_ANNOUNCE, ventry->key.vnet,
&ventry->key.vmac, ventry->addr);
+ varp_send(msg->conn, VARP_OP_ANNOUNCE,
+ &ventry->key.vnet, &ventry->key.vmac, &ventry->addr);
}
}
exit:
@@ -459,7 +467,7 @@
VCEntry *ventry;
dprintf(">\n");
- ventry = VarpCache_lookup(z, varph->vnet, &varph->vmac);
+ ventry = VarpCache_lookup(z, &varph->vnet, &varph->vmac);
if(ventry){
err = VCEntry_update(ventry, msg, varph, state);
} else {
@@ -503,14 +511,14 @@
* @param local whether it's local or not
*/
void vcache_forward_varp(VarpHdr *varph, int local){
- uint16_t opcode = ntohs(varph->vnetmsghdr.opcode);
+ uint16_t opcode = ntohs(varph->hdr.opcode);
if(local){
ConnList *l;
for(l = vnetd->connections; l; l = l->next){
- varp_send(l->conn, opcode, varph->vnet, &varph->vmac,
varph->addr);
+ varp_send(l->conn, opcode, &varph->vnet, &varph->vmac,
&varph->addr);
}
} else {
- varp_send(vnetd->bcast_conn, opcode, varph->vnet, &varph->vmac,
varph->addr);
+ varp_send(vnetd->bcast_conn, opcode, &varph->vnet, &varph->vmac,
&varph->addr);
}
}
@@ -531,13 +539,13 @@
#else
int vcache_handle_request(IPMessage *msg, VarpHdr *varph, int local){
int err = -ENOENT;
- uint32_t vnet;
+ VnetId *vnet;
Vmac *vmac;
VCEntry *ventry = NULL;
int reply = 0;
dprintf(">\n");
- vnet = htonl(varph->vnet);
+ vnet = &varph->vnet;
vmac = &varph->vmac;
ventry = VarpCache_lookup(vcache, vnet, vmac);
if(!ventry){
@@ -605,13 +613,18 @@
VarpHdr *varph = &vmsg->varp.varph;
dprintf(">\n");
- if(1){
+#ifdef DEBUG
+ {
+ char vnetbuf[VNET_ID_BUF];
dprintf("> src=%s:%d\n", inet_ntoa(msg->saddr.sin_addr),
ntohs(msg->saddr.sin_port));
dprintf("> dst=%s:%d\n", inet_ntoa(msg->daddr.sin_addr),
ntohs(msg->daddr.sin_port));
- dprintf("> opcode=%d vnet=%u vmac=" MACFMT "\n",
- ntohs(varph->opcode), ntohl(varph->vnet),
MAC6TUPLE(varph->vmac.mac));
- }
- switch(ntohs(varph->vnetmsghdr.opcode)){
+ dprintf("> opcode=%d vnet=%s vmac=" MACFMT "\n",
+ ntohs(varph->opcode),
+ VnetId_ntoa(&varph->vnet, vnetbuf),
+ MAC6TUPLE(varph->vmac.mac));
+ }
+#endif
+ switch(ntohs(varph->hdr.opcode)){
case VARP_OP_REQUEST:
err = vcache_handle_request(msg, varph, local);
break;
diff -r 9fb0bad776dd tools/vnet/vnetd/vcache.h
--- a/tools/vnet/vnetd/vcache.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnetd/vcache.h Fri Aug 26 09:04:02 2005
@@ -93,7 +93,7 @@
/** Key for varp cache entries. */
typedef struct VCKey {
/** Vnet id (network order). */
- uint32_t vnet;
+ VnetId vnet;
/** Virtual MAC address. */
Vmac vmac;
} VCKey;
@@ -103,7 +103,7 @@
VCKey key;
/** Care-of address for the key. */
- uint32_t addr;
+ VarpAddr addr;
/** Alias coa if we are a gateway. */
//uint32_t gateway;
@@ -111,7 +111,7 @@
//uint32_t encaps;
/** Where this entry came from. */
- uint32_t source;
+ VarpAddr source;
/** Last-updated timestamp. */
double timestamp;
diff -r 9fb0bad776dd tools/vnet/vnetd/vnetd.c
--- a/tools/vnet/vnetd/vnetd.c Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnetd/vnetd.c Fri Aug 26 09:04:02 2005
@@ -112,7 +112,6 @@
#include <sys/wait.h>
#include <sys/select.h>
-//#include </usr/include/linux/ip.h> // For struct iphdr;
#include <linux/ip.h> // For struct iphdr;
#include <linux/if_ether.h>
@@ -492,22 +491,16 @@
dprintf("> addr=%s protocol=%d n=%d\n",
inet_ntoa(conn->addr.sin_addr), protocol, data_n);
string_stream_init(io, &sdata, buf, sizeof(buf));
- dprintf("> 10\n");
err = marshal_uint16(io, VNET_FWD_ID);
if(err < 0) goto exit;
- dprintf("> 20\n");
err = marshal_uint16(io, 0);
if(err < 0) goto exit;
- dprintf("> 30\n");
err = marshal_uint16(io, protocol);
if(err < 0) goto exit;
- dprintf("> 40\n");
err = marshal_uint16(io, data_n);
if(err < 0) goto exit;
- dprintf("> 50\n");
err = marshal_bytes(io, data, data_n);
if(err < 0) goto exit;
- dprintf("> 60 bytes=%d\n", IOStream_get_written(io));
err = IOStream_write(conn->out, buf, IOStream_get_written(io));
IOStream_flush(conn->out);
exit:
@@ -978,7 +971,7 @@
int err = 0;
uint32_t addr = INADDR_ANY;
uint16_t port = vnetd->port;
- int flags = VSOCK_BIND | VSOCK_REUSE;
+ int flags = (VSOCK_BIND | VSOCK_REUSE);
err = create_socket(SOCK_DGRAM, addr, port, flags, val);
return err;
}
@@ -1162,7 +1155,7 @@
err = vnetd_broadcast_conn(vnetd, &vnetd->bcast_conn);
if(err < 0) goto exit;
{
- int flags = VSOCK_BROADCAST | VSOCK_MULTICAST;
+ int flags = (VSOCK_BROADCAST | VSOCK_MULTICAST);
uint32_t mcaddr = vnetd->mcast_addr.sin_addr.s_addr;
err = vnetd_raw_socket(IPPROTO_ETHERIP, flags, mcaddr,
&vnetd->etherip_sock);
diff -r 9fb0bad776dd tools/vnet/vnetd/vnetd.h
--- a/tools/vnet/vnetd/vnetd.h Thu Aug 25 18:49:48 2005
+++ b/tools/vnet/vnetd/vnetd.h Fri Aug 26 09:04:02 2005
@@ -20,6 +20,7 @@
#include <asm/types.h>
#include <linux/if_ether.h>
#include "if_varp.h"
+#include "varp_util.h"
#include "connection.h"
#include "sxpr.h"
diff -r 9fb0bad776dd tools/vnet/INSTALL
--- a/tools/vnet/INSTALL Thu Aug 25 18:49:48 2005
+++ /dev/null Fri Aug 26 09:04:02 2005
@@ -1,31 +0,0 @@
-To compile and install run "make install"; if it fails or you need to
reinstall
-run "make clean" first or the build will fail, at least that is what I have
-found under 2.6.10.
-
-Other important items:
-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 alogorithms 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
-
-4) The module (vnet_module) will not properly load from the command line
- with a "modprobe vnet_module". Use network-vnet to properly configure
- your system and load the module for you.
-
-Please refer to the additional documentation found in tools/vnet/doc for
-proper syntax and config file parameters.
-
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|