ia64/xen-unstable
changeset 6448:6bad5eb72ce0
Vnet update.
Fix 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@hp.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
Fix 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@hp.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
line diff
1.1 --- a/tools/vnet/00INSTALL Fri Aug 26 10:51:10 2005 +0000 1.2 +++ b/tools/vnet/00INSTALL Fri Aug 26 10:52:53 2005 +0000 1.3 @@ -1,14 +1,34 @@ 1.4 1.5 -To compile and install run "make install"; if it fails or you need to reinstall 1.6 -run "make clean" first or the build will fail, at least that is what I have 1.7 -found under 2.6.10. 1.8 +make 1.9 + - compile in local dirs. The module is in vnet-module/vnet_module.ko. 1.10 + 1.11 +make dist 1.12 + - compile and install into $(XEN_ROOT)/dist/install, 1.13 + - where XEN_ROOT is the root of the xen tree. 1.14 + 1.15 +make install 1.16 + - compile and install into system. 1.17 1.18 -Other important items: 1.19 +The xen0 kernel must have been compiled before building the vnet module. 1.20 +The vnet module installs to 1.21 + /lib/modules/<kernel version>-xen0/kernel/xen/vnet_module.ko 1.22 + 1.23 +The vnet module should be loaded before starting xend, or 1.24 +xend will fail to create any persistent vnets it has in its configuration. 1.25 +The script network-vnet is a modified version of the xen network script 1.26 +that loads the module if it's not already loaded. 1.27 + 1.28 +The module uses kernel crypto functions, and these need to be 1.29 +enabled in the xen0 kernel config. They should be on by default - 1.30 +if they're not you will get compile or insmod errors (see below). 1.31 + 1.32 +Kernel config options: 1.33 + 1.34 1) You will need to have your xen0 kernel compiled with HMAC_SUPPORT 1.35 2.6.x = (MAIN MENU: Cryptographic Options -> HMAC Support) 1.36 BEFORE running "make install". 1.37 1.38 -2) You will want at least some of the other alogorithms listed under 1.39 +2) You will want at least some of the other algorithms listed under 1.40 "Cryptographic Options" for the kernel compiled as modules. 1.41 1.42 3) You will want the networking IPsec/VLAN options compiled in as modules 1.43 @@ -23,9 +43,5 @@ 3) You will want the networking IPsec/VL 1.44 1.45 802.1Q VLAN Support 1.46 1.47 -4) The module (vnet_module) will not properly load from the command line 1.48 - with a "modprobe vnet_module". Use network-vnet to properly configure 1.49 - your system and load the module for you. 1.50 - 1.51 Please refer to the additional documentation found in tools/vnet/doc for 1.52 proper syntax and config file parameters.
2.1 --- a/tools/vnet/INSTALL Fri Aug 26 10:51:10 2005 +0000 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,31 +0,0 @@ 2.4 -To compile and install run "make install"; if it fails or you need to reinstall 2.5 -run "make clean" first or the build will fail, at least that is what I have 2.6 -found under 2.6.10. 2.7 - 2.8 -Other important items: 2.9 -1) You will need to have your xen0 kernel compiled with HMAC_SUPPORT 2.10 - 2.6.x = (MAIN MENU: Cryptographic Options -> HMAC Support) 2.11 - BEFORE running "make install". 2.12 - 2.13 -2) You will want at least some of the other alogorithms listed under 2.14 - "Cryptographic Options" for the kernel compiled as modules. 2.15 - 2.16 -3) You will want the networking IPsec/VLAN options compiled in as modules 2.17 - 2.6.x = (MAIN MENU: Device Drivers -> Networking Support -> 2.18 - Networking Options -> 2.19 - IP: AH transformation 2.20 - IP: ESP transformation 2.21 - IP: IPComp transformation 2.22 - IP: tunnel transformation 2.23 - 2.24 - IPsec user configuration interface 2.25 - 2.26 - 802.1Q VLAN Support 2.27 - 2.28 -4) The module (vnet_module) will not properly load from the command line 2.29 - with a "modprobe vnet_module". Use network-vnet to properly configure 2.30 - your system and load the module for you. 2.31 - 2.32 -Please refer to the additional documentation found in tools/vnet/doc for 2.33 -proper syntax and config file parameters. 2.34 -
3.1 --- a/tools/vnet/Makefile Fri Aug 26 10:51:10 2005 +0000 3.2 +++ b/tools/vnet/Makefile Fri Aug 26 10:52:53 2005 +0000 3.3 @@ -1,19 +1,22 @@ 3.4 +# -*- mode: Makefile; -*- 3.5 3.6 -export LINUX_SERIES ?=2.6 3.7 +ifndef VNET_ROOT 3.8 +export VNET_ROOT = $(shell pwd) 3.9 +include $(VNET_ROOT)/Make.env 3.10 +endif 3.11 3.12 -# Root path to install in. 3.13 -# Set to '/' to install relative to filesystem root. 3.14 -export prefix?=$(shell cd ../../dist/install && pwd) 3.15 +.PHONY: all compile install dist clean pristine 3.16 +.PHONY: gc-all gc-install gc-clean 3.17 3.18 -.PHONY: all compile 3.19 -.PHONY: gc-install gc-clean gc-prstine 3.20 -.PHONY: libxutil vnetd vnet-module install dist clean pristine 3.21 +SUBDIRS:= 3.22 +SUBDIRS+= examples 3.23 +SUBDIRS+= gc 3.24 +SUBDIRS+= libxutil 3.25 +SUBDIRS+= vnetd 3.26 +SUBDIRS+= vnet-module 3.27 3.28 all: compile 3.29 3.30 -compile: libxutil vnetd vnet-module 3.31 -#compile: vnet-module 3.32 - 3.33 gc.tar.gz: 3.34 wget http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/$@ 3.35 3.36 @@ -21,36 +24,39 @@ gc: gc.tar.gz 3.37 tar xfz gc.tar.gz 3.38 ln -sf gc?.? gc 3.39 3.40 -gc-install: gc 3.41 - (cd gc && make test && ./configure --prefix=`pwd`/install) 3.42 +$(GC_LIB_A): gc 3.43 + (cd gc && ./configure --prefix=$(GC_DIR) ) 3.44 make -C gc 3.45 - make -C gc install 3.46 + DESTDIR="" make -C gc install 3.47 + 3.48 +gc-all: $(GC_LIB_A) 3.49 + 3.50 +gc-install: 3.51 3.52 gc-clean: 3.53 - -$(MAKE) -C gc clean 3.54 + -@$(RM) -r gc?.? gc 3.55 3.56 -gc-pristine: 3.57 - -rm -rf gc?.? gc 3.58 +submak = $(MAKE) -C $(patsubst %-$(1),%,$(@)) $(1) 3.59 +subtgt = $(patsubst %,%-$(1),$(SUBDIRS)) 3.60 3.61 -libxutil: 3.62 - $(MAKE) -C libxutil 3.63 +%-all: 3.64 + $(call submak,all) 3.65 3.66 -vnetd: gc-install 3.67 - $(MAKE) -C vnetd 3.68 - 3.69 -vnet-module: 3.70 - $(MAKE) -C vnet-module 3.71 +%-clean: 3.72 + -$(call submak,clean) 3.73 3.74 -install: compile 3.75 - $(MAKE) -C libxutil install 3.76 - $(MAKE) -C vnetd install 3.77 - $(MAKE) -C vnet-module install 3.78 - $(MAKE) -C examples install 3.79 +%-install: 3.80 + $(call submak,install) 3.81 + 3.82 +compile: $(call subtgt,all) 3.83 + 3.84 +install: DESTDIR= 3.85 +install: dist 3.86 3.87 -clean: 3.88 - -$(MAKE) -C libxutil clean 3.89 - -$(MAKE) -C vnetd clean 3.90 - -$(MAKE) -C vnet-module clean 3.91 - -rm -rf gc?.? gc 3.92 +dist: compile $(call subtgt,install) 3.93 3.94 -pristine: clean gc-pristine 3.95 +clean: $(call subtgt,clean) 3.96 + -@$(RM) -r build 3.97 + 3.98 +pristine: clean 3.99 + -@$(RM) gc.tar.gz
4.1 --- a/tools/vnet/doc/vnet-module.txt Fri Aug 26 10:51:10 2005 +0000 4.2 +++ b/tools/vnet/doc/vnet-module.txt Fri Aug 26 10:52:53 2005 +0000 4.3 @@ -1,21 +1,34 @@ 4.4 Vnet Module Command Interface 4.5 Mike Wray <mike.wray@hp.com> 4.6 -2004/09/17 4.7 +2005/08/25 4.8 4.9 When insmod the vnet-module creates /proc/vnet/policy which 4.10 can be used to control the module by writing commands into it. 4.11 The return code from the command should be returned by close. 4.12 +Xend uses these commands to implement its vnet interface. 4.13 4.14 The commands are: 4.15 4.16 -(vnet.add (id <id>) [(security { none | auth | conf } )] ) 4.17 +(vnet.add (id <id>) [(vnetif <ifname>)] [(security { none | auth | conf } )] ) 4.18 4.19 Create the vnet with id <id> and the given security level (default none). 4.20 +Vnet ids are 128-bit and can be specified as 8 fields of 1 to 4 hex digits 4.21 +separated by colons. A vnet id with no colons is treated as one with the first 4.22 +7 fields zero. Examples: 4.23 + 4.24 +1500 - equivalent to 0:0:0:0:0:0:0:1500 4.25 +aaff:0:0:0:0:0:77:88 4.26 + 4.27 Security levels: 4.28 - none: no security 4.29 - auth: message authentication (IPSEC hmac) 4.30 - conf: message confidentiality (IPSEC hmac and encryption) 4.31 4.32 +The <ifname> is the name of the network device created for the vnet. 4.33 +If not given it defaults to vnif<N>, where <N> is the hex for the 4.34 +8-th field in the id. Note that network device names can have a 4.35 +maximum of 14 characters. 4.36 + 4.37 (vnet.del (id <id>)) 4.38 4.39 Delete the vnet with id <id>. 4.40 @@ -31,12 +44,18 @@ on vnet <vnetid>. 4.41 Remove the vif with MAC address <macaddr> from the vnet with id <vnetid>. 4.42 The vnet module will stop responding to VARP for the vif. 4.43 4.44 +(vif.print) 4.45 + 4.46 +Print the known vnets, vifs and varp cache on the console. 4.47 + 4.48 Examples: 4.49 4.50 To create vnet 10 with no security: 4.51 4.52 echo '(vnet.add (id 10))' > /proc/vnet/policy 4.53 4.54 +This creates a device vnif0010. 4.55 + 4.56 To create vnet 11 with message authentication: 4.57 4.58 echo '(vnet.add (id 11) (security auth))' > /proc/vnet/policy
5.1 --- a/tools/vnet/doc/vnet-xend.txt Fri Aug 26 10:51:10 2005 +0000 5.2 +++ b/tools/vnet/doc/vnet-xend.txt Fri Aug 26 10:52:53 2005 +0000 5.3 @@ -3,11 +3,13 @@ Vnets: Virtual Networks for Virtual Mach 5.4 5.5 Mike Wray <mike.wray@hp.com> 5.6 5.7 +2005/08/25 5.8 + 5.9 0) Introduction 5.10 --------------- 5.11 5.12 Vnets provide virtual private LANs for virtual machines. 5.13 -This is done using bridging and tunneling. A virtual interface 5.14 +This is done using bridging and multipoint tunneling. A virtual interface 5.15 on a vnet can only see other interfaces on the same vnet - it cannot 5.16 see the real network, and the real network cannot see it either. 5.17 5.18 @@ -32,13 +34,16 @@ Configure the network script: 5.19 5.20 Restart xend. 5.21 5.22 +Alternatively insert the vnet module using vnet-insert, 5.23 +preferably before xend starts. 5.24 + 5.25 2) Creating vnets 5.26 ----------------- 5.27 5.28 Xend already implements commands to add/remove vnets and 5.29 bridge to them. To add a vnet use 5.30 5.31 -xm call vnet_add <vnet config file> 5.32 +xm vnet-create <vnet config file> 5.33 5.34 For example, if vnet97.sxp contains: 5.35 5.36 @@ -46,7 +51,7 @@ For example, if vnet97.sxp contains: 5.37 5.38 do 5.39 5.40 -xm call vnet_add vnet97.sxp 5.41 +xm vnet-create vnet97.sxp 5.42 5.43 This will define a vnet with id 97 and no security. The bridge for the 5.44 vnet is called vnet97 and the virtual interface for it is vnetif97. 5.45 @@ -64,31 +69,35 @@ In sxp: 5.46 Once configured, vnets are persistent in the xend database. 5.47 To remove a vnet use 5.48 5.49 -xm call vnet_delete <vnet id> 5.50 +xm vnet-delete <vnet id> 5.51 5.52 To list vnets use 5.53 5.54 -xm call vnets 5.55 +xm vnet-list 5.56 5.57 To get information on a vnet id use 5.58 5.59 -xm call vnet <vnet id> 5.60 +xm vnet-list <vnet id> 5.61 5.62 3) Troubleshooting 5.63 ------------------ 5.64 5.65 The vnet module should appear in 'lsmod'. 5.66 -If a vnet has been configured it should appear in the output of 'xm call vnets'. 5.67 +If a vnet has been configured it should appear in the output of 'xm vnet-list'. 5.68 Its bridge and interface should appear in 'ifconfig'. 5.69 It should also show in 'brctl show', with its attached interfaces. 5.70 5.71 -You can 'see into' a vnet from dom0 if you put an IP address on the bridge. 5.72 +You can 'see into' a vnet from dom0 if you put an IP address on the bridge 5.73 +and configure its MAC address as a vif. 5.74 For example, if you have vnet97 with a vm with ip addr 10.0.0.12 on it, 5.75 -then 5.76 +and <mac> is the MAC address of vnet97 (use ifconfig), then 5.77 5.78 +echo '(vif.add (vnet 97) (vmac <mac>))' >/proc/vnet/policy 5.79 ifconfig vnet97 10.0.0.20 up 5.80 5.81 should let you ping 10.0.0.12 via the vnet97 bridge. 5.82 +This works even if the vm with vif 10.0.0.12 is on another 5.83 +machine (it only works locally if you don't use vif.add). 5.84 5.85 4) Examples 5.86 ----------- 5.87 @@ -104,11 +113,11 @@ Here's the full config for a vm on vnet 5.88 (linux 5.89 (kernel /boot/vmlinuz-2.6-xenU) 5.90 (ip 10.0.0.12:1.2.3.4::::eth0:off) 5.91 - (root /dev/hda1) 5.92 + (root /dev/sda1) 5.93 (args 'rw fastboot 4') 5.94 ) 5.95 ) 5.96 - (device (vbd (uname phy:hda2) (dev hda1) (mode w))) 5.97 + (device (vbd (uname phy:hda2) (dev sda1) (mode w))) 5.98 (device (vif (mac aa:00:00:11:00:12) (bridge vnet97))) 5.99 ) 5.100 5.101 @@ -123,11 +132,11 @@ If you run another vm on the same vnet: 5.102 (linux 5.103 (kernel /boot/vmlinuz-2.6-xenU) 5.104 (ip 10.0.0.11:1.2.3.4::::eth0:off) 5.105 - (root /dev/hda1) 5.106 + (root /dev/sda1) 5.107 (args 'rw fastboot 4') 5.108 ) 5.109 ) 5.110 - (device (vbd (uname phy:hda3) (dev hda1) (mode w))) 5.111 + (device (vbd (uname phy:hda3) (dev sda1) (mode w))) 5.112 (device (vif (mac aa:00:00:11:00:11) (bridge vnet97))) 5.113 ) 5.114
6.1 --- a/tools/vnet/examples/Makefile Fri Aug 26 10:51:10 2005 +0000 6.2 +++ b/tools/vnet/examples/Makefile Fri Aug 26 10:52:53 2005 +0000 6.3 @@ -3,10 +3,13 @@ 6.4 6.5 XEN_SCRIPT_DIR:=/etc/xen/scripts 6.6 6.7 +.PHONY: all install clean 6.8 + 6.9 all: 6.10 6.11 install: 6.12 install -m 0755 -d $(DESTDIR)$(XEN_SCRIPT_DIR) 6.13 install -m 0554 network-vnet $(DESTDIR)$(XEN_SCRIPT_DIR) 6.14 + install -m 0554 vnet-insert $(DESTDIR)$(XEN_SCRIPT_DIR) 6.15 6.16 clean: 6.17 \ No newline at end of file
7.1 --- a/tools/vnet/examples/network-vnet Fri Aug 26 10:51:10 2005 +0000 7.2 +++ b/tools/vnet/examples/network-vnet Fri Aug 26 10:52:53 2005 +0000 7.3 @@ -1,218 +1,10 @@ 7.4 #!/bin/sh 7.5 -#============================================================================ 7.6 -# Default Xen network start/stop script. 7.7 -# Xend calls a network script when it starts. 7.8 -# The script name to use is defined in /etc/xen/xend-config.sxp 7.9 -# in the network-script field. 7.10 -# 7.11 -# This script creates a bridge (default xen-br0), adds a device 7.12 -# (default eth0) to it, copies the IP addresses from the device 7.13 -# to the bridge and adjusts the routes accordingly. 7.14 -# 7.15 -# If all goes well, this should ensure that networking stays up. 7.16 -# However, some configurations are upset by this, especially 7.17 -# NFS roots. If the bridged setup does not meet your needs, 7.18 -# configure a different script, for example using routing instead. 7.19 -# 7.20 -# Usage: 7.21 -# 7.22 -# network (start|stop|status) {VAR=VAL}* 7.23 -# 7.24 -# Vars: 7.25 -# 7.26 -# bridge The bridge to use (default xen-br0). 7.27 -# netdev The interface to add to the bridge (default eth0). 7.28 -# antispoof Whether to use iptables to prevent spoofing (default yes). 7.29 -# 7.30 -# start: 7.31 -# Creates the bridge and enslaves netdev to it. 7.32 -# Copies the IP addresses from netdev to the bridge. 7.33 -# Deletes the routes to netdev and adds them on bridge. 7.34 -# 7.35 -# stop: 7.36 -# Removes netdev from the bridge. 7.37 -# Deletes the routes to bridge and adds them to netdev. 7.38 -# 7.39 -# status: 7.40 -# Print ifconfig for netdev and bridge. 7.41 -# Print routes. 7.42 -# 7.43 -#============================================================================ 7.44 - 7.45 -# Exit if anything goes wrong. 7.46 -set -e 7.47 - 7.48 -# First arg is the operation. 7.49 -OP=$1 7.50 -shift 7.51 - 7.52 -# Pull variables in args in to environment. 7.53 -for arg ; do export "${arg}" ; done 7.54 - 7.55 -bridge=${bridge:-xen-br0} 7.56 -netdev=${netdev:-eth0} 7.57 -antispoof=${antispoof:-yes} 7.58 - 7.59 -echo "network $OP bridge=$bridge netdev=$netdev antispoof=$antispoof" 7.60 - 7.61 -# Usage: transfer_addrs src dst 7.62 -# Copy all IP addresses (including aliases) from device $src to device $dst. 7.63 -transfer_addrs () { 7.64 - local src=$1 7.65 - local dst=$2 7.66 - # Don't bother if $dst already has IP addresses. 7.67 - if ip addr show dev ${dst} | egrep -q '^ *inet' ; then 7.68 - return 7.69 - fi 7.70 - # Address lines start with 'inet' and have the device in them. 7.71 - # Replace 'inet' with 'ip addr add' and change the device name $src 7.72 - # to 'dev $src'. Remove netmask as we'll add routes later. 7.73 - ip addr show dev ${src} | egrep '^ *inet' | sed -e " 7.74 -s/inet/ip addr add/ 7.75 -s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)/[0-9]\+@\1@ 7.76 -s/${src}/dev ${dst}/ 7.77 -" | sh -e 7.78 -} 7.79 - 7.80 -# Usage: transfer_routes src dst 7.81 -# Get all IP routes to device $src, delete them, and 7.82 -# add the same routes to device $dst. 7.83 -# The original routes have to be deleted, otherwise adding them 7.84 -# for $dst fails (duplicate routes). 7.85 -transfer_routes () { 7.86 - local src=$1 7.87 - local dst=$2 7.88 - # List all routes and grep the ones with $src in. 7.89 - # Stick 'ip route del' on the front to delete. 7.90 - # Change $src to $dst and use 'ip route add' to add. 7.91 - ip route list | grep ${src} | sed -e " 7.92 -h 7.93 -s/^/ip route del / 7.94 -P 7.95 -g 7.96 -s/${src}/${dst}/ 7.97 -s/^/ip route add / 7.98 -P 7.99 -d 7.100 -" | sh -e 7.101 -} 7.102 - 7.103 -# Usage: create_bridge dev bridge 7.104 -# Create bridge $bridge and add device $dev to it. 7.105 -create_bridge () { 7.106 - local dev=$1 7.107 - local bridge=$2 7.108 +scriptdir=/etc/xen/scripts/ 7.109 7.110 - # Don't create the bridge if it already exists. 7.111 - if ! brctl show | grep -q ${bridge} ; then 7.112 - brctl addbr ${bridge} 7.113 - brctl stp ${bridge} off 7.114 - brctl setfd ${bridge} 0 7.115 - fi 7.116 - ifconfig ${bridge} up 7.117 -} 7.118 - 7.119 -# Usage: antispoofing dev bridge 7.120 -# Set the default forwarding policy for $dev to drop. 7.121 -# Allow forwarding to the bridge. 7.122 -antispoofing () { 7.123 - local dev=$1 7.124 - local bridge=$2 7.125 - 7.126 - iptables -P FORWARD DROP 7.127 - iptables -A FORWARD -m physdev --physdev-in ${dev} -j ACCEPT 7.128 -} 7.129 - 7.130 -# Usage: show_status dev bridge 7.131 -# Print ifconfig and routes. 7.132 -show_status () { 7.133 - local dev=$1 7.134 - local bridge=$2 7.135 - 7.136 - echo '============================================================' 7.137 - ifconfig ${dev} 7.138 - ifconfig ${bridge} 7.139 - echo ' ' 7.140 - ip route list 7.141 - echo ' ' 7.142 - route -n 7.143 - echo '============================================================' 7.144 -} 7.145 - 7.146 -# Insert the vnet module if it can be found and 7.147 -# it's not already there. 7.148 -vnet_insert () { 7.149 - local module="vnet_module" 7.150 - local mod_dir=/lib/modules/$(uname -r)/kernel 7.151 - local mod_path="${mod_dir}/${module}" 7.152 - local mod_obj="" 7.153 +case ${1} in 7.154 + start) 7.155 + ${scriptdir}/vnet-insert 7.156 + ;; 7.157 +esac 7.158 7.159 - for ext in ".o" ".ko" ; do 7.160 - f=${mod_path}${ext} 7.161 - if [ -f ${f} ] ; then 7.162 - mod_obj=$f 7.163 - break 7.164 - fi 7.165 - done 7.166 - if [ "${mod_obj}" == "" ] ; then 7.167 - return 7.168 - fi 7.169 - if lsmod | grep -q ${module} ; then 7.170 - echo "VNET: ${module} loaded" 7.171 - else 7.172 - echo "VNET: Loading ${module}..." 7.173 - insmod ${mod_obj} 7.174 - fi 7.175 -} 7.176 - 7.177 -op_start () { 7.178 - if [ "${bridge}" == "null" ] ; then 7.179 - return 7.180 - fi 7.181 - # Create the bridge and give it the interface IP addresses. 7.182 - # Move the interface routes onto the bridge. 7.183 - create_bridge ${netdev} ${bridge} 7.184 - transfer_addrs ${netdev} ${bridge} 7.185 - transfer_routes ${netdev} ${bridge} 7.186 - # Don't add $dev to $bridge if it's already on a bridge. 7.187 - if ! brctl show | grep -q ${netdev} ; then 7.188 - brctl addif ${bridge} ${netdev} 7.189 - fi 7.190 - 7.191 - if [ ${antispoof} == 'yes' ] ; then 7.192 - antispoofing ${netdev} ${bridge} 7.193 - fi 7.194 - 7.195 - vnet_insert 7.196 -} 7.197 - 7.198 -op_stop () { 7.199 - if [ "${bridge}" == "null" ] ; then 7.200 - return 7.201 - fi 7.202 - # Remove the interface from the bridge. 7.203 - # Move the routes back to the interface. 7.204 - brctl delif ${bridge} ${netdev} 7.205 - transfer_routes ${bridge} ${netdev} 7.206 - 7.207 - # It's not our place to be enabling forwarding... 7.208 -} 7.209 - 7.210 -case ${OP} in 7.211 - start) 7.212 - op_start 7.213 - ;; 7.214 - 7.215 - stop) 7.216 - op_stop 7.217 - ;; 7.218 - 7.219 - status) 7.220 - show_status ${netdev} ${bridge} 7.221 - ;; 7.222 - 7.223 - *) 7.224 - echo 'Unknown command: ' ${OP} 7.225 - echo 'Valid commands are: start, stop, status' 7.226 - exit 1 7.227 -esac 7.228 +${scriptdir}/network-bridge "$@"
8.1 --- a/tools/vnet/examples/vnet97.sxp Fri Aug 26 10:51:10 2005 +0000 8.2 +++ b/tools/vnet/examples/vnet97.sxp Fri Aug 26 10:52:53 2005 +0000 8.3 @@ -1,3 +1,2 @@ 8.4 # Vnet configuration for a vnet with id 97 and no security. 8.5 -# Configure using 'xm call vnet_add vnet97.sxp'. 8.6 (vnet (id 97) (bridge vnet97) (vnetif vnetif97) (security none))
9.1 --- a/tools/vnet/examples/vnet98.sxp Fri Aug 26 10:51:10 2005 +0000 9.2 +++ b/tools/vnet/examples/vnet98.sxp Fri Aug 26 10:52:53 2005 +0000 9.3 @@ -1,3 +1,2 @@ 9.4 # Vnet configuration for a vnet with id 98 and message authentication. 9.5 -# Configure using 'xm call vnet_add vnet98.sxp'. 9.6 (vnet (id 98) (bridge vnet98) (vnetif vnetif98) (security auth))
10.1 --- a/tools/vnet/examples/vnet99.sxp Fri Aug 26 10:51:10 2005 +0000 10.2 +++ b/tools/vnet/examples/vnet99.sxp Fri Aug 26 10:52:53 2005 +0000 10.3 @@ -1,3 +1,2 @@ 10.4 # Vnet configuration for a vnet with id 99 and message confidentiality. 10.5 -# Configure using 'xm call vnet_add vnet99.sxp'. 10.6 (vnet (id 99) (bridge vnet99) (vnetif vnetif99) (security conf))
11.1 --- a/tools/vnet/libxutil/Makefile Fri Aug 26 10:51:10 2005 +0000 11.2 +++ b/tools/vnet/libxutil/Makefile Fri Aug 26 10:52:53 2005 +0000 11.3 @@ -1,5 +1,8 @@ 11.4 +ifndef VNET_ROOT 11.5 +export VNET_ROOT = $(shell cd .. && pwd) 11.6 +include $(VNET_ROOT)/Make.env 11.7 +endif 11.8 11.9 -XEN_ROOT = ../../.. 11.10 INSTALL = install 11.11 INSTALL_DATA = $(INSTALL) -m0644 11.12 INSTALL_PROG = $(INSTALL) -m0755 11.13 @@ -15,6 +18,7 @@ LIB_SRCS += gzip_stream.c 11.14 LIB_SRCS += hash_table.c 11.15 LIB_SRCS += iostream.c 11.16 LIB_SRCS += lexis.c 11.17 +LIB_SRCS += mem_stream.c 11.18 LIB_SRCS += string_stream.c 11.19 LIB_SRCS += sxpr.c 11.20 LIB_SRCS += sxpr_parser.c 11.21 @@ -26,6 +30,7 @@ LIB_OBJS := $(LIB_SRCS:.c=.o) 11.22 PIC_OBJS := $(LIB_SRCS:.c=.opic) 11.23 11.24 CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing 11.25 +CFLAGS += -g 11.26 11.27 # Get gcc to generate the dependencies for us. 11.28 CFLAGS += -Wp,-MD,.$(@F).d 11.29 @@ -39,6 +44,7 @@ LIB += libxutil.so.$(MAJOR).$(MINOR 11.30 LIB += libxutil.a 11.31 11.32 all: build 11.33 + 11.34 build: check-for-zlib 11.35 $(MAKE) $(LIB) 11.36 11.37 @@ -70,8 +76,8 @@ install: build 11.38 ln -sf libxutil.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxutil.so 11.39 11.40 clean: 11.41 - $(RM) *.a *.so* *.o *.opic *.rpm 11.42 - $(RM) *~ 11.43 - $(RM) $(DEPS) 11.44 + -@$(RM) *.a *.so* *.o *.opic *.rpm 11.45 + -@$(RM) *~ 11.46 + -@$(RM) $(DEPS) 11.47 11.48 -include $(DEPS)
12.1 --- a/tools/vnet/libxutil/debug.h Fri Aug 26 10:51:10 2005 +0000 12.2 +++ b/tools/vnet/libxutil/debug.h Fri Aug 26 10:52:53 2005 +0000 12.3 @@ -49,9 +49,9 @@ 12.4 #ifdef DEBUG 12.5 12.6 #define dprintf(fmt, args...) fprintf(stdout, "%d [DBG] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args) 12.7 -#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args) 12.8 -#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args) 12.9 -#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args) 12.10 +#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args) 12.11 +#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args) 12.12 +#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args) 12.13 12.14 #else 12.15
13.1 --- a/tools/vnet/libxutil/sxpr.c Fri Aug 26 10:51:10 2005 +0000 13.2 +++ b/tools/vnet/libxutil/sxpr.c Fri Aug 26 10:52:53 2005 +0000 13.3 @@ -405,7 +405,6 @@ Sxpr setf(Sxpr k, Sxpr v, Sxpr l){ 13.4 #endif /* USE_GC */ 13.5 13.6 /** Create a new atom with the given name. 13.7 - * Makes an integer sxpr if the name can be parsed as an int. 13.8 * 13.9 * @param name the name 13.10 * @return new atom 13.11 @@ -414,7 +413,8 @@ Sxpr atom_new(char *name){ 13.12 Sxpr n, obj = ONOMEM; 13.13 long v; 13.14 13.15 - if(convert_atol(name, &v) == 0){ 13.16 + // Don't always want to do this. 13.17 + if(0 && convert_atol(name, &v) == 0){ 13.18 obj = OINT(v); 13.19 } else { 13.20 n = string_new(name);
14.1 --- a/tools/vnet/libxutil/sxpr.h Fri Aug 26 10:51:10 2005 +0000 14.2 +++ b/tools/vnet/libxutil/sxpr.h Fri Aug 26 10:52:53 2005 +0000 14.3 @@ -228,7 +228,9 @@ static inline Sxpr OBJP(int ty, void *va 14.4 * 14.5 * @param val pointer 14.6 */ 14.7 -#define PTR(val) OBJP(T_UINT, (void*)(val)) 14.8 +static inline Sxpr PTR(void *val){ 14.9 + return OBJP(T_UINT, (void*)(val)); 14.10 +} 14.11 14.12 /** Allocate some memory and return an sxpr containing it. 14.13 * Returns ONOMEM if allocation failed. 14.14 @@ -237,7 +239,9 @@ static inline Sxpr OBJP(int ty, void *va 14.15 * @param ty typecode 14.16 * @return sxpr 14.17 */ 14.18 -#define halloc(_n, _ty) OBJP(_ty, allocate(_n)) 14.19 +static inline Sxpr halloc(int n, int ty){ 14.20 + return OBJP(ty, allocate(n)); 14.21 +} 14.22 14.23 /** Allocate an sxpr containing a pointer to the given type. 14.24 *
15.1 --- a/tools/vnet/libxutil/sxpr_parser.c Fri Aug 26 10:51:10 2005 +0000 15.2 +++ b/tools/vnet/libxutil/sxpr_parser.c Fri Aug 26 10:52:53 2005 +0000 15.3 @@ -472,7 +472,14 @@ int Parser_intern(Parser *p){ 15.4 } 15.5 15.6 int Parser_atom(Parser *p){ 15.7 - Sxpr obj = atom_new(peek_token(p)); 15.8 + Sxpr obj; 15.9 + long v; 15.10 + if(Parser_flags(p, PARSE_INT) && 15.11 + convert_atol(peek_token(p), &v) == 0){ 15.12 + obj = OINT(v); 15.13 + } else { 15.14 + obj = atom_new(peek_token(p)); 15.15 + } 15.16 return Parser_set_value(p, obj); 15.17 } 15.18
16.1 --- a/tools/vnet/libxutil/sxpr_parser.h Fri Aug 26 10:51:10 2005 +0000 16.2 +++ b/tools/vnet/libxutil/sxpr_parser.h Fri Aug 26 10:52:53 2005 +0000 16.3 @@ -89,15 +89,17 @@ typedef enum { 16.4 16.5 16.6 /** Parser flags. */ 16.7 -//enum { 16.8 -//}; 16.9 +enum { 16.10 + /** Convert integer atoms to ints. */ 16.11 + PARSE_INT=1, 16.12 +}; 16.13 16.14 /** Raise some parser flags. 16.15 * 16.16 * @param in parser 16.17 * @param flags flags mask 16.18 */ 16.19 -inline static void Parser_flags_raise(Parser *in, int flags){ 16.20 +static inline void Parser_flags_raise(Parser *in, int flags){ 16.21 in->flags |= flags; 16.22 } 16.23 16.24 @@ -106,7 +108,7 @@ inline static void Parser_flags_raise(Pa 16.25 * @param in parser 16.26 * @param flags flags mask 16.27 */ 16.28 -inline static void Parser_flags_lower(Parser *in, int flags){ 16.29 +static inline void Parser_flags_lower(Parser *in, int flags){ 16.30 in->flags &= ~flags; 16.31 } 16.32 16.33 @@ -114,10 +116,14 @@ inline static void Parser_flags_lower(Pa 16.34 * 16.35 * @param in parser 16.36 */ 16.37 -inline static void Parser_flags_clear(Parser *in){ 16.38 +static inline void Parser_flags_clear(Parser *in){ 16.39 in->flags = 0; 16.40 } 16.41 16.42 +static inline int Parser_flags(Parser *in, int flags){ 16.43 + return in->flags & flags; 16.44 +} 16.45 + 16.46 extern void Parser_free(Parser *z); 16.47 extern Parser * Parser_new(void); 16.48 extern int Parser_input(Parser *p, char *buf, int buf_n);
17.1 --- a/tools/vnet/libxutil/sys_string.c Fri Aug 26 10:51:10 2005 +0000 17.2 +++ b/tools/vnet/libxutil/sys_string.c Fri Aug 26 10:52:53 2005 +0000 17.3 @@ -28,6 +28,31 @@ 17.4 #include "allocate.h" 17.5 #include "sys_string.h" 17.6 17.7 +#ifdef __KERNEL__ 17.8 + 17.9 +#define deferr(_err) case _err: return #_err 17.10 + 17.11 +extern char *strerror(int err) 17.12 +{ 17.13 + switch(err){ 17.14 + deferr(EPERM); 17.15 + deferr(ENOENT); 17.16 + deferr(ESRCH); 17.17 + deferr(EINTR); 17.18 + deferr(EIO); 17.19 + deferr(EINVAL); 17.20 + deferr(ENOMEM); 17.21 + deferr(EACCES); 17.22 + deferr(EFAULT); 17.23 + deferr(EBUSY); 17.24 + 17.25 + default: 17.26 + return "ERROR"; 17.27 + } 17.28 +} 17.29 + 17.30 +#endif 17.31 + 17.32 /** Set the base to use for converting a string to a number. Base is 17.33 * hex if starts with 0x, otherwise decimal. 17.34 *
18.1 --- a/tools/vnet/libxutil/sys_string.h Fri Aug 26 10:51:10 2005 +0000 18.2 +++ b/tools/vnet/libxutil/sys_string.h Fri Aug 26 10:52:53 2005 +0000 18.3 @@ -32,6 +32,8 @@ 18.4 #include <stdarg.h> 18.5 #include "allocate.h" 18.6 18.7 +extern char *strerror(int err); 18.8 + 18.9 #if 0 18.10 static inline int tolower(int c){ 18.11 return (c>='A' && c<='Z' ? (c-'A')+'a' : c);
19.1 --- a/tools/vnet/vnet-module/00README Fri Aug 26 10:51:10 2005 +0000 19.2 +++ b/tools/vnet/vnet-module/00README Fri Aug 26 10:52:53 2005 +0000 19.3 @@ -6,11 +6,11 @@ The vnet module can be compiled for 2.4 19.4 The makefiles use the following variables, which 19.5 can be set in your env or on the make command line: 19.6 19.7 -LINUX_SERIES: linux release to compile for, 2.4 (default), or 2.6. 19.8 -XEN_ROOT: root of the xen tree containing kernel source. 19.9 +LINUX_SERIES: linux release to compile for: 2.4, or 2.6 (default). 19.10 +XEN_ROOT: root of the xen tree containing kernel source. 19.11 KERNEL_VERSION: kernel version, default got from XEN_ROOT. 19.12 -KERNEL_MINOR: kernel minor version, default -xen0. 19.13 -KERNEL_SRC: path to kernel source, default linux-<VERSION> under XEN_ROOT. 19.14 +KERNEL_MINOR: kernel minor version, default -xen0. 19.15 +KERNEL_SRC: path to kernel source, default linux-<VERSION> under XEN_ROOT. 19.16 19.17 *) For 2.4 kernel 19.18
20.1 --- a/tools/vnet/vnet-module/Makefile Fri Aug 26 10:51:10 2005 +0000 20.2 +++ b/tools/vnet/vnet-module/Makefile Fri Aug 26 10:52:53 2005 +0000 20.3 @@ -18,9 +18,13 @@ 20.4 # 59 Temple Place, suite 330, Boston, MA 02111-1307 USA 20.5 #============================================================================ 20.6 20.7 +ifndef VNET_ROOT 20.8 +export VNET_ROOT = $(shell cd .. && pwd) 20.9 +include $(VNET_ROOT)/Make.env 20.10 +endif 20.11 + 20.12 #============================================================================ 20.13 ifeq ($(src),) 20.14 -LINUX_SERIES ?=2.6 20.15 20.16 include Makefile-$(LINUX_SERIES) 20.17 20.18 @@ -45,7 +49,7 @@ vnet_module-objs += $(VNET_LIB_OBJ) 20.19 # Setup explicit rules for them using the kbuild C compile rule. 20.20 20.21 # File names in the lib dir. 20.22 -remote_srcs = $(foreach file,$(VNET_LIB_SRC),$(LIB_DIR)/$(file)) 20.23 +remote_srcs = $(foreach file,$(VNET_LIB_SRC),$(LIBXUTIL_DIR)/$(file)) 20.24 20.25 # Equivalent file names here. 20.26 local_srcs = $(foreach file,$(VNET_LIB_SRC),$(src)/$(file)) 20.27 @@ -54,12 +58,12 @@ local_srcs = $(foreach file,$(VNET_LIB_S 20.28 local_objs = $(local_srcs:.c=.o) 20.29 20.30 # Make the local objects depend on compiling the remote sources. 20.31 -$(local_objs): $(src)/%.o: $(LIB_DIR)/%.c 20.32 +$(local_objs): $(src)/%.o: $(LIBXUTIL_DIR)/%.c 20.33 $(call if_changed_rule,cc_o_c) 20.34 #---------------------------------------------------------------------------- 20.35 20.36 -vpath %.h $(LIB_DIR) 20.37 -EXTRA_CFLAGS += -I $(LIB_DIR) 20.38 +vpath %.h $(LIBXUTIL_DIR) 20.39 +EXTRA_CFLAGS += -I $(LIBXUTIL_DIR) 20.40 EXTRA_CFLAGS += -I $(src) 20.41 20.42 endif
21.1 --- a/tools/vnet/vnet-module/Makefile-2.4 Fri Aug 26 10:51:10 2005 +0000 21.2 +++ b/tools/vnet/vnet-module/Makefile-2.4 Fri Aug 26 10:52:53 2005 +0000 21.3 @@ -21,7 +21,7 @@ 21.4 #============================================================================ 21.5 # Vnet module makefile for 2.4 series kernels. 21.6 21.7 -LINUX_SERIES ?=2.4 21.8 +LINUX_SERIES =2.4 21.9 include Makefile.ver 21.10 21.11 KERNEL_MODULE := vnet_module.o 21.12 @@ -37,9 +37,9 @@ VNET_OBJ += $(VNET_LIB_OBJ) 21.13 vpath %.h $(KERNEL_SRC)/include 21.14 INCLUDES+= -I $(KERNEL_SRC)/include 21.15 21.16 -vpath %.h $(LIB_DIR) 21.17 -vpath %.c $(LIB_DIR) 21.18 -INCLUDES += -I $(LIB_DIR) 21.19 +vpath %.h $(LIBXUTIL_DIR) 21.20 +vpath %.c $(LIBXUTIL_DIR) 21.21 +INCLUDES += -I $(LIBXUTIL_DIR) 21.22 21.23 INCLUDES+= -I . 21.24 21.25 @@ -61,6 +61,7 @@ CFLAGS += -Wno-trigraphs 21.26 CFLAGS += -Wno-unused-function 21.27 CFLAGS += -Wno-unused-parameter 21.28 21.29 +CFLAGS += -g 21.30 CFLAGS += -O2 21.31 CFLAGS += -fno-strict-aliasing 21.32 CFLAGS += -fno-common 21.33 @@ -90,8 +91,8 @@ TAGS: 21.34 21.35 .PHONY: clean 21.36 clean: 21.37 - @rm -f *.a *.o *.ko *~ 21.38 - @rm -f $(VNET_DEP) .*.cmd *.mod.? 21.39 - @rm -rf .tmp_versions 21.40 + -@$(RM) *.a *.o *.ko *~ 21.41 + -@$(RM) $(VNET_DEP) .*.cmd *.mod.? 21.42 + -@$(RM) -r .tmp_versions 21.43 21.44 -include $(VNET_DEP)
22.1 --- a/tools/vnet/vnet-module/Makefile-2.6 Fri Aug 26 10:51:10 2005 +0000 22.2 +++ b/tools/vnet/vnet-module/Makefile-2.6 Fri Aug 26 10:52:53 2005 +0000 22.3 @@ -21,7 +21,7 @@ 22.4 #============================================================================ 22.5 # Vnet module makefile for 2.6 series kernels. 22.6 22.7 -LINUX_SERIES ?=2.6 22.8 +LINUX_SERIES =2.6 22.9 include Makefile.ver 22.10 22.11 KERNEL_MODULE = vnet_module.ko 22.12 @@ -38,13 +38,14 @@ module modules: 22.13 22.14 .PHONY: install install-module modules_install 22.15 install install-module modules_install: module 22.16 - install -m 0755 -d $(DESTDIR)$(KERNEL_MODULE_DIR)/xen 22.17 - install -m 0554 $(KERNEL_MODULE) $(DESTDIR)$(KERNEL_MODULE_DIR)/xen 22.18 + install -m 0755 -d $(DESTDIR)$(KERNEL_MODULE_DIR) 22.19 + install -m 0554 $(KERNEL_MODULE) $(DESTDIR)$(KERNEL_MODULE_DIR) 22.20 22.21 .PHONY: clean 22.22 clean: 22.23 - @$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean 22.24 - @rm -f *.a *.o *.ko *~ .*.d .*.cmd *.mod.? 22.25 + -@$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean 22.26 + -@$(RM) *.a *.o *.ko *~ .*.d .*.cmd *.mod.? 22.27 + -@$(RM) -r .tmp_versions 22.28 22.29 TAGS: 22.30 etags *.c *.h
23.1 --- a/tools/vnet/vnet-module/Makefile.ver Fri Aug 26 10:51:10 2005 +0000 23.2 +++ b/tools/vnet/vnet-module/Makefile.ver Fri Aug 26 10:52:53 2005 +0000 23.3 @@ -18,22 +18,11 @@ 23.4 # 59 Temple Place, suite 330, Boston, MA 02111-1307 USA 23.5 #============================================================================ 23.6 23.7 -#---------------------------------------------------------------------------- 23.8 -# Xeno/xen. 23.9 - 23.10 -# Root of xen tree. 23.11 -XEN_ROOT ?=../../.. 23.12 - 23.13 -# Path to relativize the install. Set to / 23.14 -# to install relative to filesystem root. 23.15 -prefix ?=$(XEN_ROOT)/install/ 23.16 -#---------------------------------------------------------------------------- 23.17 - 23.18 LINUX_SERIES ?=2.6 23.19 KERNEL_MINOR ?=-xen0 23.20 23.21 -LINUX_VERSION ?= $(shell ( /bin/ls -ld $(XEN_ROOT)/linux-$(LINUX_SERIES).*-xen-sparse ) 2>/dev/null | \ 23.22 - sed -e 's!^.*linux-\(.\+\)-xen-sparse!\1!' ) 23.23 +LINUX_VERSION ?= $(shell ( /bin/ls -ld $(XEN_ROOT)/linux-$(LINUX_SERIES).*-xen0 ) 2>/dev/null | \ 23.24 + sed -e 's!^.*linux-\(.\+\)-xen0!\1!' ) 23.25 23.26 ifeq ($(LINUX_VERSION),) 23.27 $(error Kernel source for linux $(LINUX_SERIES) not found)
24.1 --- a/tools/vnet/vnet-module/Makefile.vnet Fri Aug 26 10:51:10 2005 +0000 24.2 +++ b/tools/vnet/vnet-module/Makefile.vnet Fri Aug 26 10:52:53 2005 +0000 24.3 @@ -24,8 +24,6 @@ else 24.4 SRC_DIR=$(src)/ 24.5 endif 24.6 24.7 -LIB_DIR := $(SRC_DIR)../libxutil 24.8 - 24.9 VNET_SRC := 24.10 VNET_SRC += esp.c 24.11 VNET_SRC += etherip.c
25.1 --- a/tools/vnet/vnet-module/etherip.c Fri Aug 26 10:51:10 2005 +0000 25.2 +++ b/tools/vnet/vnet-module/etherip.c Fri Aug 26 10:52:53 2005 +0000 25.3 @@ -42,6 +42,7 @@ 25.4 #include <vnet.h> 25.5 #include <varp.h> 25.6 #include <if_varp.h> 25.7 +#include <varp.h> 25.8 #include <skb_util.h> 25.9 25.10 #define MODULE_NAME "VNET" 25.11 @@ -53,22 +54,18 @@ 25.12 * The etherip protocol is used to transport Ethernet frames in IP packets. 25.13 */ 25.14 25.15 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 25.16 -#define MAC_ETH(_skb) ((struct ethhdr *)(_skb)->mac.raw) 25.17 -#else 25.18 -#define MAC_ETH(_skb) ((_skb)->mac.ethernet) 25.19 -#endif 25.20 - 25.21 /** Get the vnet label from an etherip header. 25.22 * 25.23 * @param hdr header 25.24 - * @return vnet (in host order) 25.25 + * @@param vnet (in net order) 25.26 */ 25.27 -int etheriphdr_get_vnet(struct etheriphdr *hdr){ 25.28 +void etheriphdr_get_vnet(struct etheriphdr *hdr, VnetId *vnet){ 25.29 #ifdef CONFIG_ETHERIP_EXT 25.30 - return ntohl(hdr->vnet); 25.31 + *vnet = *(VnetId*)hdr->vnet; 25.32 #else 25.33 - return hdr->reserved; 25.34 + *vnet = (VnetId){}; 25.35 + vnet->u.vnet16[7] = (unsigned short)hdr->reserved; 25.36 + 25.37 #endif 25.38 } 25.39 25.40 @@ -76,15 +73,15 @@ int etheriphdr_get_vnet(struct etheriphd 25.41 * Also sets the etherip version. 25.42 * 25.43 * @param hdr header 25.44 - * @param vnet vnet label (in host order) 25.45 + * @param vnet vnet label (in net order) 25.46 */ 25.47 -void etheriphdr_set_vnet(struct etheriphdr *hdr, int vnet){ 25.48 +void etheriphdr_set_vnet(struct etheriphdr *hdr, VnetId *vnet){ 25.49 #ifdef CONFIG_ETHERIP_EXT 25.50 - hdr->version = 4; 25.51 - hdr->vnet = htonl(vnet); 25.52 + hdr->version = ETHERIP_VERSION; 25.53 + *(VnetId*)hdr->vnet = *vnet; 25.54 #else 25.55 - hdr->version = 3; 25.56 - hdr->reserved = vnet & 0x0fff; 25.57 + hdr->version = ETHERIP_VERSION; 25.58 + hdr->reserved = (vnet->u.vnet16[7] & 0x0fff); 25.59 #endif 25.60 } 25.61 25.62 @@ -119,12 +116,12 @@ static int etherip_tunnel_send(Tunnel *t 25.63 const int ip_n = sizeof(struct iphdr); 25.64 const int eth_n = ETH_HLEN; 25.65 int head_n = 0; 25.66 - int vnet = tunnel->key.vnet; 25.67 + VnetId *vnet = &tunnel->key.vnet; 25.68 struct etheriphdr *etheriph; 25.69 struct ethhdr *ethh; 25.70 u32 saddr = 0; 25.71 25.72 - dprintf("> skb=%p vnet=%d\n", skb, vnet); 25.73 + //dprintf("> skb=%p vnet=%d\n", skb, vnet); 25.74 head_n = etherip_n + ip_n + eth_n; 25.75 err = skb_make_room(&skb, skb, head_n, 0); 25.76 if(err) goto exit; 25.77 @@ -133,7 +130,7 @@ static int etherip_tunnel_send(Tunnel *t 25.78 //if(err) goto exit; 25.79 25.80 // The original ethernet header. 25.81 - ethh = MAC_ETH(skb); 25.82 + ethh = eth_hdr(skb); 25.83 //print_skb_data(__FUNCTION__, 0, skb, skb->mac.raw, skb->len); 25.84 // Null the pointer as we are pushing a new IP header. 25.85 skb->mac.raw = NULL; 25.86 @@ -155,7 +152,7 @@ static int etherip_tunnel_send(Tunnel *t 25.87 skb->nh.iph->ttl = 64; // Linux default time-to-live. 25.88 skb->nh.iph->protocol = IPPROTO_ETHERIP; // IP protocol number. 25.89 skb->nh.iph->saddr = saddr; // Source address. 25.90 - skb->nh.iph->daddr = tunnel->key.addr; // Destination address. 25.91 + skb->nh.iph->daddr = tunnel->key.addr.u.ip4.s_addr; // Destination address. 25.92 skb->nh.iph->check = 0; 25.93 25.94 // Ethernet header will be filled-in by device. 25.95 @@ -213,15 +210,18 @@ static int etherip_protocol_recv(struct 25.96 struct etheriphdr *etheriph; 25.97 struct ethhdr *ethhdr; 25.98 Vnet *vinfo = NULL; 25.99 - u32 vnet; 25.100 + VnetId vnet = {}; 25.101 + u32 saddr, daddr; 25.102 + char vnetbuf[VNET_ID_BUF]; 25.103 25.104 - ethhdr = MAC_ETH(skb); 25.105 - if(MULTICAST(skb->nh.iph->daddr) && 25.106 - (skb->nh.iph->daddr != varp_mcast_addr)){ 25.107 + saddr = skb->nh.iph->saddr; 25.108 + daddr = skb->nh.iph->daddr; 25.109 + ethhdr = eth_hdr(skb); 25.110 + if(MULTICAST(daddr) && (daddr != varp_mcast_addr)){ 25.111 // Ignore multicast packets not addressed to us. 25.112 - dprintf("> dst=%u.%u.%u.%u varp_mcast_addr=%u.%u.%u.%u\n", 25.113 - NIPQUAD(skb->nh.iph->daddr), 25.114 - NIPQUAD(varp_mcast_addr)); 25.115 + dprintf("> Ignoring mcast skb: src=%u.%u.%u.%u dst=%u.%u.%u.%u" 25.116 + " varp_mcast_addr=%u.%u.%u.%u\n", 25.117 + NIPQUAD(saddr), NIPQUAD(daddr), NIPQUAD(varp_mcast_addr)); 25.118 goto exit; 25.119 } 25.120 ip_n = (skb->nh.iph->ihl << 2); 25.121 @@ -229,7 +229,8 @@ static int etherip_protocol_recv(struct 25.122 // skb->data points at ethernet header. 25.123 //dprintf("> len=%d\n", skb->len); 25.124 if (!pskb_may_pull(skb, eth_n + ip_n)){ 25.125 - wprintf("> Malformed skb\n"); 25.126 + wprintf("> Malformed skb (eth+ip) src=%u.%u.%u.%u\n", 25.127 + NIPQUAD(saddr)); 25.128 err = -EINVAL; 25.129 goto exit; 25.130 } 25.131 @@ -237,18 +238,30 @@ static int etherip_protocol_recv(struct 25.132 } 25.133 // Assume skb->data points at etherip header. 25.134 etheriph = (void*)skb->data; 25.135 - if(!pskb_may_pull(skb, etherip_n)){ 25.136 - wprintf("> Malformed skb\n"); 25.137 + if(etheriph->version != ETHERIP_VERSION){ 25.138 + wprintf("> Bad etherip version=%d src=%u.%u.%u.%u\n", 25.139 + etheriph->version, 25.140 + NIPQUAD(saddr)); 25.141 err = -EINVAL; 25.142 goto exit; 25.143 } 25.144 - vnet = etheriphdr_get_vnet(etheriph); 25.145 - dprintf("> Rcvd skb=%p vnet=%d\n", skb, vnet); 25.146 + if(!pskb_may_pull(skb, etherip_n)){ 25.147 + wprintf("> Malformed skb (etherip) src=%u.%u.%u.%u\n", 25.148 + NIPQUAD(saddr)); 25.149 + err = -EINVAL; 25.150 + goto exit; 25.151 + } 25.152 + etheriphdr_get_vnet(etheriph, &vnet); 25.153 + dprintf("> Rcvd skb vnet=%s src=%u.%u.%u.%u\n", 25.154 + VnetId_ntoa(&vnet, vnetbuf), 25.155 + NIPQUAD(saddr)); 25.156 // If vnet is secure, context must include IPSEC ESP. 25.157 - err = vnet_check_context(vnet, SKB_CONTEXT(skb), &vinfo); 25.158 + err = vnet_check_context(&vnet, SKB_CONTEXT(skb), &vinfo); 25.159 Vnet_decref(vinfo); 25.160 if(err){ 25.161 - wprintf("> Failed security check\n"); 25.162 + wprintf("> Failed security check vnet=%s src=%u.%u.%u.%u\n", 25.163 + VnetId_ntoa(&vnet, vnetbuf), 25.164 + NIPQUAD(saddr)); 25.165 goto exit; 25.166 } 25.167 mine = 1; 25.168 @@ -258,19 +271,29 @@ static int etherip_protocol_recv(struct 25.169 // Know source ip, vnet, vmac, so could update varp cache. 25.170 // But if traffic comes to us over a vnetd tunnel this points the coa 25.171 // at the vnetd rather than the endpoint. So don't do it. 25.172 - //varp_update(htonl(vnet), MAC_ETH(skb)->h_source, skb->nh.iph->saddr); 25.173 + //varp_update(vnet, eth_hdr(skb)->h_source, skb->nh.iph->saddr); 25.174 25.175 // Assuming a standard Ethernet frame. 25.176 + // Should check for protocol? Support ETH_P_8021Q too. 25.177 skb->nh.raw = skb_pull(skb, ETH_HLEN); 25.178 25.179 + dprintf("> Unpacked vnet=%s srcmac=" MACFMT " dstmac=" MACFMT "\n", 25.180 + VnetId_ntoa(&vnet, vnetbuf), 25.181 + MAC6TUPLE(eth_hdr(skb)->h_source), 25.182 + MAC6TUPLE(eth_hdr(skb)->h_dest)); 25.183 + 25.184 #ifdef CONFIG_NETFILTER 25.185 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) 25.186 // This stops our new pkt header being clobbered by a subsequent 25.187 - // call to nf_bridge_maybe_copy_header. Just replicate the 25.188 - // corresponding nf_bridge_save_header. 25.189 + // call to nf_bridge_maybe_copy_header. 25.190 + // Code from nf_bridge_save_header() modidifed to use h_proto 25.191 + // instead of skb->protocol. 25.192 if(skb->nf_bridge){ 25.193 + // Hmm. Standard ethernet header is ETH_HLEN (14), 25.194 + // VLAN header (802.1q) is VLAN_ETH_HLEN (18). 25.195 + // Where does 16 come from? 25.196 int header_size = 16; 25.197 - if(MAC_ETH(skb)->h_proto == __constant_htons(ETH_P_8021Q)) { 25.198 + if(eth_hdr(skb)->h_proto == __constant_htons(ETH_P_8021Q)) { 25.199 header_size = 18; 25.200 } 25.201 memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); 25.202 @@ -279,7 +302,7 @@ static int etherip_protocol_recv(struct 25.203 #endif 25.204 25.205 if(1){ 25.206 - struct ethhdr *eth = MAC_ETH(skb); 25.207 + struct ethhdr *eth = eth_hdr(skb); 25.208 // Devices use eth_type_trans() to set skb->pkt_type and skb->protocol. 25.209 // Set them from contained ethhdr, or leave as received? 25.210 // 'Ware use of hard_header_len in eth_type_trans(). 25.211 @@ -310,6 +333,7 @@ static int etherip_protocol_recv(struct 25.212 } 25.213 dst_release(skb->dst); 25.214 skb->dst = NULL; 25.215 + 25.216 #ifdef CONFIG_NETFILTER 25.217 nf_conntrack_put(skb->nfct); 25.218 skb->nfct = NULL; 25.219 @@ -321,7 +345,7 @@ static int etherip_protocol_recv(struct 25.220 25.221 //print_skb_data(__FUNCTION__, 0, skb, skb->mac.raw, skb->len + ETH_HLEN); 25.222 25.223 - err = vnet_skb_recv(skb, vnet, (Vmac*)MAC_ETH(skb)->h_dest); 25.224 + err = vnet_skb_recv(skb, &vnet, (Vmac*)eth_hdr(skb)->h_dest); 25.225 exit: 25.226 if(mine) err = 1; 25.227 dprintf("< skb=%p err=%d\n", skb, err);
26.1 --- a/tools/vnet/vnet-module/if_etherip.h Fri Aug 26 10:51:10 2005 +0000 26.2 +++ b/tools/vnet/vnet-module/if_etherip.h Fri Aug 26 10:52:53 2005 +0000 26.3 @@ -18,15 +18,30 @@ 26.4 */ 26.5 #ifndef _VNET_IF_ETHERIP_H_ 26.6 #define _VNET_IF_ETHERIP_H_ 26.7 -/*----------------------------------------------------------------------------*/ 26.8 + 26.9 +#define CONFIG_ETHERIP_EXT 26.10 + 26.11 #ifdef CONFIG_ETHERIP_EXT 26.12 + 26.13 +#define ETHERIP_VERSION 4 26.14 + 26.15 struct etheriphdr { 26.16 - __u8 version; 26.17 - __u32 vnet; 26.18 +#if defined(__LITTLE_ENDIAN_BITFIELD) 26.19 + __u16 reserved:12, 26.20 + version:4; 26.21 +#elif defined (__BIG_ENDIAN_BITFIELD) 26.22 + __u16 version:4, 26.23 + reserved:12; 26.24 +#else 26.25 +#error "Please fix <asm/byteorder.h>" 26.26 +#endif 26.27 + __u8 vnet[16]; 26.28 } __attribute__ ((packed)); 26.29 26.30 -/*----------------------------------------------------------------------------*/ 26.31 #else 26.32 + 26.33 +#define ETHERIP_VERSION 3 26.34 + 26.35 struct etheriphdr 26.36 { 26.37 #if defined(__LITTLE_ENDIAN_BITFIELD) 26.38 @@ -42,10 +57,9 @@ struct etheriphdr 26.39 }; 26.40 #endif 26.41 26.42 + 26.43 #ifndef IPPROTO_ETHERIP 26.44 #define IPPROTO_ETHERIP 97 26.45 #endif 26.46 26.47 -/*----------------------------------------------------------------------------*/ 26.48 - 26.49 #endif /* ! _VNET_IF_ETHERIP_H_ */
27.1 --- a/tools/vnet/vnet-module/if_varp.h Fri Aug 26 10:51:10 2005 +0000 27.2 +++ b/tools/vnet/vnet-module/if_varp.h Fri Aug 26 10:52:53 2005 +0000 27.3 @@ -20,6 +20,14 @@ 27.4 #ifndef _VNET_IF_VARP_H 27.5 #define _VNET_IF_VARP_H 27.6 27.7 +/* Need struct in_addr, struct in6_addr. */ 27.8 +#ifdef __KERNEL__ 27.9 +#include <linux/in.h> 27.10 +#include <linux/in6.h> 27.11 +#else 27.12 +#include <netinet/in.h> 27.13 +#endif 27.14 + 27.15 typedef struct Vmac { 27.16 unsigned char mac[ETH_ALEN]; 27.17 } Vmac; 27.18 @@ -30,24 +38,40 @@ enum { 27.19 VARP_OP_ANNOUNCE = 2, 27.20 }; 27.21 27.22 +typedef struct VnetId { 27.23 + union { 27.24 + uint8_t vnet8[16]; 27.25 + uint16_t vnet16[8]; 27.26 + uint32_t vnet32[4]; 27.27 + } u; 27.28 +} __attribute__((packed)) VnetId; 27.29 + 27.30 +typedef struct VarpAddr { 27.31 + uint8_t family; // AF_INET or AF_INET6. 27.32 + union { 27.33 + uint8_t raw[16]; 27.34 + struct in_addr ip4; 27.35 + struct in6_addr ip6; 27.36 + } u; 27.37 +} __attribute__((packed)) VarpAddr; 27.38 + 27.39 typedef struct VnetMsgHdr { 27.40 uint16_t id; 27.41 uint16_t opcode; 27.42 } __attribute__((packed)) VnetMsgHdr; 27.43 27.44 typedef struct VarpHdr { 27.45 - VnetMsgHdr vnetmsghdr; 27.46 - uint32_t vnet; 27.47 - Vmac vmac; 27.48 - uint32_t addr; 27.49 + VnetMsgHdr hdr; 27.50 + VnetId vnet; 27.51 + Vmac vmac; 27.52 + VarpAddr addr; 27.53 } __attribute__((packed)) VarpHdr; 27.54 27.55 + 27.56 /** Default address for varp/vnet broadcasts: 224.10.0.1 */ 27.57 #define VARP_MCAST_ADDR 0xe00a0001 27.58 27.59 /** UDP port to use for varp protocol. */ 27.60 #define VARP_PORT 1798 27.61 27.62 - 27.63 - 27.64 -#endif /* ! _VNET_IF_VARP_H */ 27.65 +#endif /* ! _VNET_IF_VARP_H */
28.1 --- a/tools/vnet/vnet-module/skb_util.h Fri Aug 26 10:51:10 2005 +0000 28.2 +++ b/tools/vnet/vnet-module/skb_util.h Fri Aug 26 10:52:53 2005 +0000 28.3 @@ -19,7 +19,9 @@ 28.4 #ifndef _VNET_SKB_UTIL_H_ 28.5 #define _VNET_SKB_UTIL_H_ 28.6 28.7 -struct sk_buff; 28.8 +#include <net/route.h> 28.9 +#include <linux/skbuff.h> 28.10 + 28.11 struct scatterlist; 28.12 28.13 extern int skb_make_room(struct sk_buff **pskb, struct sk_buff *skb, int head_n, int tail_n); 28.14 @@ -40,4 +42,53 @@ extern int skb_scatterlist(struct sk_buf 28.15 extern void print_skb_data(char *msg, int count, struct sk_buff *skb, u8 *data, int len); 28.16 28.17 28.18 +/* The mac.ethernet field went away in 2.6 in favour of eth_hdr(). 28.19 + */ 28.20 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 28.21 +#else 28.22 +static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) 28.23 +{ 28.24 + return (struct ethhdr *)skb->mac.raw; 28.25 +} 28.26 #endif 28.27 + 28.28 + 28.29 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 28.30 + 28.31 +static inline int skb_route(struct sk_buff *skb, struct rtable **prt){ 28.32 + int err = 0; 28.33 + struct flowi fl = { 28.34 + .nl_u = { 28.35 + .ip4_u = { 28.36 + .daddr = skb->nh.iph->daddr, 28.37 + .saddr = skb->nh.iph->saddr, 28.38 + .tos = skb->nh.iph->tos, 28.39 + } 28.40 + } 28.41 + }; 28.42 + 28.43 + if(skb->dev){ 28.44 + fl.oif = skb->dev->ifindex; 28.45 + } 28.46 + err = ip_route_output_key(prt, &fl); 28.47 + return err; 28.48 +} 28.49 + 28.50 +#else 28.51 + 28.52 +static inline int skb_route(struct sk_buff *skb, struct rtable **prt){ 28.53 + int err = 0; 28.54 + struct rt_key key = { }; 28.55 + key.dst = skb->nh.iph->daddr; 28.56 + key.src = skb->nh.iph->saddr; 28.57 + key.tos = skb->nh.iph->tos; 28.58 + if(skb->dev){ 28.59 + key.oif = skb->dev->ifindex; 28.60 + } 28.61 + err = ip_route_output_key(prt, &key); 28.62 + return err; 28.63 +} 28.64 + 28.65 +#endif 28.66 + 28.67 +#endif
29.1 --- a/tools/vnet/vnet-module/tunnel.c Fri Aug 26 10:51:10 2005 +0000 29.2 +++ b/tools/vnet/vnet-module/tunnel.c Fri Aug 26 10:52:53 2005 +0000 29.3 @@ -36,7 +36,7 @@ 29.4 #include "hash_table.h" 29.5 29.6 #define MODULE_NAME "VNET" 29.7 -//#define DEBUG 1 29.8 +#define DEBUG 1 29.9 #undef DEBUG 29.10 #include "debug.h" 29.11 29.12 @@ -56,11 +56,9 @@ void Tunnel_print(Tunnel *tunnel){ 29.13 } 29.14 } 29.15 29.16 -int Tunnel_create(TunnelType *type, u32 vnet, u32 addr, Tunnel *base, Tunnel **val){ 29.17 +int Tunnel_create(TunnelType *type, VnetId *vnet, VarpAddr *addr, Tunnel *base, Tunnel **val){ 29.18 int err = 0; 29.19 Tunnel *tunnel = NULL; 29.20 - dprintf("> type=%s vnet=%d addr=" IPFMT " base=%s\n", 29.21 - type->name, vnet, NIPQUAD(addr), (base ? base->type->name : "ip")); 29.22 if(!type || !type->open || !type->send || !type->close){ 29.23 err = -EINVAL; 29.24 goto exit; 29.25 @@ -71,8 +69,8 @@ int Tunnel_create(TunnelType *type, u32 29.26 goto exit; 29.27 } 29.28 atomic_set(&tunnel->refcount, 1); 29.29 - tunnel->key.vnet = vnet; 29.30 - tunnel->key.addr = addr; 29.31 + tunnel->key.vnet = *vnet; 29.32 + tunnel->key.addr = *addr; 29.33 tunnel->type = type; 29.34 tunnel->data = NULL; 29.35 tunnel->send_stats = (TunnelStats){}; 29.36 @@ -89,7 +87,7 @@ int Tunnel_create(TunnelType *type, u32 29.37 return err; 29.38 } 29.39 29.40 -int Tunnel_open(TunnelType *type, u32 vnet, u32 addr, Tunnel *base, Tunnel **tunnel){ 29.41 +int Tunnel_open(TunnelType *type, VnetId *vnet, VarpAddr *addr, Tunnel *base, Tunnel **tunnel){ 29.42 int err = 0; 29.43 29.44 dprintf(">\n"); 29.45 @@ -123,15 +121,16 @@ HashTable *tunnel_table = NULL; 29.46 static inline Hashcode tunnel_table_key_hash_fn(void *k){ 29.47 TunnelKey *key = k; 29.48 Hashcode h = 0; 29.49 - h = hash_2ul(key->vnet, key->addr); 29.50 + h = VnetId_hash(h, &key->vnet); 29.51 + h = VarpAddr_hash(h, &key->addr); 29.52 return h; 29.53 } 29.54 29.55 static int tunnel_table_key_equal_fn(void *k1, void *k2){ 29.56 TunnelKey *key1 = k1; 29.57 TunnelKey *key2 = k2; 29.58 - return (key1->vnet == key2->vnet) 29.59 - && (key1->addr == key2->addr); 29.60 + return VnetId_eq(&key1->vnet, &key2->vnet) && 29.61 + VarpAddr_eq(&key1->addr, &key2->addr); 29.62 } 29.63 29.64 static void tunnel_table_entry_free_fn(HashTable *table, HTEntry *entry){ 29.65 @@ -165,9 +164,9 @@ int Tunnel_init(void){ 29.66 * @param addr destination address 29.67 * @return tunnel state or NULL 29.68 */ 29.69 -Tunnel * Tunnel_lookup(u32 vnet, u32 addr){ 29.70 +Tunnel * Tunnel_lookup(VnetId *vnet, VarpAddr *addr){ 29.71 Tunnel *tunnel = NULL; 29.72 - TunnelKey key = {.vnet = vnet, .addr = addr }; 29.73 + TunnelKey key = {.vnet = *vnet, .addr = *addr }; 29.74 dprintf(">\n"); 29.75 tunnel = HashTable_get(tunnel_table, &key); 29.76 Tunnel_incref(tunnel); 29.77 @@ -199,23 +198,16 @@ int Tunnel_del(Tunnel *tunnel){ 29.78 */ 29.79 int Tunnel_send(Tunnel *tunnel, struct sk_buff *skb){ 29.80 int err = 0; 29.81 - int len; 29.82 dprintf("> tunnel=%p skb=%p\n", tunnel, skb); 29.83 - len = skb->len; 29.84 if(tunnel){ 29.85 + int len = skb->len; 29.86 dprintf("> type=%s type->send...\n", tunnel->type->name); 29.87 + // Must not refer to skb after sending - might have been freed. 29.88 err = tunnel->type->send(tunnel, skb); 29.89 - // Must not refer to skb after sending - might have been freed. 29.90 TunnelStats_update(&tunnel->send_stats, len, err); 29.91 } else { 29.92 - struct net_device *dev = NULL; 29.93 - err = vnet_get_device(DEVICE, &dev); 29.94 - if(err) goto exit; 29.95 - skb->dev = dev; 29.96 err = skb_xmit(skb); 29.97 - dev_put(dev); 29.98 } 29.99 - exit: 29.100 dprintf("< err=%d\n", err); 29.101 return err; 29.102 } 29.103 @@ -225,4 +217,8 @@ int __init tunnel_module_init(void){ 29.104 } 29.105 29.106 void __exit tunnel_module_exit(void){ 29.107 + if(tunnel_table){ 29.108 + HashTable_free(tunnel_table); 29.109 + tunnel_table = NULL; 29.110 + } 29.111 }
30.1 --- a/tools/vnet/vnet-module/tunnel.h Fri Aug 26 10:51:10 2005 +0000 30.2 +++ b/tools/vnet/vnet-module/tunnel.h Fri Aug 26 10:52:53 2005 +0000 30.3 @@ -22,6 +22,7 @@ 30.4 #include <linux/types.h> 30.5 #include <linux/slab.h> 30.6 #include <asm/atomic.h> 30.7 +#include <if_varp.h> 30.8 30.9 struct sk_buff; 30.10 struct Tunnel; 30.11 @@ -41,8 +42,8 @@ typedef struct TunnelStats { 30.12 } TunnelStats; 30.13 30.14 typedef struct TunnelKey { 30.15 - u32 vnet; 30.16 - u32 addr; 30.17 + VnetId vnet; 30.18 + VarpAddr addr; 30.19 } TunnelKey; 30.20 30.21 typedef struct Tunnel { 30.22 @@ -87,13 +88,15 @@ static inline void Tunnel_incref(Tunnel 30.23 } 30.24 30.25 extern int Tunnel_init(void); 30.26 -extern Tunnel * Tunnel_lookup(u32 vnet, u32 addr); 30.27 +extern Tunnel * Tunnel_lookup(struct VnetId *vnet, struct VarpAddr *addr); 30.28 extern int Tunnel_add(Tunnel *tunnel); 30.29 extern int Tunnel_del(Tunnel *tunnel); 30.30 extern int Tunnel_send(Tunnel *tunnel, struct sk_buff *skb); 30.31 30.32 -extern int Tunnel_create(TunnelType *type, u32 vnet, u32 addr, Tunnel *base, Tunnel **tunnelp); 30.33 -extern int Tunnel_open(TunnelType *type, u32 vnet, u32 addr, Tunnel *base, Tunnel **tunnelp); 30.34 +extern int Tunnel_create(TunnelType *type, struct VnetId *vnet, struct VarpAddr *addr, 30.35 + Tunnel *base, Tunnel **tunnelp); 30.36 +extern int Tunnel_open(TunnelType *type, struct VnetId *vnet, struct VarpAddr *addr, 30.37 + Tunnel *base, Tunnel **tunnelp); 30.38 30.39 extern int tunnel_module_init(void); 30.40 extern void tunnel_module_exit(void);
31.1 --- a/tools/vnet/vnet-module/varp.c Fri Aug 26 10:51:10 2005 +0000 31.2 +++ b/tools/vnet/vnet-module/varp.c Fri Aug 26 10:52:53 2005 +0000 31.3 @@ -40,27 +40,21 @@ 31.4 #include <tunnel.h> 31.5 #include <vnet.h> 31.6 #include <vif.h> 31.7 +#include <if_varp.h> 31.8 #include <varp.h> 31.9 -#include <if_varp.h> 31.10 +#include <vnet.h> 31.11 31.12 #include "allocate.h" 31.13 #include "hash_table.h" 31.14 #include "sys_net.h" 31.15 #include "sys_string.h" 31.16 +#include "skb_util.h" 31.17 31.18 #define MODULE_NAME "VARP" 31.19 -//#define DEBUG 1 31.20 +#define DEBUG 1 31.21 #undef DEBUG 31.22 #include "debug.h" 31.23 31.24 - 31.25 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 31.26 -// The 'ethernet' field in the skb->mac union went away. 31.27 -#define MAC_ETH(_skb) ((struct ethhdr *)(_skb)->mac.raw) 31.28 -#else 31.29 -#define MAC_ETH(_skb) ((_skb)->mac.ethernet) 31.30 -#endif 31.31 - 31.32 /** @file VARP: Virtual ARP. 31.33 * 31.34 * Handles virtual ARP requests for vnet/vmac. 31.35 @@ -121,8 +115,8 @@ enum { 31.36 31.37 /** Key for varp entries. */ 31.38 typedef struct VarpKey { 31.39 - /** Vnet id (host order). */ 31.40 - u32 vnet; 31.41 + /** Vnet id (network order). */ 31.42 + VnetId vnet; 31.43 /** Virtual MAC address. */ 31.44 Vmac vmac; 31.45 } VarpKey; 31.46 @@ -132,7 +126,7 @@ typedef struct VarpEntry { 31.47 /** Key for the entry. */ 31.48 VarpKey key; 31.49 /** Care-of address for the key. */ 31.50 - u32 addr; 31.51 + VarpAddr addr; 31.52 /** Last-updated timestamp. */ 31.53 unsigned long timestamp; 31.54 /** State. */ 31.55 @@ -152,8 +146,6 @@ typedef struct VarpEntry { 31.56 struct sk_buff_head queue; 31.57 /** Maximum size of the queue. */ 31.58 int queue_max; 31.59 - 31.60 - int locks; 31.61 } VarpEntry; 31.62 31.63 /** The varp cache. Varp entries indexed by VarpKey. */ 31.64 @@ -181,14 +173,10 @@ static char *varp_mcaddr = NULL; 31.65 /** Multicast address (network order). */ 31.66 u32 varp_mcast_addr = 0; 31.67 31.68 -/** Unicast address (network order). */ 31.69 -u32 varp_ucast_addr = 0; 31.70 - 31.71 /** UDP port (network order). */ 31.72 u16 varp_port = 0; 31.73 31.74 -/** Network device to use. */ 31.75 -char *varp_device = DEVICE; 31.76 +char *varp_device = "xen-br0"; 31.77 31.78 #define VarpTable_read_lock(z, flags) do{ (flags) = 0; down(&(z)->lock); } while(0) 31.79 #define VarpTable_read_unlock(z, flags) do{ (flags) = 0; up(&(z)->lock); } while(0) 31.80 @@ -199,8 +187,11 @@ char *varp_device = DEVICE; 31.81 #define VarpEntry_unlock(ventry, flags) write_unlock_irqrestore(&(ventry)->lock, (flags)) 31.82 31.83 void VarpTable_sweep(VarpTable *z, int all); 31.84 +void VarpTable_flush(VarpTable *z); 31.85 void VarpTable_print(VarpTable *z); 31.86 31.87 +#include "./varp_util.c" 31.88 + 31.89 /** Print the varp cache (if debug on). 31.90 */ 31.91 void varp_dprint(void){ 31.92 @@ -209,14 +200,53 @@ void varp_dprint(void){ 31.93 #endif 31.94 } 31.95 31.96 +/** Flush the varp cache. 31.97 + */ 31.98 +void varp_flush(void){ 31.99 + VarpTable_flush(varp_table); 31.100 +} 31.101 + 31.102 +static int device_ucast_addr(const char *device, uint32_t *addr) 31.103 +{ 31.104 + int err; 31.105 + struct net_device *dev = NULL; 31.106 + 31.107 + err = vnet_get_device(device, &dev); 31.108 + if(err) goto exit; 31.109 + err = vnet_get_device_address(dev, addr); 31.110 + exit: 31.111 + if(err){ 31.112 + *addr = 0; 31.113 + } 31.114 + return err; 31.115 +} 31.116 + 31.117 +/** Get the unicast address of the varp device. 31.118 + */ 31.119 +int varp_ucast_addr(uint32_t *addr) 31.120 +{ 31.121 + int err = -ENODEV; 31.122 + const char *devices[] = { varp_device, "eth0", "eth1", "eth2", NULL }; 31.123 + const char **p; 31.124 + for(p = devices; err && *p; p++){ 31.125 + err = device_ucast_addr(*p, addr); 31.126 + } 31.127 + return err; 31.128 +} 31.129 + 31.130 /** Print varp info and the varp cache. 31.131 */ 31.132 void varp_print(void){ 31.133 + uint32_t addr = 0; 31.134 + varp_ucast_addr(&addr); 31.135 + 31.136 printk(KERN_INFO "=== VARP ===============================================================\n"); 31.137 printk(KERN_INFO "varp_device %s\n", varp_device); 31.138 printk(KERN_INFO "varp_mcast_addr " IPFMT "\n", NIPQUAD(varp_mcast_addr)); 31.139 - printk(KERN_INFO "varp_ucast_addr " IPFMT "\n", NIPQUAD(varp_ucast_addr)); 31.140 + printk(KERN_INFO "varp_ucast_addr " IPFMT "\n", NIPQUAD(addr)); 31.141 printk(KERN_INFO "varp_port %d\n", ntohs(varp_port)); 31.142 + vnet_print(); 31.143 + vif_print(); 31.144 VarpTable_print(varp_table); 31.145 printk(KERN_INFO "========================================================================\n"); 31.146 } 31.147 @@ -246,19 +276,44 @@ int vnet_get_device_address(struct net_d 31.148 int err = 0; 31.149 struct in_device *in_dev; 31.150 31.151 - //printk("%s>\n", __FUNCTION__); 31.152 in_dev = in_dev_get(dev); 31.153 if(!in_dev){ 31.154 - err = -EIO; 31.155 + err = -ENODEV; 31.156 goto exit; 31.157 } 31.158 *addr = in_dev->ifa_list->ifa_address; 31.159 in_dev_put(in_dev); 31.160 exit: 31.161 - //printk("%s< err=%d\n", __FUNCTION__, err); 31.162 return err; 31.163 } 31.164 31.165 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 31.166 + 31.167 +static inline int addr_route(u32 daddr, struct rtable **prt){ 31.168 + int err = 0; 31.169 + struct flowi fl = { 31.170 + .nl_u = { 31.171 + .ip4_u = { 31.172 + .daddr = daddr, 31.173 + } 31.174 + } 31.175 + }; 31.176 + 31.177 + err = ip_route_output_key(prt, &fl); 31.178 + return err; 31.179 +} 31.180 + 31.181 +#else 31.182 + 31.183 +static inline int addr_route(u32 daddr, struct rtable **prt){ 31.184 + int err = 0; 31.185 + struct rt_key key = { .dst = daddr }; 31.186 + err = ip_route_output_key(prt, &key); 31.187 + return err; 31.188 +} 31.189 + 31.190 +#endif 31.191 + 31.192 #ifndef LL_RESERVED_SPACE 31.193 #define HH_DATA_MOD 16 31.194 #define LL_RESERVED_SPACE(dev) \ 31.195 @@ -270,12 +325,12 @@ int vnet_get_device_address(struct net_d 31.196 * @param opcode varp opcode (host order) 31.197 * @param dev device (may be null) 31.198 * @param skb skb being replied to (may be null) 31.199 - * @param vnet vnet id (in host order) 31.200 + * @param vnet vnet id (in network order) 31.201 * @param vmac vmac (in network order) 31.202 * @return 0 on success, error code otherwise 31.203 */ 31.204 int varp_send(u16 opcode, struct net_device *dev, struct sk_buff *skbin, 31.205 - u32 vnet, Vmac *vmac){ 31.206 + VnetId *vnet, Vmac *vmac){ 31.207 int err = 0; 31.208 int link_n = 0; 31.209 int ip_n = sizeof(struct iphdr); 31.210 @@ -285,45 +340,53 @@ int varp_send(u16 opcode, struct net_dev 31.211 struct in_device *in_dev = NULL; 31.212 VarpHdr *varph = NULL; 31.213 u8 macbuf[6] = {}; 31.214 - u8 *smac, *dmac; 31.215 + u8 *smac, *dmac = macbuf; 31.216 u32 saddr, daddr; 31.217 u16 sport, dport; 31.218 +#if defined(DEBUG) 31.219 + char vnetbuf[VNET_ID_BUF]; 31.220 +#endif 31.221 31.222 - dmac = macbuf; 31.223 - dprintf("> opcode=%d vnet=%d vmac=" MACFMT "\n", 31.224 - opcode, ntohl(vnet), MAC6TUPLE(vmac->mac)); 31.225 - if(!dev){ 31.226 - //todo: should use routing for daddr to get device. 31.227 - err = vnet_get_device(varp_device, &dev); 31.228 - if(err) goto exit; 31.229 - } 31.230 - link_n = LL_RESERVED_SPACE(dev); 31.231 - in_dev = in_dev_get(dev); 31.232 - if(!in_dev) goto exit; 31.233 + dprintf("> opcode=%d vnet= %s vmac=" MACFMT "\n", 31.234 + opcode, VnetId_ntoa(vnet, vnetbuf), MAC6TUPLE(vmac->mac)); 31.235 31.236 - smac = dev->dev_addr; 31.237 - saddr = in_dev->ifa_list->ifa_address; 31.238 - 31.239 + dport = varp_port; 31.240 if(skbin){ 31.241 - dmac = MAC_ETH(skbin)->h_source; 31.242 + daddr = skbin->nh.iph->saddr; 31.243 + dmac = eth_hdr(skbin)->h_source; 31.244 sport = skbin->h.uh->dest; 31.245 - daddr = skbin->nh.iph->saddr; 31.246 - //dport = skbin->h.uh->source; 31.247 - dport = varp_port; 31.248 } else { 31.249 - if(!in_dev) goto exit; 31.250 if(MULTICAST(varp_mcast_addr)){ 31.251 daddr = varp_mcast_addr; 31.252 ip_eth_mc_map(daddr, dmac); 31.253 } else { 31.254 - daddr = in_dev->ifa_list->ifa_broadcast; 31.255 - dmac = dev->broadcast; 31.256 + daddr = INADDR_BROADCAST; 31.257 } 31.258 sport = varp_port; 31.259 - dport = varp_port; 31.260 + } 31.261 + 31.262 + if(!dev){ 31.263 + struct rtable *rt = NULL; 31.264 + err = addr_route(daddr, &rt); 31.265 + if(err) goto exit; 31.266 + dev = rt->u.dst.dev; 31.267 + } 31.268 + 31.269 + in_dev = in_dev_get(dev); 31.270 + if(!in_dev){ 31.271 + err = -ENODEV; 31.272 + goto exit; 31.273 + } 31.274 + link_n = LL_RESERVED_SPACE(dev); 31.275 + saddr = in_dev->ifa_list->ifa_address; 31.276 + smac = dev->dev_addr; 31.277 + if(daddr == INADDR_BROADCAST){ 31.278 + daddr = in_dev->ifa_list->ifa_broadcast; 31.279 + dmac = dev->broadcast; 31.280 } 31.281 in_dev_put(in_dev); 31.282 31.283 + dprintf("> dev=%s\n", dev->name); 31.284 dprintf("> smac=" MACFMT " dmac=" MACFMT "\n", MAC6TUPLE(smac), MAC6TUPLE(dmac)); 31.285 dprintf("> saddr=" IPFMT " daddr=" IPFMT "\n", NIPQUAD(saddr), NIPQUAD(daddr)); 31.286 dprintf("> sport=%u dport=%u\n", ntohs(sport), ntohs(dport)); 31.287 @@ -368,11 +431,12 @@ int varp_send(u16 opcode, struct net_dev 31.288 // Varp header. 31.289 varph = (void*)skb_put(skbout, varp_n); 31.290 *varph = (VarpHdr){}; 31.291 - varph->vnetmsghdr.id = htons(VARP_ID); 31.292 - varph->vnetmsghdr.opcode = htons(opcode); 31.293 - varph->vnet = htonl(vnet); 31.294 + varph->hdr.id = htons(VARP_ID); 31.295 + varph->hdr.opcode = htons(opcode); 31.296 + varph->vnet = *vnet; 31.297 varph->vmac = *vmac; 31.298 - varph->addr = saddr; 31.299 + varph->addr.family = AF_INET; 31.300 + varph->addr.u.ip4.s_addr = saddr; 31.301 31.302 err = skb_xmit(skbout); 31.303 31.304 @@ -385,16 +449,13 @@ int varp_send(u16 opcode, struct net_dev 31.305 /** Send a varp request for the vnet and destination mac of a packet. 31.306 * 31.307 * @param skb packet 31.308 - * @param vnet vnet (in host order) 31.309 + * @param vnet vnet (in network order) 31.310 * @return 0 on success, error code otherwise 31.311 */ 31.312 -int varp_solicit(struct sk_buff *skb, int vnet){ 31.313 +int varp_solicit(struct sk_buff *skb, VnetId *vnet){ 31.314 int err = 0; 31.315 - dprintf("> skb=%p\n", skb); 31.316 - varp_dprint(); 31.317 err = varp_send(VARP_OP_REQUEST, NULL, NULL, 31.318 - vnet, (Vmac*)MAC_ETH(skb)->h_dest); 31.319 - dprintf("< err=%d\n", err); 31.320 + vnet, (Vmac*)eth_hdr(skb)->h_dest); 31.321 return err; 31.322 } 31.323 31.324 @@ -430,22 +491,26 @@ int VarpEntry_set_flags(VarpEntry *z, in 31.325 */ 31.326 void VarpEntry_print(VarpEntry *ventry){ 31.327 if(ventry){ 31.328 - char *c, *d; 31.329 + char *state, *flags; 31.330 + char vnetbuf[VNET_ID_BUF]; 31.331 + char addrbuf[VARP_ADDR_BUF]; 31.332 + 31.333 switch(ventry->state){ 31.334 - case VARP_STATE_INCOMPLETE: c = "INC"; break; 31.335 - case VARP_STATE_REACHABLE: c = "RCH"; break; 31.336 - case VARP_STATE_FAILED: c = "FLD"; break; 31.337 - default: c = "UNK"; break; 31.338 + case VARP_STATE_INCOMPLETE: state = "INC"; break; 31.339 + case VARP_STATE_REACHABLE: state = "RCH"; break; 31.340 + case VARP_STATE_FAILED: state = "FLD"; break; 31.341 + default: state = "UNK"; break; 31.342 } 31.343 - d = (VarpEntry_get_flags(ventry, VARP_FLAG_PROBING) ? "P" : " "); 31.344 + flags = (VarpEntry_get_flags(ventry, VARP_FLAG_PROBING) ? "P" : " "); 31.345 31.346 - printk(KERN_INFO "VENTRY(%p ref=%1d %s %s vnet=%d vmac=" MACFMT " addr=" IPFMT " q=%d t=%lu)\n", 31.347 + printk(KERN_INFO "VENTRY(%p ref=%1d %s %s vnet=%s vmac=" MACFMT 31.348 + " addr=%s q=%3d t=%lu)\n", 31.349 ventry, 31.350 atomic_read(&ventry->refcount), 31.351 - c, d, 31.352 - ventry->key.vnet, 31.353 + state, flags, 31.354 + VnetId_ntoa(&ventry->key.vnet, vnetbuf), 31.355 MAC6TUPLE(ventry->key.vmac.mac), 31.356 - NIPQUAD(ventry->addr), 31.357 + VarpAddr_ntoa(&ventry->addr, addrbuf), 31.358 skb_queue_len(&ventry->queue), 31.359 ventry->timestamp); 31.360 } else { 31.361 @@ -469,7 +534,6 @@ void VarpEntry_free(VarpEntry *z){ 31.362 void VarpEntry_incref(VarpEntry *z){ 31.363 if(!z) return; 31.364 atomic_inc(&z->refcount); 31.365 - //dprintf("> "); VarpEntry_print(z); 31.366 } 31.367 31.368 /** Decrement reference count, freeing if zero. 31.369 @@ -478,9 +542,7 @@ void VarpEntry_incref(VarpEntry *z){ 31.370 */ 31.371 void VarpEntry_decref(VarpEntry *z){ 31.372 if(!z) return; 31.373 - //dprintf("> "); VarpEntry_print(z); 31.374 if(atomic_dec_and_test(&z->refcount)){ 31.375 - //dprintf("> freeing %p...\n", z); 31.376 VarpEntry_free(z); 31.377 } 31.378 } 31.379 @@ -499,7 +561,7 @@ void VarpEntry_error(VarpEntry *ventry){ 31.380 31.381 /** Schedule the varp entry timer. 31.382 * Must increment the reference count before doing 31.383 - * this the first time, so the ventry won' be freed 31.384 + * this the first time, so the ventry won't be freed 31.385 * before the timer goes off. 31.386 * 31.387 * @param ventry varp entry 31.388 @@ -538,7 +600,7 @@ static void varp_timer_fn(unsigned long 31.389 atomic_inc(&ventry->probes); 31.390 VarpEntry_unlock(ventry, flags); 31.391 locked = 0; 31.392 - varp_solicit(skb, ventry->key.vnet); 31.393 + varp_solicit(skb, &ventry->key.vnet); 31.394 } else { 31.395 dprintf("> empty queue.\n"); 31.396 } 31.397 @@ -568,7 +630,7 @@ static void varp_error_fn(VarpEntry *ven 31.398 * @param vmac virtual MAC address (copied) 31.399 * @return ventry or null 31.400 */ 31.401 -VarpEntry * VarpEntry_new(u32 vnet, Vmac *vmac){ 31.402 +VarpEntry * VarpEntry_new(VnetId *vnet, Vmac *vmac){ 31.403 VarpEntry *z = ALLOCATE(VarpEntry); 31.404 if(z){ 31.405 unsigned long now = jiffies; 31.406 @@ -584,7 +646,7 @@ VarpEntry * VarpEntry_new(u32 vnet, Vmac 31.407 z->timestamp = now; 31.408 z->error = varp_error_fn; 31.409 31.410 - z->key.vnet = vnet; 31.411 + z->key.vnet = *vnet; 31.412 z->key.vmac = *vmac; 31.413 } 31.414 return z; 31.415 @@ -598,15 +660,9 @@ VarpEntry * VarpEntry_new(u32 vnet, Vmac 31.416 */ 31.417 Hashcode varp_key_hash_fn(void *k){ 31.418 VarpKey *key = k; 31.419 - Hashcode h; 31.420 - h = hash_2ul(key->vnet, 31.421 - (key->vmac.mac[0] << 24) | 31.422 - (key->vmac.mac[1] << 16) | 31.423 - (key->vmac.mac[2] << 8) | 31.424 - (key->vmac.mac[3] )); 31.425 - h = hash_hul(h, 31.426 - (key->vmac.mac[4] << 8) | 31.427 - (key->vmac.mac[5] )); 31.428 + Hashcode h = 0; 31.429 + h = VnetId_hash(h, &key->vnet); 31.430 + h = Vmac_hash(h, &key->vmac); 31.431 return h; 31.432 } 31.433 31.434 @@ -620,8 +676,8 @@ Hashcode varp_key_hash_fn(void *k){ 31.435 int varp_key_equal_fn(void *k1, void *k2){ 31.436 VarpKey *key1 = k1; 31.437 VarpKey *key2 = k2; 31.438 - return (key1->vnet == key2->vnet) 31.439 - && (memcmp(key1->vmac.mac, key2->vmac.mac, ETH_ALEN) == 0); 31.440 + return (VnetId_eq(&key1->vnet, &key2->vnet) && 31.441 + Vmac_eq(&key1->vmac, &key2->vmac)); 31.442 } 31.443 31.444 /** Free an entry in the varp cache. 31.445 @@ -670,12 +726,10 @@ void VarpTable_schedule(VarpTable *z){ 31.446 */ 31.447 static void varp_table_timer_fn(unsigned long arg){ 31.448 VarpTable *z = (VarpTable *)arg; 31.449 - //dprintf("> z=%p\n", z); 31.450 if(z){ 31.451 VarpTable_sweep(z, 0); 31.452 VarpTable_schedule(z); 31.453 } 31.454 - //dprintf("<\n"); 31.455 } 31.456 31.457 /** Print a varp table. 31.458 @@ -687,7 +741,6 @@ void VarpTable_print(VarpTable *z){ 31.459 VarpEntry *ventry; 31.460 unsigned long flags, vflags; 31.461 31.462 - //dprintf(">\n"); 31.463 VarpTable_read_lock(z, flags); 31.464 HashTable_for_each(entry, varp_table->table){ 31.465 ventry = entry->value; 31.466 @@ -696,7 +749,6 @@ void VarpTable_print(VarpTable *z){ 31.467 VarpEntry_unlock(ventry, vflags); 31.468 } 31.469 VarpTable_read_unlock(z, flags); 31.470 - //dprintf("<\n"); 31.471 } 31.472 31.473 /** Create a varp table. 31.474 @@ -735,7 +787,7 @@ VarpTable * VarpTable_new(void){ 31.475 * @param vmac virtual MAC address (copied) 31.476 * @return new entry or null 31.477 */ 31.478 -VarpEntry * VarpTable_add(VarpTable *z, u32 vnet, Vmac *vmac){ 31.479 +VarpEntry * VarpTable_add(VarpTable *z, VnetId *vnet, Vmac *vmac){ 31.480 int err = -ENOMEM; 31.481 VarpEntry *ventry; 31.482 HTEntry *entry; 31.483 @@ -743,7 +795,6 @@ VarpEntry * VarpTable_add(VarpTable *z, 31.484 31.485 ventry = VarpEntry_new(vnet, vmac); 31.486 if(!ventry) goto exit; 31.487 - //dprintf("> "); VarpEntry_print(ventry); 31.488 VarpTable_write_lock(z, flags); 31.489 entry = HashTable_add(z->table, ventry, ventry); 31.490 VarpTable_write_unlock(z, flags); 31.491 @@ -775,19 +826,20 @@ int VarpTable_remove(VarpTable *z, VarpE 31.492 * @param vmac virtual MAC addres 31.493 * @return entry found or null 31.494 */ 31.495 -VarpEntry * VarpTable_lookup(VarpTable *z, u32 vnet, Vmac *vmac){ 31.496 +VarpEntry * VarpTable_lookup(VarpTable *z, VnetId *vnet, Vmac *vmac){ 31.497 unsigned long flags; 31.498 - VarpKey key = { .vnet = vnet, .vmac = *vmac }; 31.499 + VarpKey key = { .vnet = *vnet, .vmac = *vmac }; 31.500 VarpEntry *ventry; 31.501 VarpTable_read_lock(z, flags); 31.502 ventry = HashTable_get(z->table, &key); 31.503 + if(ventry) VarpEntry_incref(ventry); 31.504 VarpTable_read_unlock(z, flags); 31.505 - if(ventry) VarpEntry_incref(ventry); 31.506 return ventry; 31.507 } 31.508 31.509 /** Handle output for a reachable ventry. 31.510 * Send the skb using the tunnel to the care-of address. 31.511 + * Assumes the ventry lock is held. 31.512 * 31.513 * @param ventry varp entry 31.514 * @param skb skb to send 31.515 @@ -796,12 +848,12 @@ VarpEntry * VarpTable_lookup(VarpTable * 31.516 int VarpEntry_send(VarpEntry *ventry, struct sk_buff *skb){ 31.517 int err = 0; 31.518 unsigned long flags = 0; 31.519 - u32 addr; 31.520 + VarpAddr addr; 31.521 31.522 dprintf("> skb=%p\n", skb); 31.523 addr = ventry->addr; 31.524 VarpEntry_unlock(ventry, flags); 31.525 - err = vnet_tunnel_send(ventry->key.vnet, addr, skb); 31.526 + err = vnet_tunnel_send(&ventry->key.vnet, &addr, skb); 31.527 VarpEntry_lock(ventry, flags); 31.528 dprintf("< err=%d\n", err); 31.529 return err; 31.530 @@ -811,6 +863,7 @@ int VarpEntry_send(VarpEntry *ventry, st 31.531 * If the entry is still incomplete, queue the skb, otherwise 31.532 * send it. If the queue is full, dequeue and free an old skb to 31.533 * make room for the new one. 31.534 + * Assumes the ventry lock is held. 31.535 * 31.536 * @param ventry varp entry 31.537 * @param skb skb to send 31.538 @@ -820,7 +873,7 @@ int VarpEntry_resolve(VarpEntry *ventry, 31.539 int err = 0; 31.540 unsigned long flags = 0; 31.541 31.542 - dprintf("> skb=%p\n", skb); //VarpEntry_print(ventry); 31.543 + dprintf("> skb=%p\n", skb); 31.544 ventry->state = VARP_STATE_INCOMPLETE; 31.545 atomic_set(&ventry->probes, 1); 31.546 if(!VarpEntry_get_flags(ventry, VARP_FLAG_PROBING)){ 31.547 @@ -829,7 +882,7 @@ int VarpEntry_resolve(VarpEntry *ventry, 31.548 VarpEntry_schedule(ventry); 31.549 } 31.550 VarpEntry_unlock(ventry, flags); 31.551 - varp_solicit(skb, ventry->key.vnet); 31.552 + varp_solicit(skb, &ventry->key.vnet); 31.553 VarpEntry_lock(ventry, flags); 31.554 31.555 if(ventry->state == VARP_STATE_INCOMPLETE){ 31.556 @@ -837,7 +890,7 @@ int VarpEntry_resolve(VarpEntry *ventry, 31.557 struct sk_buff *oldskb; 31.558 oldskb = ventry->queue.next; 31.559 __skb_unlink(oldskb, &ventry->queue); 31.560 - dprintf("> purging skb=%p\n", oldskb); 31.561 + dprintf("> dropping skb=%p\n", oldskb); 31.562 kfree_skb(oldskb); 31.563 } 31.564 __skb_queue_tail(&ventry->queue, skb); 31.565 @@ -893,33 +946,39 @@ void VarpEntry_process_queue(VarpEntry * 31.566 * @param state state 31.567 * @return 0 on success, error code otherwise 31.568 */ 31.569 -int VarpEntry_update(VarpEntry *ventry, u32 addr, int state){ 31.570 +int VarpEntry_update(VarpEntry *ventry, VarpAddr *addr, int state){ 31.571 int err = 0; 31.572 unsigned long now = jiffies; 31.573 unsigned long flags; 31.574 31.575 dprintf("> addr=" IPFMT " state=%d\n", NIPQUAD(addr), state); 31.576 - //VarpEntry_print(ventry); 31.577 VarpEntry_lock(ventry, flags); 31.578 if(VarpEntry_get_flags(ventry, VARP_FLAG_PERMANENT)) goto exit; 31.579 - ventry->addr = addr; 31.580 + ventry->addr = *addr; 31.581 ventry->timestamp = now; 31.582 ventry->state = state; 31.583 VarpEntry_process_queue(ventry); 31.584 exit: 31.585 - //dprintf("> "); VarpEntry_print(ventry); 31.586 VarpEntry_unlock(ventry, flags); 31.587 dprintf("< err=%d\n", err); 31.588 return err; 31.589 } 31.590 31.591 -int VarpTable_update(VarpTable *z, int vnet, Vmac *vmac, u32 addr, 31.592 +int VarpTable_update(VarpTable *z, VnetId *vnet, Vmac *vmac, VarpAddr *addr, 31.593 int state, int force){ 31.594 int err = 0; 31.595 VarpEntry *ventry; 31.596 +#ifdef DEBUG 31.597 + char vnetbuf[VNET_ID_BUF]; 31.598 + char addrbuf[VARP_ADDR_BUF]; 31.599 +#endif 31.600 31.601 - dprintf("> vnet=%d mac=" MACFMT " addr=" IPFMT " state=%d force=%d\n", 31.602 - vnet, MAC6TUPLE(vmac->mac), NIPQUAD(addr), state, force); 31.603 + dprintf("> vnet=%s mac=" MACFMT " addr=%s state=%d force=%d\n", 31.604 + VnetId_ntoa(vnet, vnetbuf), 31.605 + MAC6TUPLE(vmac->mac), 31.606 + VarpAddr_ntoa(addr, addrbuf), 31.607 + state, 31.608 + force); 31.609 ventry = VarpTable_lookup(z, vnet, vmac); 31.610 if(force && !ventry){ 31.611 dprintf("> No entry, adding\n"); 31.612 @@ -945,10 +1004,10 @@ int VarpTable_update(VarpTable *z, int v 31.613 * @return 0 on success, -ENOENT if no entry found 31.614 */ 31.615 int VarpTable_update_entry(VarpTable *z, VarpHdr *varph, int state){ 31.616 - return VarpTable_update(z, ntohl(varph->vnet), &varph->vmac, varph->addr, state, 0); 31.617 + return VarpTable_update(z, &varph->vnet, &varph->vmac, &varph->addr, state, 0); 31.618 } 31.619 31.620 -int varp_update(int vnet, unsigned char *vmac, u32 addr){ 31.621 +int varp_update(VnetId *vnet, unsigned char *vmac, VarpAddr *addr){ 31.622 if(!varp_table){ 31.623 return -ENOSYS; 31.624 } 31.625 @@ -971,7 +1030,6 @@ void VarpTable_sweep(VarpTable *z, int a 31.626 unsigned long old = now - VARP_ENTRY_TTL; 31.627 unsigned long flags, vflags; 31.628 31.629 - //dprintf(">\n"); 31.630 VarpTable_read_lock(z, flags); 31.631 HashTable_for_each(entry, varp_table->table){ 31.632 ventry = entry->value; 31.633 @@ -984,7 +1042,36 @@ void VarpTable_sweep(VarpTable *z, int a 31.634 VarpEntry_unlock(ventry, vflags); 31.635 } 31.636 VarpTable_read_unlock(z, flags); 31.637 - //dprintf("<\n"); 31.638 +} 31.639 + 31.640 +/** Flush the varp table. 31.641 + * Remove old unreachable varp entries with empty queues. 31.642 + * Permanent entries are not removed. 31.643 + * 31.644 + * @param z table 31.645 + */ 31.646 +void VarpTable_flush(VarpTable *z){ 31.647 + HashTable_for_decl(entry); 31.648 + VarpEntry *ventry; 31.649 + unsigned long now = jiffies; 31.650 + unsigned long old = now - VARP_ENTRY_TTL; 31.651 + unsigned long flags, vflags; 31.652 + int flush; 31.653 + 31.654 + VarpTable_write_lock(z, flags); 31.655 + HashTable_for_each(entry, varp_table->table){ 31.656 + ventry = entry->value; 31.657 + VarpEntry_lock(ventry, vflags); 31.658 + flush = (!VarpEntry_get_flags(ventry, VARP_FLAG_PERMANENT) && 31.659 + (ventry->timestamp < old) && 31.660 + (ventry->state != VARP_STATE_REACHABLE) && 31.661 + (skb_queue_len(&ventry->queue) == 0)); 31.662 + VarpEntry_unlock(ventry, vflags); 31.663 + if(flush){ 31.664 + VarpTable_remove(z, ventry); 31.665 + } 31.666 + } 31.667 + VarpTable_write_unlock(z, flags); 31.668 } 31.669 31.670 /** Handle a varp request. Look for a vif with the requested 31.671 @@ -997,14 +1084,13 @@ void VarpTable_sweep(VarpTable *z, int a 31.672 */ 31.673 int varp_handle_request(struct sk_buff *skb, VarpHdr *varph){ 31.674 int err = -ENOENT; 31.675 - u32 vnet; 31.676 + VnetId *vnet; 31.677 Vmac *vmac; 31.678 Vif *vif = NULL; 31.679 31.680 dprintf(">\n"); 31.681 - vnet = ntohl(varph->vnet); 31.682 + vnet = &varph->vnet; 31.683 vmac = &varph->vmac; 31.684 - dprintf("> vnet=%d vmac=" MACFMT "\n", vnet, MAC6TUPLE(vmac->mac)); 31.685 if(vif_lookup(vnet, vmac, &vif)) goto exit; 31.686 varp_send(VARP_OP_ANNOUNCE, skb->dev, skb, vnet, vmac); 31.687 vif_decref(vif); 31.688 @@ -1026,7 +1112,7 @@ int varp_announce_vif(struct net_device 31.689 err = -ENOSYS; 31.690 goto exit; 31.691 } 31.692 - err = varp_send(VARP_OP_ANNOUNCE, dev, NULL, vif->vnet, &vif->vmac); 31.693 + err = varp_send(VARP_OP_ANNOUNCE, dev, NULL, &vif->vnet, &vif->vmac); 31.694 exit: 31.695 dprintf("< err=%d\n", err); 31.696 return err; 31.697 @@ -1067,7 +1153,7 @@ int varp_handle_message(struct sk_buff * 31.698 (skb->nh.iph->daddr != varp_mcast_addr)){ 31.699 // Ignore multicast packets not addressed to us. 31.700 err = 0; 31.701 - dprintf("> daddr=" IPFMT " mcaddr=" IPFMT "\n", 31.702 + dprintf("> Ignoring daddr=" IPFMT " mcaddr=" IPFMT "\n", 31.703 NIPQUAD(skb->nh.iph->daddr), NIPQUAD(varp_mcast_addr)); 31.704 goto exit; 31.705 } 31.706 @@ -1076,23 +1162,29 @@ int varp_handle_message(struct sk_buff * 31.707 goto exit; 31.708 } 31.709 mine = 1; 31.710 - if(varph->vnetmsghdr.id != htons(VARP_ID)){ 31.711 + if(varph->hdr.id != htons(VARP_ID)){ 31.712 // It's not varp at all - ignore it. 31.713 - wprintf("> Unknown id: %d \n", ntohs(varph->vnetmsghdr.id)); 31.714 + wprintf("> Invalid varp id: %d, expected %d \n", 31.715 + ntohs(varph->hdr.id), 31.716 + VARP_ID); 31.717 goto exit; 31.718 } 31.719 - if(1){ 31.720 +#ifdef DEBUG 31.721 + { 31.722 + char vnetbuf[VNET_ID_BUF]; 31.723 + char addrbuf[VARP_ADDR_BUF]; 31.724 dprintf("> saddr=" IPFMT " daddr=" IPFMT "\n", 31.725 NIPQUAD(skb->nh.iph->saddr), NIPQUAD(skb->nh.iph->daddr)); 31.726 dprintf("> sport=%u dport=%u\n", ntohs(skb->h.uh->source), ntohs(skb->h.uh->dest)); 31.727 - dprintf("> opcode=%d vnet=%u vmac=" MACFMT " addr=" IPFMT "\n", 31.728 - ntohs(varph->vnetmsghdr.opcode), 31.729 - ntohl(varph->vnet), 31.730 + dprintf("> opcode=%d vnet=%s vmac=" MACFMT " addr=%s\n", 31.731 + ntohs(varph->hdr.opcode), 31.732 + VnetId_ntoa(&varph->vnet, vnetbuf), 31.733 MAC6TUPLE(varph->vmac.mac), 31.734 - NIPQUAD(varph->addr)); 31.735 + VarpAddr_ntoa(&varph->addr, addrbuf)); 31.736 varp_dprint(); 31.737 } 31.738 - switch(ntohs(varph->vnetmsghdr.opcode)){ 31.739 +#endif 31.740 + switch(ntohs(varph->hdr.opcode)){ 31.741 case VARP_OP_REQUEST: 31.742 err = varp_handle_request(skb, varph); 31.743 break; 31.744 @@ -1100,8 +1192,8 @@ int varp_handle_message(struct sk_buff * 31.745 err = varp_handle_announce(skb, varph); 31.746 break; 31.747 default: 31.748 - wprintf("> Unknown opcode: %d \n", ntohs(varph->vnetmsghdr.opcode)); 31.749 - break; 31.750 + wprintf("> Unknown opcode: %d \n", ntohs(varph->hdr.opcode)); 31.751 + break; 31.752 } 31.753 exit: 31.754 if(mine) err = 1; 31.755 @@ -1112,30 +1204,32 @@ int varp_handle_message(struct sk_buff * 31.756 /** Send an outgoing packet on the appropriate vnet tunnel. 31.757 * 31.758 * @param skb outgoing message 31.759 - * @param vnet vnet (host order) 31.760 + * @param vnet vnet (network order) 31.761 * @return 0 on success, error code otherwise 31.762 */ 31.763 -int varp_output(struct sk_buff *skb, u32 vnet){ 31.764 +int varp_output(struct sk_buff *skb, VnetId *vnet){ 31.765 int err = 0; 31.766 unsigned char *mac = NULL; 31.767 Vmac *vmac = NULL; 31.768 VarpEntry *ventry = NULL; 31.769 31.770 - dprintf("> skb=%p vnet=%u\n", skb, vnet); 31.771 + dprintf(">\n"); 31.772 if(!varp_table){ 31.773 err = -ENOSYS; 31.774 goto exit; 31.775 } 31.776 - dprintf("> skb.mac=%p\n", skb->mac.raw); 31.777 if(!skb->mac.raw){ 31.778 wprintf("> No ethhdr in skb!\n"); 31.779 err = -EINVAL; 31.780 goto exit; 31.781 } 31.782 - mac = MAC_ETH(skb)->h_dest; 31.783 + mac = eth_hdr(skb)->h_dest; 31.784 vmac = (Vmac*)mac; 31.785 if(mac_is_multicast(mac)){ 31.786 - err = vnet_tunnel_send(vnet, varp_mcast_addr, skb); 31.787 + VarpAddr addr = {}; 31.788 + addr.family = AF_INET; 31.789 + addr.u.ip4.s_addr = varp_mcast_addr; 31.790 + err = vnet_tunnel_send(vnet, &addr, skb); 31.791 } else { 31.792 ventry = VarpTable_lookup(varp_table, vnet, vmac); 31.793 if(!ventry){ 31.794 @@ -1165,7 +1259,7 @@ int varp_set_mcast_addr(uint32_t addr){ 31.795 int err = 0; 31.796 varp_close(); 31.797 varp_mcast_addr = addr; 31.798 - err = varp_open(varp_mcast_addr, varp_ucast_addr, varp_port); 31.799 + err = varp_open(varp_mcast_addr, varp_port); 31.800 return err; 31.801 } 31.802 31.803 @@ -1191,7 +1285,6 @@ static void varp_init_mcast_addr(char *s 31.804 */ 31.805 int varp_init(void){ 31.806 int err = 0; 31.807 - struct net_device *dev = NULL; 31.808 31.809 dprintf(">\n"); 31.810 varp_table = VarpTable_new(); 31.811 @@ -1200,18 +1293,10 @@ int varp_init(void){ 31.812 goto exit; 31.813 } 31.814 varp_init_mcast_addr(varp_mcaddr); 31.815 - err = vnet_get_device(varp_device, &dev); 31.816 - dprintf("> vnet_get_device(%s)=%d\n", varp_device, err); 31.817 - if(err) goto exit; 31.818 - err = vnet_get_device_address(dev, &varp_ucast_addr); 31.819 - dprintf("> vnet_get_device_address()=%d\n", err); 31.820 - if(err) goto exit; 31.821 varp_port = htons(VARP_PORT); 31.822 31.823 - err = varp_open(varp_mcast_addr, varp_ucast_addr, varp_port); 31.824 - dprintf("> varp_open()=%d\n", err); 31.825 + err = varp_open(varp_mcast_addr, varp_port); 31.826 exit: 31.827 - if(dev) dev_put(dev); 31.828 dprintf("< err=%d\n", err); 31.829 return err; 31.830 }
32.1 --- a/tools/vnet/vnet-module/varp.h Fri Aug 26 10:51:10 2005 +0000 32.2 +++ b/tools/vnet/vnet-module/varp.h Fri Aug 26 10:52:53 2005 +0000 32.3 @@ -19,6 +19,10 @@ 32.4 32.5 #ifndef _VNET_VARP_H 32.6 #define _VNET_VARP_H 32.7 +#include "hash_table.h" 32.8 +#include "if_varp.h" 32.9 +#include "varp_util.h" 32.10 + 32.11 32.12 #define CONFIG_VARP_GRATUITOUS 1 32.13 32.14 @@ -26,30 +30,27 @@ struct net_device; 32.15 struct sk_buff; 32.16 struct Vif; 32.17 32.18 -#define DEVICE "xen-br0" 32.19 - 32.20 extern int vnet_get_device(const char *name, struct net_device **dev); 32.21 extern int vnet_get_device_address(struct net_device *dev, u32 *addr); 32.22 32.23 extern int varp_handle_message(struct sk_buff *skb); 32.24 -extern int varp_output(struct sk_buff *skb, u32 vnet); 32.25 -extern int varp_update(int vnet, unsigned char *vmac, u32 addr); 32.26 +extern int varp_output(struct sk_buff *skb, struct VnetId *vnet); 32.27 +extern int varp_update(struct VnetId *vnet, unsigned char *vmac, struct VarpAddr *addr); 32.28 32.29 extern int varp_init(void); 32.30 extern void varp_exit(void); 32.31 32.32 -extern int varp_open(u32 mcaddr, u32 addr, u16 port); 32.33 +extern int varp_open(u32 mcaddr, u16 port); 32.34 extern void varp_close(void); 32.35 extern int varp_set_mcast_addr(u32 addr); 32.36 32.37 extern void varp_print(void); 32.38 +extern void varp_flush(void); 32.39 32.40 extern int varp_announce_vif(struct net_device *dev, struct Vif *vif); 32.41 -//extern int varp_announce_vifs(struct net_device *dev, struct task_struct *domain); 32.42 32.43 extern u32 varp_mcast_addr; 32.44 32.45 - 32.46 /* MAC broadcast addr is ff-ff-ff-ff-ff-ff (all 1's). 32.47 * MAC multicast addr has low bit 1, i.e. 01-00-00-00-00-00. 32.48 */
33.1 --- a/tools/vnet/vnet-module/varp_socket.c Fri Aug 26 10:51:10 2005 +0000 33.2 +++ b/tools/vnet/vnet-module/varp_socket.c Fri Aug 26 10:52:53 2005 +0000 33.3 @@ -177,7 +177,7 @@ int getsockname(int fd, struct sockaddr 33.4 33.5 /*============================================================================*/ 33.6 /** Socket flags. */ 33.7 -enum { 33.8 +enum VsockFlag { 33.9 VSOCK_REUSE = 1, 33.10 VSOCK_BIND = 2, 33.11 VSOCK_CONNECT = 4, 33.12 @@ -256,28 +256,13 @@ int setsock_broadcast(int sock, int bcas 33.13 */ 33.14 int setsock_multicast(int sock, uint32_t saddr){ 33.15 int err = 0; 33.16 - struct net_device *dev = NULL; 33.17 - u32 addr = 0; 33.18 struct ip_mreqn mreq = {}; 33.19 int mloop = 0; 33.20 33.21 - err = vnet_get_device(DEVICE, &dev); 33.22 - if(err){ 33.23 - eprintf("> error getting device: %d %d\n", err, errno); 33.24 - goto exit; 33.25 - } 33.26 - err = vnet_get_device_address(dev, &addr); 33.27 - if(err){ 33.28 - eprintf("> error getting device address: %d %d\n", err, errno); 33.29 - goto exit; 33.30 - } 33.31 // See 'man 7 ip' for these options. 33.32 mreq.imr_multiaddr.s_addr = saddr; // IP multicast address. 33.33 - //mreq.imr_address.s_addr = addr; // Interface IP address. 33.34 mreq.imr_address.s_addr = INADDR_ANY; // Interface IP address. 33.35 mreq.imr_ifindex = 0; // Interface index (0 means any). 33.36 - dprintf("> saddr=%u.%u.%u.%u addr=%u.%u.%u.%u ifindex=%d\n", 33.37 - NIPQUAD(saddr), NIPQUAD(addr), mreq.imr_ifindex); 33.38 err = setsockopt(sock, SOL_IP, IP_MULTICAST_LOOP, &mloop, sizeof(mloop)); 33.39 if(err < 0){ 33.40 eprintf("> setsockopt IP_MULTICAST_LOOP: %d %d\n", err, errno); 33.41 @@ -305,7 +290,7 @@ int setsock_multicast_ttl(int sock, uint 33.42 } 33.43 33.44 /** Create a socket. 33.45 - * The flags can include VSOCK_REUSE, VSOCK_BROADCAST, VSOCK_CONNECT. 33.46 + * The flags can include values from enum VsockFlag. 33.47 * 33.48 * @param socktype socket type 33.49 * @param saddr address 33.50 @@ -368,19 +353,15 @@ int create_socket(int socktype, uint32_t 33.51 /** Open the varp multicast socket. 33.52 * 33.53 * @param mcaddr multicast address 33.54 - * @param saddr address 33.55 * @param port port 33.56 * @param val return parameter for the socket 33.57 * @return 0 on success, error code otherwise 33.58 */ 33.59 -int varp_mcast_open(uint32_t mcaddr, uint32_t saddr, uint16_t port, int *val){ 33.60 +int varp_mcast_open(uint32_t mcaddr, uint16_t port, int *val){ 33.61 int err = 0; 33.62 int flags = VSOCK_REUSE; 33.63 int multicast = MULTICAST(mcaddr); 33.64 int sock = 0; 33.65 - struct sockaddr_in addr_in; 33.66 - struct sockaddr *addr = (struct sockaddr *)&addr_in; 33.67 - int addr_n = sizeof(addr_in); 33.68 33.69 dprintf(">\n"); 33.70 flags |= VSOCK_MULTICAST; 33.71 @@ -392,23 +373,6 @@ int varp_mcast_open(uint32_t mcaddr, uin 33.72 err = setsock_multicast_ttl(sock, 1); 33.73 if(err < 0) goto exit; 33.74 } 33.75 - if(0){ 33.76 - addr_in.sin_family = AF_INET; 33.77 - addr_in.sin_addr.s_addr = saddr; 33.78 - addr_in.sin_port = port; 33.79 - err = bind(sock, addr, addr_n); 33.80 - if(err < 0){ 33.81 - eprintf("> bind: %d %d\n", err, errno); 33.82 - goto exit; 33.83 - } 33.84 - } 33.85 - if(0){ 33.86 - struct sockaddr_in self = {}; 33.87 - int self_n; 33.88 - getsockname(sock, (struct sockaddr *)&self, &self_n); 33.89 - dprintf("> sockname sock=%d addr=%u.%u.%u.%u port=%d\n", 33.90 - sock, NIPQUAD(saddr), ntohs(port)); 33.91 - } 33.92 exit: 33.93 if(err){ 33.94 shutdown(sock, 2); 33.95 @@ -427,7 +391,7 @@ int varp_mcast_open(uint32_t mcaddr, uin 33.96 */ 33.97 int varp_ucast_open(uint32_t addr, u16 port, int *val){ 33.98 int err = 0; 33.99 - int flags = VSOCK_BIND | VSOCK_REUSE; 33.100 + int flags = (VSOCK_BIND | VSOCK_REUSE); 33.101 dprintf(">\n"); 33.102 err = create_socket(SOCK_DGRAM, addr, port, flags, val); 33.103 dprintf("< err=%d val=%d\n", err, *val); 33.104 @@ -536,7 +500,6 @@ int varp_main(void *arg){ 33.105 err = sock_add_wait_queue(varp_mcast_sock, &mcast_wait); 33.106 err = sock_add_wait_queue(varp_ucast_sock, &ucast_wait); 33.107 for(n = 1; atomic_read(&varp_run) == 1; n++){ 33.108 - //dprintf("> n=%d\n", n); 33.109 count = 0; 33.110 count += handle_sock_skb(varp_mcast_sock); 33.111 count += handle_sock_skb(varp_ucast_sock); 33.112 @@ -609,20 +572,18 @@ void varp_close(void){ 33.113 /** Open the varp sockets and start the thread handling them. 33.114 * 33.115 * @param mcaddr multicast address 33.116 - * @param addr unicast address 33.117 * @param port port 33.118 * @return 0 on success, error code otherwise 33.119 */ 33.120 -int varp_open(u32 mcaddr, u32 addr, u16 port){ 33.121 +int varp_open(u32 mcaddr, u16 port){ 33.122 int err = 0; 33.123 mm_segment_t oldfs; 33.124 33.125 //MOD_INC_USE_COUNT; 33.126 - dprintf("> mcaddr=%u.%u.%u.%u addr=%u.%u.%u.%u port=%u\n", 33.127 - NIPQUAD(mcaddr), NIPQUAD(addr), ntohs(port)); 33.128 - //MOD_INC_USE_COUNT; 33.129 + dprintf("> mcaddr=%u.%u.%u.%u port=%u\n", 33.130 + NIPQUAD(mcaddr), ntohs(port)); 33.131 oldfs = change_fs(KERNEL_DS); 33.132 - err = varp_mcast_open(mcaddr, addr, port, &varp_mcast_sock); 33.133 + err = varp_mcast_open(mcaddr, port, &varp_mcast_sock); 33.134 if(err < 0 ) goto exit; 33.135 err = varp_ucast_open(INADDR_ANY, port, &varp_ucast_sock); 33.136 if(err < 0 ) goto exit;
34.1 --- a/tools/vnet/vnet-module/vif.c Fri Aug 26 10:51:10 2005 +0000 34.2 +++ b/tools/vnet/vnet-module/vif.c Fri Aug 26 10:52:53 2005 +0000 34.3 @@ -22,6 +22,7 @@ 34.4 #include <linux/module.h> 34.5 #include <linux/init.h> 34.6 #include <linux/string.h> 34.7 +#include <linux/version.h> 34.8 34.9 #include <linux/net.h> 34.10 #include <linux/in.h> 34.11 @@ -33,11 +34,14 @@ 34.12 #include <net/protocol.h> 34.13 #include <net/route.h> 34.14 #include <linux/skbuff.h> 34.15 +#include <linux/spinlock.h> 34.16 34.17 #include <etherip.h> 34.18 #include <if_varp.h> 34.19 #include <vnet_dev.h> 34.20 #include <vif.h> 34.21 +#include <varp.h> 34.22 + 34.23 #include "allocate.h" 34.24 #include "hash_table.h" 34.25 #include "sys_net.h" 34.26 @@ -50,6 +54,27 @@ 34.27 34.28 /** Table of vifs indexed by VifKey. */ 34.29 HashTable *vif_table = NULL; 34.30 +rwlock_t vif_table_lock = RW_LOCK_UNLOCKED; 34.31 + 34.32 +#define vif_read_lock(flags) read_lock_irqsave(&vif_table_lock, (flags)) 34.33 +#define vif_read_unlock(flags) read_unlock_irqrestore(&vif_table_lock, (flags)) 34.34 +#define vif_write_lock(flags) write_lock_irqsave(&vif_table_lock, (flags)) 34.35 +#define vif_write_unlock(flags) write_unlock_irqrestore(&vif_table_lock, (flags)) 34.36 + 34.37 +void vif_print(void){ 34.38 + HashTable_for_decl(entry); 34.39 + Vif *vif; 34.40 + unsigned long flags; 34.41 + char vnetbuf[VNET_ID_BUF]; 34.42 + 34.43 + vif_read_lock(flags); 34.44 + HashTable_for_each(entry, vif_table){ 34.45 + vif = entry->value; 34.46 + printk(KERN_INFO "VIF(vnet=%s vmac=" MACFMT ")\n", 34.47 + VnetId_ntoa(&vif->vnet, vnetbuf), MAC6TUPLE(vif->vmac.mac)); 34.48 + } 34.49 + vif_read_unlock(flags); 34.50 +} 34.51 34.52 void vif_decref(Vif *vif){ 34.53 if(!vif) return; 34.54 @@ -71,19 +96,12 @@ void vif_incref(Vif *vif){ 34.55 */ 34.56 Hashcode vif_key_hash_fn(void *k){ 34.57 VifKey *key = k; 34.58 - Hashcode h; 34.59 - h = hash_2ul(key->vnet, 34.60 - (key->vmac.mac[0] << 24) | 34.61 - (key->vmac.mac[1] << 16) | 34.62 - (key->vmac.mac[2] << 8) | 34.63 - (key->vmac.mac[3] )); 34.64 - h = hash_hul(h, 34.65 - (key->vmac.mac[4] << 8) | 34.66 - (key->vmac.mac[5] )); 34.67 + Hashcode h = 0; 34.68 + h = VnetId_hash(h, &key->vnet); 34.69 + h = Vmac_hash(h, &key->vmac); 34.70 return h; 34.71 } 34.72 34.73 - 34.74 /** Test equality for keys in the vif table. 34.75 * Compares vnet and mac. 34.76 * 34.77 @@ -94,7 +112,8 @@ Hashcode vif_key_hash_fn(void *k){ 34.78 int vif_key_equal_fn(void *k1, void *k2){ 34.79 VifKey *key1 = k1; 34.80 VifKey *key2 = k2; 34.81 - return (key1->vnet == key2->vnet) && (memcmp(key1->vmac.mac, key2->vmac.mac, ETH_ALEN) == 0); 34.82 + return (VnetId_eq(&key1->vnet , &key2->vnet) && 34.83 + Vmac_eq(&key1->vmac, &key2->vmac)); 34.84 } 34.85 34.86 /** Free an entry in the vif table. 34.87 @@ -118,13 +137,13 @@ static void vif_entry_free_fn(HashTable 34.88 * @param mac MAC address 34.89 * @return 0 on success, -ENOENT otherwise 34.90 */ 34.91 -int vif_lookup(int vnet, Vmac *vmac, Vif **vif){ 34.92 +int vif_lookup(VnetId *vnet, Vmac *vmac, Vif **vif){ 34.93 int err = 0; 34.94 - VifKey key = {}; 34.95 + VifKey key = { .vnet = *vnet, .vmac = *vmac }; 34.96 HTEntry *entry = NULL; 34.97 + unsigned long flags; 34.98 34.99 - key.vnet = vnet; 34.100 - key.vmac = *vmac; 34.101 + vif_read_lock(flags); 34.102 entry = HashTable_get_entry(vif_table, &key); 34.103 if(entry){ 34.104 *vif = entry->value; 34.105 @@ -133,7 +152,7 @@ int vif_lookup(int vnet, Vmac *vmac, Vif 34.106 *vif = NULL; 34.107 err = -ENOENT; 34.108 } 34.109 - //dprintf("< err=%d addr=" IPFMT "\n", err, NIPQUAD(*coaddr)); 34.110 + vif_read_unlock(flags); 34.111 return err; 34.112 } 34.113 34.114 @@ -143,10 +162,12 @@ int vif_lookup(int vnet, Vmac *vmac, Vif 34.115 * @param mac MAC address 34.116 * @return 0 on success, negative error code otherwise 34.117 */ 34.118 -int vif_add(int vnet, Vmac *vmac, Vif **val){ 34.119 +int vif_add(VnetId *vnet, Vmac *vmac, Vif **val){ 34.120 int err = 0; 34.121 Vif *vif = NULL; 34.122 HTEntry *entry; 34.123 + unsigned long flags; 34.124 + 34.125 dprintf("> vnet=%d\n", vnet); 34.126 vif = ALLOCATE(Vif); 34.127 if(!vif){ 34.128 @@ -154,9 +175,11 @@ int vif_add(int vnet, Vmac *vmac, Vif ** 34.129 goto exit; 34.130 } 34.131 atomic_set(&vif->refcount, 1); 34.132 - vif->vnet = vnet; 34.133 + vif->vnet = *vnet; 34.134 vif->vmac = *vmac; 34.135 + vif_write_lock(flags); 34.136 entry = HashTable_add(vif_table, vif, vif); 34.137 + vif_write_unlock(flags); 34.138 if(!entry){ 34.139 err = -ENOMEM; 34.140 deallocate(vif); 34.141 @@ -177,22 +200,14 @@ int vif_add(int vnet, Vmac *vmac, Vif ** 34.142 * @param coaddr return parameter for care-of address 34.143 * @return number of entries deleted, or negative error code 34.144 */ 34.145 -int vif_remove(int vnet, Vmac *vmac){ 34.146 +int vif_remove(VnetId *vnet, Vmac *vmac){ 34.147 int err = 0; 34.148 - VifKey key = { .vnet = vnet, .vmac = *vmac }; 34.149 - //dprintf("> vnet=%d addr=%u.%u.%u.%u\n", vnet, NIPQUAD(coaddr)); 34.150 + VifKey key = { .vnet = *vnet, .vmac = *vmac }; 34.151 + unsigned long flags; 34.152 + 34.153 + vif_write_lock(flags); 34.154 err = HashTable_remove(vif_table, &key); 34.155 - //dprintf("< err=%d\n", err); 34.156 - return err; 34.157 -} 34.158 - 34.159 -int vif_find(int vnet, Vmac *vmac, int create, Vif **vif){ 34.160 - int err = 0; 34.161 - 34.162 - err = vif_lookup(vnet, vmac, vif); 34.163 - if(err && create){ 34.164 - err = vif_add(vnet, vmac, vif); 34.165 - } 34.166 + vif_write_unlock(flags); 34.167 return err; 34.168 } 34.169 34.170 @@ -200,15 +215,15 @@ void vif_purge(void){ 34.171 HashTable_clear(vif_table); 34.172 } 34.173 34.174 -int vif_create(int vnet, Vmac *vmac, Vif **vif){ 34.175 +int vif_create(VnetId *vnet, Vmac *vmac, Vif **vif){ 34.176 int err = 0; 34.177 34.178 dprintf(">\n"); 34.179 - if(!vif_lookup(vnet, vmac, vif)){ 34.180 + if(vif_lookup(vnet, vmac, vif) == 0){ 34.181 + vif_decref(*vif); 34.182 err = -EEXIST; 34.183 goto exit; 34.184 } 34.185 - dprintf("> vif_add...\n"); 34.186 err = vif_add(vnet, vmac, vif); 34.187 exit: 34.188 if(err){ 34.189 @@ -218,25 +233,6 @@ int vif_create(int vnet, Vmac *vmac, Vif 34.190 return err; 34.191 } 34.192 34.193 -/** Create a vif. 34.194 - * 34.195 - * @param vnet vnet id 34.196 - * @param mac mac address (as a string) 34.197 - * @return 0 on success, error code otherwise 34.198 - */ 34.199 -int mkvif(int vnet, char *mac){ 34.200 - int err = 0; 34.201 - Vmac vmac = {}; 34.202 - Vif *vif = NULL; 34.203 - dprintf("> vnet=%d mac=%s\n", vnet, mac); 34.204 - err = mac_aton(mac, vmac.mac); 34.205 - if(err) goto exit; 34.206 - err = vif_create(vnet, &vmac, &vif); 34.207 - exit: 34.208 - dprintf("< err=%d\n", err); 34.209 - return err; 34.210 -} 34.211 - 34.212 /** Initialize the vif table. 34.213 * 34.214 * @return 0 on success, error code otherwise 34.215 @@ -250,12 +246,9 @@ int vif_init(void){ 34.216 goto exit; 34.217 } 34.218 vif_table->entry_free_fn = vif_entry_free_fn; 34.219 - vif_table->key_hash_fn = vif_key_hash_fn; 34.220 - vif_table->key_equal_fn = vif_key_equal_fn; 34.221 + vif_table->key_hash_fn = vif_key_hash_fn; 34.222 + vif_table->key_equal_fn = vif_key_equal_fn; 34.223 34.224 - // Some vifs for testing. 34.225 - //mkvif(1, "aa:00:00:00:20:11"); 34.226 - //mkvif(2, "aa:00:00:00:20:12"); 34.227 exit: 34.228 if(err < 0) wprintf("< err=%d\n", err); 34.229 dprintf("< err=%d\n", err);
35.1 --- a/tools/vnet/vnet-module/vif.h Fri Aug 26 10:51:10 2005 +0000 35.2 +++ b/tools/vnet/vnet-module/vif.h Fri Aug 26 10:52:53 2005 +0000 35.3 @@ -24,12 +24,12 @@ struct net_device; 35.4 35.5 /** Key for entries in the vif table. */ 35.6 typedef struct VifKey { 35.7 - int vnet; 35.8 + VnetId vnet; 35.9 Vmac vmac; 35.10 } VifKey; 35.11 35.12 typedef struct Vif { 35.13 - int vnet; 35.14 + VnetId vnet; 35.15 Vmac vmac; 35.16 struct net_device *dev; 35.17 atomic_t refcount; 35.18 @@ -38,15 +38,17 @@ typedef struct Vif { 35.19 struct HashTable; 35.20 extern struct HashTable *vif_table; 35.21 35.22 +extern void vif_print(void); 35.23 + 35.24 extern void vif_decref(Vif *vif); 35.25 extern void vif_incref(Vif *vif); 35.26 35.27 -extern int vif_create(int vnet, Vmac *vmac, Vif **vif); 35.28 +extern int vif_create(struct VnetId *vnet, Vmac *vmac, Vif **vif); 35.29 35.30 -extern int vif_add(int vnet, Vmac *vmac, Vif **vif); 35.31 -extern int vif_lookup(int vnet, Vmac *vmac, Vif **vif); 35.32 -extern int vif_remove(int vnet, Vmac *vmac); 35.33 -extern int vif_find(int vnet, Vmac *vmac, int create, Vif **vif); 35.34 +extern int vif_create(VnetId *vnet, Vmac *vmac, Vif **vif); 35.35 +extern int vif_add(struct VnetId *vnet, Vmac *vmac, Vif **vif); 35.36 +extern int vif_lookup(struct VnetId *vnet, Vmac *vmac, Vif **vif); 35.37 +extern int vif_remove(struct VnetId *vnet, Vmac *vmac); 35.38 extern void vif_purge(void); 35.39 35.40 extern int vif_init(void);
36.1 --- a/tools/vnet/vnet-module/vnet.c Fri Aug 26 10:51:10 2005 +0000 36.2 +++ b/tools/vnet/vnet-module/vnet.c Fri Aug 26 10:52:53 2005 +0000 36.3 @@ -47,6 +47,7 @@ 36.4 #include <random.h> 36.5 #include <tunnel.h> 36.6 36.7 +#include <skb_util.h> 36.8 #include <vnet_dev.h> 36.9 #include <vnet.h> 36.10 #include <vif.h> 36.11 @@ -70,7 +71,7 @@ int vnet_security_default = SA_AUTH ; // 36.12 /** Key for entries in the vnet address table. */ 36.13 typedef struct VnetAddrKey { 36.14 /** Vnet id. */ 36.15 - int vnet; 36.16 + VnetId vnet; 36.17 /** MAC address. */ 36.18 unsigned char mac[ETH_ALEN]; 36.19 } VnetAddrKey; 36.20 @@ -88,7 +89,6 @@ static HashTable *vnet_table = NULL; 36.21 void Vnet_decref(Vnet *info){ 36.22 if(!info) return; 36.23 if(atomic_dec_and_test(&info->refcount)){ 36.24 - dprintf("> free vnet=%u\n", info->vnet); 36.25 vnet_dev_remove(info); 36.26 deallocate(info); 36.27 } 36.28 @@ -103,6 +103,28 @@ void Vnet_incref(Vnet *info){ 36.29 atomic_inc(&info->refcount); 36.30 } 36.31 36.32 +void Vnet_print(Vnet *info) 36.33 +{ 36.34 + char vnetbuf[VNET_ID_BUF]; 36.35 + 36.36 + printk(KERN_INFO "VNET(vnet=%s device=%s security=%c%c)\n", 36.37 + VnetId_ntoa(&info->vnet, vnetbuf), 36.38 + info->device, 36.39 + ((info->security & SA_AUTH) ? 'a' : '-'), 36.40 + ((info->security & SA_CONF) ? 'c' : '-')); 36.41 +} 36.42 + 36.43 +void vnet_print(void) 36.44 +{ 36.45 + HashTable_for_decl(entry); 36.46 + Vnet *info; 36.47 + 36.48 + HashTable_for_each(entry, vnet_table){ 36.49 + info = entry->value; 36.50 + Vnet_print(info); 36.51 + } 36.52 +} 36.53 + 36.54 /** Allocate a vnet, setting reference count to 1. 36.55 * 36.56 * @param info return parameter for vnet 36.57 @@ -129,7 +151,7 @@ int Vnet_add(Vnet *info){ 36.58 HTEntry *entry = NULL; 36.59 // Vnet_del(info->vnet); //todo: Delete existing vnet info? 36.60 Vnet_incref(info); 36.61 - entry = HashTable_add(vnet_table, HKEY(info->vnet), info); 36.62 + entry = HashTable_add(vnet_table, &info->vnet, info); 36.63 if(!entry){ 36.64 err = -ENOMEM; 36.65 Vnet_decref(info); 36.66 @@ -142,8 +164,8 @@ int Vnet_add(Vnet *info){ 36.67 * @param vnet id of vnet to remove 36.68 * @return number of vnets removed 36.69 */ 36.70 -int Vnet_del(vnetid_t vnet){ 36.71 - return HashTable_remove(vnet_table, HKEY(vnet)); 36.72 +int Vnet_del(VnetId *vnet){ 36.73 + return HashTable_remove(vnet_table, vnet); 36.74 } 36.75 36.76 /** Lookup a vnet by id. 36.77 @@ -153,17 +175,14 @@ int Vnet_del(vnetid_t vnet){ 36.78 * @param info return parameter for vnet 36.79 * @return 0 on sucess, -ENOENT if no vnet found 36.80 */ 36.81 -int Vnet_lookup(vnetid_t vnet, Vnet **info){ 36.82 +int Vnet_lookup(VnetId *vnet, Vnet **info){ 36.83 int err = 0; 36.84 - dprintf("> vnet=%u info=%p\n", vnet, info); 36.85 - dprintf("> vnet_table=%p\n",vnet_table); 36.86 - *info = HashTable_get(vnet_table, HKEY(vnet)); 36.87 + *info = HashTable_get(vnet_table, vnet); 36.88 if(*info){ 36.89 Vnet_incref(*info); 36.90 } else { 36.91 err = -ENOENT; 36.92 } 36.93 - dprintf("< err=%d\n", err); 36.94 return err; 36.95 } 36.96 36.97 @@ -191,24 +210,35 @@ static void vnet_entry_free_fn(HashTable 36.98 */ 36.99 static int vnet_setup(void){ 36.100 int err = 0; 36.101 - int i, n = 5; //20; 36.102 + int i, n = 3; 36.103 int security = vnet_security_default; 36.104 + uint32_t vnetid; 36.105 Vnet *vnet; 36.106 36.107 - dprintf(">\n"); 36.108 for(i=0; i<n; i++){ 36.109 err = Vnet_alloc(&vnet); 36.110 if(err) break; 36.111 - vnet->vnet = VNET_VIF + i; 36.112 - vnet->security = (vnet->vnet > 10 ? security : 0); 36.113 - //err = Vnet_add(vnet); 36.114 + vnetid = VNET_VIF + i; 36.115 + vnet->vnet = toVnetId(vnetid); 36.116 + sprintf(vnet->device, "vnif%04x", vnetid); 36.117 + vnet->security = (vnetid > 10 ? security : 0); 36.118 err = Vnet_create(vnet); 36.119 if(err) break; 36.120 } 36.121 - dprintf("< err=%d\n", err); 36.122 return err; 36.123 } 36.124 36.125 +int vnet_key_equal_fn(void *k1, void *k2){ 36.126 + VnetId *key1 = k1; 36.127 + VnetId *key2 = k2; 36.128 + return VnetId_eq(key1, key2); 36.129 +} 36.130 + 36.131 +Hashcode vnet_key_hash_fn(void *k){ 36.132 + VnetId *key = k; 36.133 + return VnetId_hash(0, key); 36.134 +} 36.135 + 36.136 /** Initialize the vnet table and the physical vnet. 36.137 * 36.138 * @return 0 on success, error code otherwise 36.139 @@ -216,18 +246,18 @@ static int vnet_setup(void){ 36.140 int vnet_init(void){ 36.141 int err = 0; 36.142 36.143 - dprintf(">\n"); 36.144 vnet_table = HashTable_new(0); 36.145 - dprintf("> vnet_table=%p\n", vnet_table); 36.146 if(!vnet_table){ 36.147 err = -ENOMEM; 36.148 goto exit; 36.149 } 36.150 + vnet_table->key_equal_fn = vnet_key_equal_fn; 36.151 + vnet_table->key_hash_fn = vnet_key_hash_fn; 36.152 vnet_table->entry_free_fn = vnet_entry_free_fn; 36.153 36.154 err = Vnet_alloc(&vnet_physical); 36.155 if(err) goto exit; 36.156 - vnet_physical->vnet = VNET_PHYS; 36.157 + vnet_physical->vnet = toVnetId(VNET_PHYS); 36.158 vnet_physical->security = 0; 36.159 err = Vnet_add(vnet_physical); 36.160 if(err) goto exit; 36.161 @@ -237,7 +267,6 @@ int vnet_init(void){ 36.162 if(err) goto exit; 36.163 err = vif_init(); 36.164 exit: 36.165 - if(err < 0) wprintf("< err=%d\n", err); 36.166 return err; 36.167 } 36.168 36.169 @@ -248,50 +277,28 @@ void vnet_exit(void){ 36.170 vnet_table = NULL; 36.171 } 36.172 36.173 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 36.174 - 36.175 -static inline int skb_route(struct sk_buff *skb, struct rtable **prt){ 36.176 - int err = 0; 36.177 - struct flowi fl = { 36.178 - .oif = skb->dev->ifindex, 36.179 - .nl_u = { 36.180 - .ip4_u = { 36.181 - .daddr = skb->nh.iph->daddr, 36.182 - .saddr = skb->nh.iph->saddr, 36.183 - .tos = skb->nh.iph->tos, 36.184 - } 36.185 - } 36.186 - }; 36.187 - 36.188 - err = ip_route_output_key(prt, &fl); 36.189 - return err; 36.190 -} 36.191 - 36.192 -#else 36.193 - 36.194 -static inline int skb_route(struct sk_buff *skb, struct rtable **prt){ 36.195 - int err = 0; 36.196 - struct rt_key key = { }; 36.197 - key.dst = skb->nh.iph->daddr; 36.198 - key.src = skb->nh.iph->saddr; 36.199 - key.tos = skb->nh.iph->tos; 36.200 - key.oif = skb->dev->ifindex; 36.201 - err = ip_route_output_key(prt, &key); 36.202 - return err; 36.203 -} 36.204 - 36.205 -#endif 36.206 - 36.207 inline int skb_xmit(struct sk_buff *skb){ 36.208 int err = 0; 36.209 struct rtable *rt = NULL; 36.210 36.211 - dprintf("> skb=%p dev=%s\n", skb, skb->dev->name); 36.212 - 36.213 + dprintf(">\n"); 36.214 skb->protocol = htons(ETH_P_IP); 36.215 err = skb_route(skb, &rt); 36.216 - if(err) goto exit; 36.217 + if(err){ 36.218 + wprintf("> skb_route=%d\n", err); 36.219 + wprintf("> dev=%s idx=%d src=%u.%u.%u.%u dst=%u.%u.%u.%u tos=%d\n", 36.220 + (skb->dev ? skb->dev->name : "???"), 36.221 + (skb->dev ? skb->dev->ifindex : -1), 36.222 + NIPQUAD(skb->nh.iph->saddr), 36.223 + NIPQUAD(skb->nh.iph->daddr), 36.224 + skb->nh.iph->tos); 36.225 + 36.226 + goto exit; 36.227 + } 36.228 skb->dst = &rt->u.dst; 36.229 + if(!skb->dev){ 36.230 + skb->dev = rt->u.dst.dev; 36.231 + } 36.232 36.233 ip_select_ident(skb->nh.iph, &rt->u.dst, NULL); 36.234 36.235 @@ -317,39 +324,27 @@ inline int skb_xmit(struct sk_buff *skb) 36.236 * 36.237 * @todo fixme 36.238 */ 36.239 -int vnet_skb_send(struct sk_buff *skb, u32 vnet){ 36.240 +int vnet_skb_send(struct sk_buff *skb, VnetId *vnet){ 36.241 int err = 0; 36.242 - Vif *vif = NULL; 36.243 + VnetId vnet_phys = toVnetId(VNET_PHYS); 36.244 36.245 - dprintf("> skb=%p vnet=%u\n", skb, vnet); 36.246 - if(vnet == VNET_PHYS || !vnet){ 36.247 - // For completeness, send direct to the network. 36.248 - if(skb->dev){ 36.249 - err = skb_xmit(skb); 36.250 - } else { 36.251 - // Can't assume eth0 - might be nbe-br or other. Need to route. 36.252 - struct net_device *dev = NULL; 36.253 - err = vnet_get_device(DEVICE, &dev); 36.254 - if(err) goto exit; 36.255 - skb->dev = dev; 36.256 - err = skb_xmit(skb); 36.257 - dev_put(dev); 36.258 - } 36.259 + dprintf(">\n"); 36.260 + skb->dev = NULL; 36.261 + if(!vnet || VnetId_eq(vnet, &vnet_phys)){ 36.262 + // No vnet or physical vnet, send direct to the network. 36.263 + skb_xmit(skb); 36.264 } else { 36.265 - dprintf("> varp_output\n"); 36.266 err = varp_output(skb, vnet); 36.267 } 36.268 - //dprintf("< err=%d\n", err); 36.269 - exit: 36.270 - if(vif) vif_decref(vif); 36.271 dprintf("< err=%d\n", err); 36.272 return err; 36.273 } 36.274 36.275 /** Receive an skb for a vnet. 36.276 + * We make the skb come out of the vif for the vnet, and 36.277 + * let ethernet bridging forward it to related interfaces. 36.278 * If the dest is broadcast, goes to all vifs on the vnet. 36.279 - * If the dest is unicast, goes to addressed vif on vnet. 36.280 - * For each vif we set the packet dev and receive the packet. 36.281 + * If the dest is unicast, goes to the addressed vif on the vnet. 36.282 * 36.283 * The packet must have skb->mac.raw set and skb->data must point 36.284 * after the device (ethernet) header. 36.285 @@ -359,139 +354,19 @@ int vnet_skb_send(struct sk_buff *skb, u 36.286 * @param vmac packet vmac 36.287 * @return 0 on success, error code otherwise 36.288 */ 36.289 -#if 1 36.290 -int vnet_skb_recv(struct sk_buff *skb, u32 vnet, Vmac *vmac){ 36.291 - // Receive the skb for a vnet. 36.292 - // We make the skb come out of the vif for the vnet, and 36.293 - // let ethernet bridging forward it to related interfaces. 36.294 +int vnet_skb_recv(struct sk_buff *skb, VnetId *vnet, Vmac *vmac){ 36.295 int err = 0; 36.296 Vnet *info = NULL; 36.297 36.298 - dprintf("> vnet=%u mac=%s\n", vnet, mac_ntoa(vmac->mac)); 36.299 err = Vnet_lookup(vnet, &info); 36.300 if(err) goto exit; 36.301 skb->dev = info->dev; 36.302 - dprintf("> netif_rx dev=%s\n", skb->dev->name); 36.303 netif_rx(skb); 36.304 exit: 36.305 if(info) Vnet_decref(info); 36.306 if(err){ 36.307 - kfree_skb(skb); 36.308 - } 36.309 - dprintf("< err=%d\n", err); 36.310 - return err; 36.311 -} 36.312 - 36.313 -#else 36.314 -int vnet_skb_recv(struct sk_buff *skb, u32 vnet, Vmac *vmac){ 36.315 - int err = 0; 36.316 - Vif *vif = NULL; 36.317 - 36.318 - dprintf("> vnet=%u mac=%s\n", vnet, mac_ntoa(vmac->mac)); 36.319 - if(mac_is_multicast(vmac->mac)){ 36.320 - HashTable_for_decl(entry); 36.321 - int count = 0; 36.322 - struct sk_buff *new_skb; 36.323 - 36.324 - HashTable_for_each(entry, vif_table){ 36.325 - vif = entry->value; 36.326 - if(vif->vnet != vnet) continue; 36.327 - count++; 36.328 - new_skb = skb_copy(skb, GFP_ATOMIC); 36.329 - if(!new_skb) break; 36.330 - new_skb->dev = vif->dev; 36.331 - dprintf("> %d] netif_rx dev=%s\n", count, new_skb->dev->name); 36.332 - netif_rx(new_skb); 36.333 - } 36.334 kfree_skb(skb); 36.335 - } else { 36.336 - err = vif_lookup(vnet, vmac, &vif); 36.337 - if(err){ 36.338 - kfree_skb(skb); 36.339 - goto exit; 36.340 - } 36.341 - skb->dev = vif->dev; 36.342 - dprintf("> netif_rx dev=%s\n", skb->dev->name); 36.343 - netif_rx(skb); 36.344 } 36.345 - exit: 36.346 - dprintf("< err=%d\n", err); 36.347 - return err; 36.348 -} 36.349 -#endif 36.350 - 36.351 -/** Check validity of an incoming IP frame. 36.352 - * 36.353 - * @param skb frame 36.354 - * @return 0 if ok, error code otherwise 36.355 - * 36.356 - * @todo fixme Can prob skip most of this because linux will have done it. 36.357 - * @todo Only need the vnet skb context check. 36.358 - */ 36.359 -int check_ip_frame(struct sk_buff *skb){ 36.360 - int err = -EINVAL; 36.361 - struct iphdr* iph; 36.362 - struct net_device *dev; 36.363 - __u32 len; 36.364 - __u16 check; 36.365 - 36.366 -#if 0 36.367 - if(skb->context){ 36.368 - // Todo: After ESP want to skip most checks (including checksum), 36.369 - // Todo: but in general may not want to skip all checks on detunnel. 36.370 - //dprintf("> Skip check, has context\n"); 36.371 - err = 0; 36.372 - goto exit; 36.373 - } 36.374 -#endif 36.375 - // Check we have enough for an ip header - the skb passed should 36.376 - // have data pointing at the eth header and skb->len should include 36.377 - // that. skb->nh should already have been set. Let the indvidual 36.378 - // protocol handlers worry about the exact ip header len 36.379 - // (i.e. whether any ip options are set). 36.380 - dev = skb->dev; 36.381 - 36.382 - if(skb->len < ETH_HLEN + sizeof(struct iphdr)){ 36.383 - wprintf("> packet too short for ip header\n"); 36.384 - goto exit; 36.385 - } 36.386 - 36.387 - iph = skb->nh.iph; 36.388 - /* 36.389 - * RFC1122: 3.1.2.2 MUST silently discard any IP frame that fails the checksum. 36.390 - * 36.391 - * Is the datagram acceptable? 36.392 - * 36.393 - * 1. Length at least the size of an ip header 36.394 - * 2. Version of 4 36.395 - * 3. Checksums correctly. [Speed optimisation for later, skip loopback checksums] 36.396 - * 4. Doesn't have a bogus length 36.397 - */ 36.398 - if (iph->ihl < 5 || iph->version != 4){ 36.399 - wprintf("> len and version check failed\n"); 36.400 - goto exit; 36.401 - } 36.402 - if(skb->len < ETH_HLEN + (iph->ihl << 2)){ 36.403 - wprintf("> packet too short for given ihl\n"); 36.404 - goto exit; 36.405 - } 36.406 - 36.407 - check = iph->check; 36.408 - //iph->check = 0; 36.409 - //iph->check = compute_cksum((__u16 *)iph, (iph->ihl << 1)); 36.410 - if(iph->check != check){ 36.411 - wprintf("> invalid checksum\n"); 36.412 - goto exit; 36.413 - } 36.414 - 36.415 - len = ntohs(iph->tot_len); 36.416 - if (skb->len < len + ETH_HLEN || len < (iph->ihl << 2)){ 36.417 - wprintf("> packet too short for tot_len\n"); 36.418 - goto exit; 36.419 - } 36.420 - skb->h.raw = skb->nh.raw + (iph->ihl << 2); 36.421 - err = 0; 36.422 - exit: 36.423 return err; 36.424 } 36.425 36.426 @@ -539,14 +414,13 @@ int vnet_sa_create(u32 spi, int protocol 36.427 * 36.428 * @todo Need to check that the sa provides the correct security level. 36.429 */ 36.430 -int vnet_check_context(int vnet, SkbContext *context, Vnet **val){ 36.431 +int vnet_check_context(VnetId *vnet, SkbContext *context, Vnet **val){ 36.432 int err = 0; 36.433 Vnet *info = NULL; 36.434 SAState *sa = NULL; 36.435 36.436 err = Vnet_lookup(vnet, &info); 36.437 if(err){ 36.438 - wprintf("> No vnet %d\n", vnet); 36.439 goto exit; 36.440 } 36.441 if(!info->security) goto exit; 36.442 @@ -556,7 +430,8 @@ int vnet_check_context(int vnet, SkbCont 36.443 goto exit; 36.444 } 36.445 if(context->protocol != IPPROTO_ESP){ 36.446 - wprintf("> Invalid protocol: wanted %d, got %d\n", IPPROTO_ESP, context->protocol); 36.447 + wprintf("> Invalid protocol: wanted %d, got %d\n", 36.448 + IPPROTO_ESP, context->protocol); 36.449 goto exit; 36.450 } 36.451 sa = context->data; 36.452 @@ -586,13 +461,11 @@ static int sa_tunnel_open(Tunnel *tunnel 36.453 */ 36.454 static void sa_tunnel_close(Tunnel *tunnel){ 36.455 SAState *sa; 36.456 - dprintf(">\n"); 36.457 if(!tunnel) return; 36.458 sa = tunnel->data; 36.459 if(!sa) return; 36.460 SAState_decref(sa); 36.461 tunnel->data = NULL; 36.462 - dprintf("<\n"); 36.463 } 36.464 36.465 /** Packet send function for SA tunnels. 36.466 @@ -604,7 +477,6 @@ static void sa_tunnel_close(Tunnel *tunn 36.467 static int sa_tunnel_send(Tunnel *tunnel, struct sk_buff *skb){ 36.468 int err = -EINVAL; 36.469 SAState *sa; 36.470 - //dprintf("> tunnel=%p\n", tunnel); 36.471 if(!tunnel){ 36.472 wprintf("> Null tunnel!\n"); 36.473 goto exit; 36.474 @@ -616,7 +488,6 @@ static int sa_tunnel_send(Tunnel *tunnel 36.475 } 36.476 err = SAState_send(sa, skb, tunnel->base); 36.477 exit: 36.478 - //dprintf("< err=%d\n", err); 36.479 return err; 36.480 } 36.481 36.482 @@ -638,7 +509,7 @@ TunnelType *sa_tunnel_type = &_sa_tunnel 36.483 * @param tunnel return parameter 36.484 * @return 0 on success, error code otherwise 36.485 */ 36.486 -int vnet_tunnel_open(u32 vnet, u32 addr, Tunnel **tunnel){ 36.487 +int vnet_tunnel_open(VnetId *vnet, VarpAddr *addr, Tunnel **tunnel){ 36.488 extern TunnelType *etherip_tunnel_type; 36.489 int err = 0; 36.490 Vnet *info = NULL; 36.491 @@ -646,20 +517,17 @@ int vnet_tunnel_open(u32 vnet, u32 addr, 36.492 Tunnel *sa_tunnel = NULL; 36.493 Tunnel *etherip_tunnel = NULL; 36.494 36.495 - dprintf("> vnet=%u addr=" IPFMT "\n", vnet, NIPQUAD(addr)); 36.496 err = Vnet_lookup(vnet, &info); 36.497 - dprintf("> Vnet_lookup=%d\n", err); 36.498 if(err) goto exit; 36.499 if(info->security){ 36.500 SAState *sa = NULL; 36.501 - dprintf("> security=%d\n", info->security); 36.502 + //FIXME: Assuming IPv4 for now. 36.503 + u32 ipaddr = addr->u.ip4.s_addr; 36.504 err = Tunnel_create(sa_tunnel_type, vnet, addr, base_tunnel, &sa_tunnel); 36.505 if(err) goto exit; 36.506 - dprintf("> sa_tunnel=%p\n", sa_tunnel); 36.507 - err = sa_create(info->security, 0, IPPROTO_ESP, addr, &sa); 36.508 + err = sa_create(info->security, 0, IPPROTO_ESP, ipaddr, &sa); 36.509 if(err) goto exit; 36.510 sa_tunnel->data = sa; 36.511 - dprintf("> sa=%p\n", sa); 36.512 base_tunnel = sa_tunnel; 36.513 } 36.514 err = Tunnel_create(etherip_tunnel_type, vnet, addr, base_tunnel, ðerip_tunnel); 36.515 @@ -673,7 +541,6 @@ int vnet_tunnel_open(u32 vnet, u32 addr, 36.516 } else { 36.517 *tunnel = etherip_tunnel; 36.518 } 36.519 - dprintf("< err=%d\n", err); 36.520 return err; 36.521 } 36.522 36.523 @@ -685,14 +552,12 @@ int vnet_tunnel_open(u32 vnet, u32 addr, 36.524 * @param tunnel return parameter 36.525 * @return 0 on success, error code otherwise 36.526 */ 36.527 -int vnet_tunnel_lookup(u32 vnet, u32 addr, Tunnel **tunnel){ 36.528 +int vnet_tunnel_lookup(VnetId *vnet, VarpAddr *addr, Tunnel **tunnel){ 36.529 int err = 0; 36.530 - dprintf("> vnet=%d addr=" IPFMT "\n", vnet, NIPQUAD(addr)); 36.531 *tunnel = Tunnel_lookup(vnet, addr); 36.532 if(!*tunnel){ 36.533 err = vnet_tunnel_open(vnet, addr, tunnel); 36.534 } 36.535 - dprintf("< err=%d\n", err); 36.536 return err; 36.537 } 36.538 36.539 @@ -703,16 +568,14 @@ int vnet_tunnel_lookup(u32 vnet, u32 add 36.540 * @param skb packet 36.541 * @return 0 on success, error code otherwise 36.542 */ 36.543 -int vnet_tunnel_send(vnetid_t vnet, vnetaddr_t addr, struct sk_buff *skb){ 36.544 +int vnet_tunnel_send(VnetId *vnet, VarpAddr *addr, struct sk_buff *skb){ 36.545 int err = 0; 36.546 Tunnel *tunnel = NULL; 36.547 - dprintf("> vnet=%u addr=" IPFMT "\n", vnet, NIPQUAD(addr)); 36.548 err = vnet_tunnel_lookup(vnet, addr, &tunnel); 36.549 if(err) goto exit; 36.550 err = Tunnel_send(tunnel, skb); 36.551 Tunnel_decref(tunnel); 36.552 exit: 36.553 - dprintf("< err=%d\n", err); 36.554 return err; 36.555 } 36.556 36.557 @@ -722,7 +585,7 @@ static void __exit vnet_module_exit(void 36.558 vnet_exit(); 36.559 esp_module_exit(); 36.560 etherip_module_exit(); 36.561 - tunnel_module_init(); 36.562 + tunnel_module_exit(); 36.563 random_module_exit(); 36.564 } 36.565 36.566 @@ -753,12 +616,13 @@ static int __init vnet_module_init(void) 36.567 sa_algorithm_probe_all(); 36.568 err = sa_table_init(); 36.569 if(err) wprintf("> sa_table_init err=%d\n", err); 36.570 + if(err) goto exit; 36.571 ProcFS_init(); 36.572 exit: 36.573 if(err < 0){ 36.574 vnet_module_exit(); 36.575 + wprintf("< err=%d\n", err); 36.576 } 36.577 - if(err < 0) wprintf("< err=%d\n", err); 36.578 return err; 36.579 } 36.580
37.1 --- a/tools/vnet/vnet-module/vnet.h Fri Aug 26 10:51:10 2005 +0000 37.2 +++ b/tools/vnet/vnet-module/vnet.h Fri Aug 26 10:52:53 2005 +0000 37.3 @@ -29,17 +29,15 @@ struct Vmac; 37.4 struct Vif; 37.5 struct net_device; 37.6 37.7 -typedef uint32_t vnetid_t; 37.8 -typedef uint32_t vnetaddr_t; 37.9 - 37.10 /** Vnet property record. */ 37.11 typedef struct Vnet { 37.12 /** Reference count. */ 37.13 atomic_t refcount; 37.14 /** Vnet id. */ 37.15 - vnetid_t vnet; 37.16 + struct VnetId vnet; 37.17 /** Security flag. If true the vnet requires ESP. */ 37.18 int security; 37.19 + char device[IFNAMSIZ]; 37.20 37.21 struct net_device *dev; 37.22 struct net_device *bridge; 37.23 @@ -51,31 +49,29 @@ typedef struct Vnet { 37.24 int recursion; 37.25 } Vnet; 37.26 37.27 -extern int Vnet_lookup(vnetid_t id, Vnet **vnet); 37.28 -extern int Vnet_add(Vnet *vnet); 37.29 -extern int Vnet_del(vnetid_t vnet); 37.30 -extern void Vnet_incref(Vnet *); 37.31 -extern void Vnet_decref(Vnet *); 37.32 -extern int Vnet_alloc(Vnet **vnet); 37.33 +extern void vnet_print(void); 37.34 +extern void Vnet_print(Vnet *info); 37.35 + 37.36 +extern int Vnet_lookup(struct VnetId *vnet, struct Vnet **info); 37.37 +extern int Vnet_add(struct Vnet *info); 37.38 +extern int Vnet_del(struct VnetId *vnet); 37.39 +extern void Vnet_incref(struct Vnet *info); 37.40 +extern void Vnet_decref(struct Vnet *info); 37.41 +extern int Vnet_alloc(struct Vnet **info); 37.42 extern Vnet *vnet_physical; 37.43 37.44 extern int skb_xmit(struct sk_buff *skb); 37.45 -extern int vnet_skb_send(struct sk_buff *skb, u32 vnet); 37.46 -extern int vnet_skb_recv(struct sk_buff *skb, u32 vnet, struct Vmac *vmac); 37.47 +extern int vnet_skb_send(struct sk_buff *skb, struct VnetId *vnet); 37.48 +extern int vnet_skb_recv(struct sk_buff *skb, struct VnetId *vnet, struct Vmac *vmac); 37.49 37.50 -extern int vnet_check_context(int vnet, SkbContext *context, Vnet **vinfo); 37.51 +extern int vnet_check_context(struct VnetId *vnet, SkbContext *context, Vnet **vinfo); 37.52 37.53 -extern int vnet_tunnel_open(vnetid_t vnet, vnetaddr_t addr, Tunnel **tunnel); 37.54 -extern int vnet_tunnel_lookup(vnetid_t vnet, vnetaddr_t addr, Tunnel **tunnel); 37.55 -extern int vnet_tunnel_send(vnetid_t vnet, vnetaddr_t addr, struct sk_buff *skb); 37.56 +extern int vnet_tunnel_open(struct VnetId *vnet, struct VarpAddr *addr, Tunnel **tunnel); 37.57 +extern int vnet_tunnel_lookup(struct VnetId *vnet, struct VarpAddr *addr, Tunnel **tunnel); 37.58 +extern int vnet_tunnel_send(struct VnetId *vnet, struct VarpAddr *addr, struct sk_buff *skb); 37.59 37.60 extern int vnet_init(void); 37.61 37.62 -enum { 37.63 - HANDLE_OK = 1, 37.64 - HANDLE_NO = 0, 37.65 -}; 37.66 - 37.67 extern int vnet_sa_security(u32 spi, int protocol, u32 addr); 37.68 struct SAState; 37.69 extern int vnet_sa_create(u32 spi, int protocol, u32 addr, struct SAState **sa);
38.1 --- a/tools/vnet/vnet-module/vnet_dev.c Fri Aug 26 10:51:10 2005 +0000 38.2 +++ b/tools/vnet/vnet-module/vnet_dev.c Fri Aug 26 10:52:53 2005 +0000 38.3 @@ -48,16 +48,10 @@ 38.4 #undef DEBUG 38.5 #include "debug.h" 38.6 38.7 -#define VNETIF_FMT "vnetif%u" 38.8 -#define VNETBR_FMT "vnet%u" 38.9 - 38.10 #ifndef CONFIG_BRIDGE 38.11 #error Must configure ethernet bridging in Network Options 38.12 #endif 38.13 38.14 -#include <linux/../../net/bridge/br_private.h> 38.15 -#define dev_bridge(_dev) ((struct net_bridge *)(_dev)->priv) 38.16 - 38.17 static void vnet_dev_destructor(struct net_device *dev){ 38.18 dprintf(">\n"); 38.19 dev->open = NULL; 38.20 @@ -113,190 +107,15 @@ static int vnet_dev_set_name(struct net_ 38.21 Vnet *vnet = (void*)dev->priv; 38.22 38.23 dprintf(">\n"); 38.24 - dprintf("> vnet=%d\n", vnet->vnet); 38.25 - snprintf(dev->name, IFNAMSIZ - 1, VNETIF_FMT, vnet->vnet); 38.26 - if(__dev_get_by_name(dev->name)){ 38.27 + if(__dev_get_by_name(vnet->device)){ 38.28 err = -ENOMEM; 38.29 + wprintf("> vnet device name in use: %s\n", vnet->device); 38.30 } 38.31 + strcpy(dev->name, vnet->device); 38.32 dprintf("< err=%d\n", err); 38.33 return err; 38.34 } 38.35 38.36 -//============================================================================ 38.37 -#ifdef CONFIG_VNET_BRIDGE 38.38 - 38.39 -#define BRIDGE DEVICE 38.40 - 38.41 -void vnet_bridge_fini(Vnet *vnet){ 38.42 - if(!vnet) return; 38.43 - if(vnet->bridge){ 38.44 - br_del_bridge(vnet->bridge->name); 38.45 - vnet->bridge = NULL; 38.46 - } 38.47 -} 38.48 - 38.49 -/** Create the bridge for a vnet, and add the 38.50 - * vnet interface to it. 38.51 - * 38.52 - * @param vnet vnet 38.53 - * @return 0 on success, error code otherwise 38.54 - */ 38.55 -int vnet_bridge_init(Vnet *vnet){ 38.56 - int err = 0; 38.57 - char bridge[IFNAMSIZ] = {}; 38.58 - struct net_bridge *br; 38.59 - vnet->bridge = NULL; 38.60 - snprintf(bridge, IFNAMSIZ - 1, VNETBR_FMT, vnet->vnet); 38.61 - rtnl_lock(); 38.62 - err = br_add_bridge(bridge); 38.63 - rtnl_unlock(); 38.64 - if(err){ 38.65 - dprintf("> Error creating vnet bridge %s: err=%d\n", bridge, err); 38.66 - goto exit; 38.67 - } 38.68 - vnet->bridge = __dev_get_by_name(bridge); 38.69 - if(!vnet->bridge){ 38.70 - wprintf("> Vnet bridge %s is null!\n", bridge); 38.71 - err = -EINVAL; 38.72 - goto exit; 38.73 - } 38.74 - br = dev_bridge(vnet->bridge); 38.75 - br->stp_enabled = 0; 38.76 - br->bridge_hello_time = 0; 38.77 - br->hello_time = 0; 38.78 - br->bridge_forward_delay = 0; 38.79 - br->forward_delay = 0; 38.80 - rtnl_lock(); 38.81 - err = br_add_if(br, vnet->dev); 38.82 - rtnl_unlock(); 38.83 - if(err){ 38.84 - dprintf("> Error adding vif %s to vnet bridge %s: err=%d\n", 38.85 - vnet->dev->name, bridge, err); 38.86 - goto exit; 38.87 - } 38.88 - rtnl_lock(); 38.89 - dev_open(vnet->dev); 38.90 - dev_open(vnet->bridge); 38.91 - rtnl_unlock(); 38.92 - exit: 38.93 - if(err){ 38.94 - if(vnet->bridge){ 38.95 - rtnl_lock(); 38.96 - br_del_bridge(bridge); 38.97 - rtnl_unlock(); 38.98 - vnet->bridge = NULL; 38.99 - } 38.100 - } 38.101 - return err; 38.102 -} 38.103 - 38.104 - 38.105 -/** Add an interface to the bridge for a vnet. 38.106 - * 38.107 - * @param vnet vnet 38.108 - * @param dev interface 38.109 - * @return 0 on success, error code otherwise 38.110 - */ 38.111 -int vnet_add_if(Vnet *vnet, struct net_device *dev){ 38.112 - int err = 0; 38.113 - struct net_device *brdev; 38.114 - 38.115 - dprintf(">\n"); 38.116 - if(!vnet->bridge){ 38.117 - err = -EINVAL; 38.118 - goto exit; 38.119 - } 38.120 - // Delete the interface from the default bridge. 38.121 - // todo: Really want to delete it from any bridge it's in. 38.122 - if(!vnet_get_device(BRIDGE, &brdev)){ 38.123 - rtnl_lock(); 38.124 - br_del_if(dev_bridge(brdev), dev); 38.125 - rtnl_unlock(); 38.126 - } 38.127 - dprintf("> br_add_if %s %s\n", vnet->bridge->name, dev->name); 38.128 - rtnl_lock(); 38.129 - dev_open(dev); 38.130 - dev_open(vnet->bridge); 38.131 - err = br_add_if(dev_bridge(vnet->bridge), dev); 38.132 - rtnl_unlock(); 38.133 - exit: 38.134 - dprintf("< err=%d\n", err); 38.135 - return err; 38.136 -} 38.137 - 38.138 -int vnet_del_if(Vnet *vnet, struct net_device *dev){ 38.139 - int err = 0; 38.140 - 38.141 - dprintf(">\n"); 38.142 - if(!vnet->bridge){ 38.143 - err = -EINVAL; 38.144 - goto exit; 38.145 - } 38.146 - rtnl_lock(); 38.147 - br_del_if(dev_bridge(vnet->bridge), dev); 38.148 - rtnl_unlock(); 38.149 - exit: 38.150 - dprintf("< err=%d\n", err); 38.151 - return err; 38.152 -} 38.153 - 38.154 - 38.155 -/** Create the bridge and virtual interface for a vnet. 38.156 - * 38.157 - * @param info vnet 38.158 - * @return 0 on success, error code otherwise 38.159 - */ 38.160 -int Vnet_create(Vnet *info){ 38.161 - int err = 0; 38.162 - 38.163 - dprintf("> %u\n", info->vnet); 38.164 - err = vnet_dev_add(info); 38.165 - if(err) goto exit; 38.166 - dprintf("> vnet_bridge_init\n"); 38.167 - err = vnet_bridge_init(info); 38.168 - if(err) goto exit; 38.169 - dprintf("> Vnet_add...\n"); 38.170 - err = Vnet_add(info); 38.171 - exit: 38.172 - if(err){ 38.173 - dprintf("> vnet_bridge_fini...\n"); 38.174 - vnet_bridge_fini(info); 38.175 - } 38.176 - dprintf("< err=%d\n", err); 38.177 - return err; 38.178 -} 38.179 - 38.180 - 38.181 - 38.182 -/** Remove the net device for a vnet. 38.183 - * Clears the dev field of the vnet. 38.184 - * Safe to call if the vnet or its dev are null. 38.185 - * 38.186 - * @param vnet vnet 38.187 - */ 38.188 -void vnet_dev_remove(Vnet *vnet){ 38.189 - if(!vnet) return; 38.190 - dprintf("> vnet=%u\n", vnet->vnet); 38.191 - if(vnet->bridge){ 38.192 - dprintf("> br_del_bridge(%s)\n", vnet->bridge->name); 38.193 - rtnl_lock(); 38.194 - br_del_bridge(vnet->bridge->name); 38.195 - rtnl_unlock(); 38.196 - vnet->bridge = NULL; 38.197 - } 38.198 - if(vnet->dev){ 38.199 - //dev_put(vnet->dev); 38.200 - dprintf("> unregister_netdev(%s)\n", vnet->dev->name); 38.201 - unregister_netdev(vnet->dev); 38.202 - vnet->dev = NULL; 38.203 - } 38.204 - dprintf("<\n"); 38.205 -} 38.206 - 38.207 -//============================================================================ 38.208 -#else 38.209 -//============================================================================ 38.210 - 38.211 /** Create the virtual interface for a vnet. 38.212 * 38.213 * @param info vnet 38.214 @@ -305,27 +124,13 @@ void vnet_dev_remove(Vnet *vnet){ 38.215 int Vnet_create(Vnet *info){ 38.216 int err = 0; 38.217 38.218 - dprintf("> %u\n", info->vnet); 38.219 err = vnet_dev_add(info); 38.220 if(err) goto exit; 38.221 - dprintf("> Vnet_add...\n"); 38.222 err = Vnet_add(info); 38.223 exit: 38.224 - dprintf("< err=%d\n", err); 38.225 return err; 38.226 } 38.227 38.228 -int vnet_add_if(Vnet *vnet, struct net_device *dev){ 38.229 - int err = -ENOSYS; 38.230 - return err; 38.231 -} 38.232 - 38.233 - 38.234 -int vnet_del_if(Vnet *vnet, struct net_device *dev){ 38.235 - int err = 0; 38.236 - return err; 38.237 -} 38.238 - 38.239 /** Remove the net device for a vnet. 38.240 * Clears the dev field of the vnet. 38.241 * Safe to call if the vnet or its dev are null. 38.242 @@ -334,17 +139,13 @@ int vnet_del_if(Vnet *vnet, struct net_d 38.243 */ 38.244 void vnet_dev_remove(Vnet *vnet){ 38.245 if(!vnet) return; 38.246 - dprintf("> vnet=%u\n", vnet->vnet); 38.247 if(vnet->dev){ 38.248 //dev_put(vnet->dev); 38.249 dprintf("> unregister_netdev(%s)\n", vnet->dev->name); 38.250 unregister_netdev(vnet->dev); 38.251 vnet->dev = NULL; 38.252 } 38.253 - dprintf("<\n"); 38.254 } 38.255 -#endif 38.256 -//============================================================================ 38.257 38.258 static int vnet_dev_open(struct net_device *dev){ 38.259 int err = 0; 38.260 @@ -365,6 +166,7 @@ static int vnet_dev_stop(struct net_devi 38.261 static int vnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev){ 38.262 int err = 0; 38.263 Vnet *vnet = dev->priv; 38.264 + int len = 0; 38.265 38.266 dprintf("> skb=%p\n", skb); 38.267 if(vnet->recursion++) { 38.268 @@ -385,12 +187,14 @@ static int vnet_dev_hard_start_xmit(stru 38.269 skb->mac.raw = skb->data; 38.270 } 38.271 //dev->trans_start = jiffies; 38.272 - err = vnet_skb_send(skb, vnet->vnet); 38.273 + len = skb->len; 38.274 + // Must not use skb pointer after vnet_skb_send(). 38.275 + err = vnet_skb_send(skb, &vnet->vnet); 38.276 if(err < 0){ 38.277 vnet->stats.tx_errors++; 38.278 } else { 38.279 vnet->stats.tx_packets++; 38.280 - vnet->stats.tx_bytes += skb->len; 38.281 + vnet->stats.tx_bytes += len; 38.282 } 38.283 exit: 38.284 vnet->recursion--; 38.285 @@ -416,43 +220,48 @@ static int vnet_dev_hard_header(struct s 38.286 struct net_device *dev, unsigned short type, 38.287 void *daddr, void *saddr, unsigned len){ 38.288 int err = 0; 38.289 - dprintf("> skb=%p ethhdr=%p dev=%s len=%u\n", 38.290 - skb, skb->mac.raw, dev->name, len); 38.291 - if(saddr){ 38.292 - dprintf("> saddr=" MACFMT "\n", MAC6TUPLE((unsigned char*)saddr)); 38.293 - } else { 38.294 - dprintf("> saddr=NULL\n"); 38.295 - } 38.296 - if(daddr){ 38.297 - dprintf("> daddr=" MACFMT "\n", MAC6TUPLE((unsigned char*)daddr)); 38.298 - } else { 38.299 - dprintf("> daddr=NULL\n"); 38.300 - } 38.301 + 38.302 err = eth_hard_header(skb, dev, type, daddr, saddr, len); 38.303 - dprintf("> eth_hard_header=%d\n", err); 38.304 + if(err) goto exit; 38.305 skb->mac.raw = skb->data; 38.306 - dprintf("> src=" MACFMT " dst=" MACFMT "\n", 38.307 - MAC6TUPLE(skb->mac.ethernet->h_source), 38.308 - MAC6TUPLE(skb->mac.ethernet->h_dest)); 38.309 - dprintf("< err=%d\n", err); 38.310 + exit: 38.311 + return err; 38.312 +} 38.313 + 38.314 +void vnet_default_mac(unsigned char *mac) 38.315 +{ 38.316 + static unsigned val = 1; 38.317 + mac[0] = 0xAA; 38.318 + mac[1] = 0xFF; 38.319 + mac[2] = (unsigned char)((val >> 24) & 0xff); 38.320 + mac[3] = (unsigned char)((val >> 16) & 0xff); 38.321 + mac[4] = (unsigned char)((val >> 8) & 0xff); 38.322 + mac[5] = (unsigned char)((val ) & 0xff); 38.323 + val++; 38.324 +} 38.325 + 38.326 +int vnet_device_mac(const char *device, unsigned char *mac){ 38.327 + int err; 38.328 + struct net_device *dev; 38.329 + 38.330 + err = vnet_get_device(device, &dev); 38.331 + if(err) goto exit; 38.332 + memcpy(mac, dev->dev_addr, ETH_ALEN); 38.333 + dev_put(dev); 38.334 + exit: 38.335 return err; 38.336 } 38.337 38.338 void vnet_dev_mac(unsigned char *mac){ 38.339 - static unsigned val = 1; 38.340 - struct net_device *dev; 38.341 + const char *devices[] = { "eth0", "eth1", "eth2", NULL }; 38.342 + const char **pdev; 38.343 + int err = -ENODEV; 38.344 38.345 - if(vnet_get_device(DEVICE, &dev)){ 38.346 - mac[0] = 0xAA; 38.347 - mac[1] = 0xFF; 38.348 - mac[2] = (unsigned char)((val >> 24) & 0xff); 38.349 - mac[3] = (unsigned char)((val >> 16) & 0xff); 38.350 - mac[4] = (unsigned char)((val >> 8) & 0xff); 38.351 - mac[5] = (unsigned char)((val ) & 0xff); 38.352 - val++; 38.353 - } else { 38.354 - memcpy(mac, dev->dev_addr, ETH_ALEN); 38.355 - dev_put(dev); 38.356 + for(pdev = devices; err && *pdev; pdev++){ 38.357 + err = vnet_device_mac(*pdev, mac); 38.358 + } 38.359 + if(err){ 38.360 + vnet_default_mac(mac); 38.361 } 38.362 } 38.363 38.364 @@ -463,7 +272,9 @@ static int vnet_dev_init(struct net_devi 38.365 dprintf(">\n"); 38.366 ether_setup(dev); 38.367 38.368 - if(!eth_hard_header) eth_hard_header = dev->hard_header; 38.369 + if(!eth_hard_header){ 38.370 + eth_hard_header = dev->hard_header; 38.371 + } 38.372 dev->hard_header = vnet_dev_hard_header; 38.373 38.374 dev->open = vnet_dev_open; 38.375 @@ -507,7 +318,10 @@ int vnet_dev_add(Vnet *vnet){ 38.376 if(vnet->dev) goto exit; 38.377 vnet->header_n = sizeof(struct iphdr) + sizeof(struct etheriphdr); 38.378 dev = kmalloc(sizeof(struct net_device), GFP_ATOMIC); 38.379 - if(!dev){ err = -ENOMEM; goto exit; } 38.380 + if(!dev){ 38.381 + err = -ENOMEM; 38.382 + goto exit; 38.383 + } 38.384 *dev = (struct net_device){}; 38.385 dev->priv = vnet; 38.386 vnet->dev = dev; 38.387 @@ -515,9 +329,10 @@ int vnet_dev_add(Vnet *vnet){ 38.388 err = vnet_dev_set_name(dev); 38.389 if(err) goto exit; 38.390 vnet_dev_init(dev); 38.391 - dprintf("> name=%s, register_netdev...\n", dev->name); 38.392 err = register_netdev(dev); 38.393 - dprintf("> register_netdev=%d\n", err); 38.394 + if(err){ 38.395 + wprintf("> register_netdev(%s) = %d\n", dev->name, err); 38.396 + } 38.397 if(err) goto exit; 38.398 rtnl_lock(); 38.399 dev_open(dev);
39.1 --- a/tools/vnet/vnet-module/vnet_dev.h Fri Aug 26 10:51:10 2005 +0000 39.2 +++ b/tools/vnet/vnet-module/vnet_dev.h Fri Aug 26 10:52:53 2005 +0000 39.3 @@ -20,12 +20,9 @@ 39.4 #define _VNET_VNET_DEV_H_ 39.5 39.6 struct Vnet; 39.7 -struct net_device; 39.8 39.9 extern int vnet_dev_add(struct Vnet *vnet); 39.10 extern void vnet_dev_remove(struct Vnet *vnet); 39.11 extern int Vnet_create(struct Vnet *info); 39.12 -extern int vnet_add_if(struct Vnet *vnet, struct net_device *dev); 39.13 -extern int vnet_del_if(struct Vnet *vnet, struct net_device *dev); 39.14 39.15 #endif
40.1 --- a/tools/vnet/vnet-module/vnet_ioctl.c Fri Aug 26 10:51:10 2005 +0000 40.2 +++ b/tools/vnet/vnet-module/vnet_ioctl.c Fri Aug 26 10:52:53 2005 +0000 40.3 @@ -59,7 +59,7 @@ Have to rely on ethernet bridging being 40.4 on the kernel interface being available to us (it's not exported @!$"%!). 40.5 40.6 Create a vnet N: 40.7 -- create the vnet device vnetifN: using commands to /proc, kernel api 40.8 +- create the vnet device vnifN: using commands to /proc, kernel api 40.9 - create the vnet bridge vnetN: using brctl in user-space 40.10 - for best results something should keep track of the mapping vnet id <-> bridge name 40.11 40.12 @@ -312,7 +312,6 @@ static int proc_release_fn(Inode *inode, 40.13 err = Parser_input(parser, NULL, 0); 40.14 if(err) goto exit; 40.15 obj = parser->val; 40.16 - objprint(iostdout, obj, 0); IOStream_print(iostdout, "\n"); 40.17 for(l = obj; CONSP(l); l = CDR(l)){ 40.18 err = eval(CAR(l)); 40.19 if(err) break; 40.20 @@ -451,6 +450,7 @@ static int child_string(Sxpr exp, Sxpr k 40.21 return err; 40.22 } 40.23 40.24 +#if 0 40.25 static int intof(Sxpr exp, int *v){ 40.26 int err = 0; 40.27 char *s; 40.28 @@ -473,6 +473,24 @@ static int child_int(Sxpr exp, Sxpr key, 40.29 err = intof(val, v); 40.30 return err; 40.31 } 40.32 +#endif 40.33 + 40.34 +static int vnetof(Sxpr exp, VnetId *v){ 40.35 + int err = 0; 40.36 + char *s; 40.37 + err = stringof(exp, &s); 40.38 + if(err) goto exit; 40.39 + err = VnetId_aton(s, v); 40.40 + exit: 40.41 + return err; 40.42 +} 40.43 + 40.44 +static int child_vnet(Sxpr exp, Sxpr key, VnetId *v){ 40.45 + int err = 0; 40.46 + Sxpr val = sxpr_child_value(exp, key, ONONE); 40.47 + err = vnetof(val, v); 40.48 + return err; 40.49 +} 40.50 40.51 static int macof(Sxpr exp, unsigned char *v){ 40.52 int err = 0; 40.53 @@ -515,20 +533,27 @@ static int child_addr(Sxpr exp, Sxpr key 40.54 * It is an error if a vnet with the same id exists. 40.55 * 40.56 * @param vnet vnet id 40.57 + * @param device vnet device name 40.58 * @param security security level 40.59 * @return 0 on success, error code otherwise 40.60 */ 40.61 -static int ctrl_vnet_add(int vnet, int security){ 40.62 +static int ctrl_vnet_add(VnetId *vnet, char *device, int security){ 40.63 int err = 0; 40.64 Vnet *vnetinfo = NULL; 40.65 + 40.66 + if(strlen(device) >= IFNAMSIZ){ 40.67 + err = -EINVAL; 40.68 + goto exit; 40.69 + } 40.70 if(Vnet_lookup(vnet, &vnetinfo) == 0){ 40.71 err = -EEXIST; 40.72 goto exit; 40.73 } 40.74 err = Vnet_alloc(&vnetinfo); 40.75 if(err) goto exit; 40.76 - vnetinfo->vnet = vnet; 40.77 + vnetinfo->vnet = *vnet; 40.78 vnetinfo->security = security; 40.79 + strcpy(vnetinfo->device, device); 40.80 err = Vnet_create(vnetinfo); 40.81 exit: 40.82 if(vnetinfo) Vnet_decref(vnetinfo); 40.83 @@ -540,9 +565,15 @@ static int ctrl_vnet_add(int vnet, int s 40.84 * @param vnet vnet id 40.85 * @return 0 on success, error code otherwise 40.86 */ 40.87 -static int ctrl_vnet_del(int vnet){ 40.88 +static int ctrl_vnet_del(VnetId *vnet){ 40.89 int err = -ENOSYS; 40.90 // Can't delete if there are any vifs on the vnet. 40.91 + 40.92 + // Need to flush vif entries for the deleted vnet. 40.93 + // Need to flush varp entries for the deleted vnet. 40.94 + // Note that (un)register_netdev() hold rtnl_lock() around 40.95 + // (un)register_netdevice(). 40.96 + 40.97 //Vnet_del(vnet); 40.98 return err; 40.99 } 40.100 @@ -553,7 +584,7 @@ static int ctrl_vnet_del(int vnet){ 40.101 * @param vmac mac address 40.102 * @return 0 on success, error code otherwise 40.103 */ 40.104 -static int ctrl_vif_add(int vnet, Vmac *vmac){ 40.105 +static int ctrl_vif_add(VnetId *vnet, Vmac *vmac){ 40.106 int err = 0; 40.107 Vnet *vnetinfo = NULL; 40.108 Vif *vif = NULL; 40.109 @@ -561,7 +592,7 @@ static int ctrl_vif_add(int vnet, Vmac * 40.110 dprintf(">\n"); 40.111 err = Vnet_lookup(vnet, &vnetinfo); 40.112 if(err) goto exit; 40.113 - err = vif_add(vnet, vmac, &vif); 40.114 + err = vif_create(vnet, vmac, &vif); 40.115 exit: 40.116 if(vnetinfo) Vnet_decref(vnetinfo); 40.117 if(vif) vif_decref(vif); 40.118 @@ -569,46 +600,13 @@ static int ctrl_vif_add(int vnet, Vmac * 40.119 return err; 40.120 } 40.121 40.122 -/** Add net device 'vifname' to the bridge for 'vnet' and 40.123 - * create an entry for a vif with the given vnet and vmac. 40.124 - * This is used when device 'vifname' is a virtual device 40.125 - * connected to a vif in a vm. 40.126 - * 40.127 - * @param vifname name of device to bridge 40.128 - * @param vnet vnet id 40.129 - * @param vmac mac address 40.130 - * @return 0 on success, error code otherwise 40.131 - */ 40.132 -static int ctrl_vif_conn(char *vifname, int vnet, Vmac *vmac){ 40.133 - int err = 0; 40.134 - Vnet *vnetinfo = NULL; 40.135 - struct net_device *vifdev = NULL; 40.136 - Vif *vif = NULL; 40.137 - 40.138 - dprintf("> %s\n", vifname); 40.139 - err = Vnet_lookup(vnet, &vnetinfo); 40.140 - if(err) goto exit; 40.141 - err = vif_add(vnet, vmac, &vif); 40.142 - if(err) goto exit; 40.143 - err = vnet_get_device(vifname, &vifdev); 40.144 - if(err) goto exit; 40.145 - vif->dev = vifdev; 40.146 - err = vnet_add_if(vnetinfo, vifdev); 40.147 - exit: 40.148 - if(vnetinfo) Vnet_decref(vnetinfo); 40.149 - if(vif) vif_decref(vif); 40.150 - if(vifdev) dev_put(vifdev); 40.151 - dprintf("< err=%d\n", err); 40.152 - return err; 40.153 -} 40.154 - 40.155 /** Delete a vif. 40.156 * 40.157 * @param vnet vnet id 40.158 * @param vmac mac address 40.159 * @return 0 on success, error code otherwise 40.160 */ 40.161 -static int ctrl_vif_del(int vnet, Vmac *vmac){ 40.162 +static int ctrl_vif_del(VnetId *vnet, Vmac *vmac){ 40.163 int err = 0; 40.164 Vnet *vnetinfo = NULL; 40.165 Vif *vif = NULL; 40.166 @@ -618,10 +616,6 @@ static int ctrl_vif_del(int vnet, Vmac * 40.167 if(err) goto exit; 40.168 err = vif_lookup(vnet, vmac, &vif); 40.169 if(err) goto exit; 40.170 - if(vif->dev){ 40.171 - vnet_del_if(vnetinfo, vif->dev); 40.172 - vif->dev = NULL; 40.173 - } 40.174 vif_remove(vnet, vmac); 40.175 exit: 40.176 if(vnetinfo) Vnet_decref(vnetinfo); 40.177 @@ -652,21 +646,37 @@ static int eval_varp_mcaddr(Sxpr exp){ 40.178 return err; 40.179 } 40.180 40.181 -/** (vnet.add (id <id>) [(security { none | auth | conf } )] ) 40.182 +/** (varp.flush) 40.183 + */ 40.184 +static int eval_varp_flush(Sxpr exp){ 40.185 + int err = 0; 40.186 + varp_flush(); 40.187 + return err; 40.188 +} 40.189 + 40.190 +/** (vnet.add (id <id>) 40.191 + * [(vnetif <name>)] 40.192 + * [(security { none | auth | conf } )] 40.193 + * ) 40.194 */ 40.195 static int eval_vnet_add(Sxpr exp){ 40.196 int err = 0; 40.197 Sxpr oid = intern("id"); 40.198 Sxpr osecurity = intern("security"); 40.199 + Sxpr ovnetif = intern("vnetif"); 40.200 Sxpr csecurity; 40.201 - int id; 40.202 - char *security; 40.203 + VnetId vnet = {}; 40.204 + char *device = NULL; 40.205 + char dev[IFNAMSIZ] = {}; 40.206 + char *security = NULL; 40.207 int sec; 40.208 - err = child_int(exp, oid, &id); 40.209 + 40.210 + err = child_vnet(exp, oid, &vnet); 40.211 if(err) goto exit; 40.212 - if(id < VNET_VIF){ 40.213 - err = -EINVAL; 40.214 - goto exit; 40.215 + child_string(exp, ovnetif, &device); 40.216 + if(!device){ 40.217 + snprintf(dev, IFNAMSIZ-1, "vnif%04x", ntohs(vnet.u.vnet16[7])); 40.218 + device = dev; 40.219 } 40.220 csecurity = sxpr_child_value(exp, osecurity, intern("none")); 40.221 err = stringof(csecurity, &security); 40.222 @@ -681,8 +691,7 @@ static int eval_vnet_add(Sxpr exp){ 40.223 err = -EINVAL; 40.224 goto exit; 40.225 } 40.226 - dprintf("> vnet id=%d\n", id); 40.227 - err = ctrl_vnet_add(id, sec); 40.228 + err = ctrl_vnet_add(&vnet, device, sec); 40.229 exit: 40.230 dprintf("< err=%d\n", err); 40.231 return err; 40.232 @@ -698,11 +707,11 @@ static int eval_vnet_add(Sxpr exp){ 40.233 static int eval_vnet_del(Sxpr exp){ 40.234 int err = 0; 40.235 Sxpr oid = intern("id"); 40.236 - int id; 40.237 + VnetId vnet = {}; 40.238 40.239 - err = child_int(exp, oid, &id); 40.240 + err = child_vnet(exp, oid, &vnet); 40.241 if(err) goto exit; 40.242 - err = ctrl_vnet_del(id); 40.243 + err = ctrl_vnet_del(&vnet); 40.244 exit: 40.245 return err; 40.246 } 40.247 @@ -713,55 +722,32 @@ static int eval_vif_add(Sxpr exp){ 40.248 int err = 0; 40.249 Sxpr ovnet = intern("vnet"); 40.250 Sxpr ovmac = intern("vmac"); 40.251 - int vnet; 40.252 + VnetId vnet = {}; 40.253 Vmac vmac = {}; 40.254 40.255 - err = child_int(exp, ovnet, &vnet); 40.256 + err = child_vnet(exp, ovnet, &vnet); 40.257 if(err) goto exit; 40.258 err = child_mac(exp, ovmac, vmac.mac); 40.259 if(err) goto exit; 40.260 - err = ctrl_vif_add(vnet, &vmac); 40.261 + err = ctrl_vif_add(&vnet, &vmac); 40.262 exit: 40.263 return err; 40.264 } 40.265 40.266 -/** (vif.conn (vif <name>) (vnet <id>) (vmac <mac>)) 40.267 - */ 40.268 -static int eval_vif_conn(Sxpr exp){ 40.269 - int err = 0; 40.270 - Sxpr ovif = intern("vif"); 40.271 - Sxpr ovnet = intern("vnet"); 40.272 - Sxpr ovmac = intern("vmac"); 40.273 - char *vif = NULL; 40.274 - int vnet = 0; 40.275 - Vmac vmac = {}; 40.276 - 40.277 - err = child_string(exp, ovif, &vif); 40.278 - if(err) goto exit; 40.279 - err = child_int(exp, ovnet, &vnet); 40.280 - if(err) goto exit; 40.281 - err = child_mac(exp, ovmac, vmac.mac); 40.282 - dprintf("> connect vif=%s vnet=%d\n", vif, vnet); 40.283 - err = ctrl_vif_conn(vif, vnet, &vmac); 40.284 - exit: 40.285 - dprintf("< err=%d\n", err); 40.286 - return err; 40.287 -} 40.288 - 40.289 /** (vif.del (vnet <vnet>) (vmac <macaddr>)) 40.290 */ 40.291 static int eval_vif_del(Sxpr exp){ 40.292 int err = 0; 40.293 Sxpr ovnet = intern("vnet"); 40.294 Sxpr ovmac = intern("vmac"); 40.295 - int vnet; 40.296 + VnetId vnet = {}; 40.297 Vmac vmac = {}; 40.298 40.299 - err = child_int(exp, ovnet, &vnet); 40.300 + err = child_vnet(exp, ovnet, &vnet); 40.301 if(err) goto exit; 40.302 err = child_mac(exp, ovmac, vmac.mac); 40.303 if(err) goto exit; 40.304 - err = ctrl_vif_del(vnet, &vmac); 40.305 + err = ctrl_vif_del(&vnet, &vmac); 40.306 exit: 40.307 return err; 40.308 } 40.309 @@ -776,23 +762,23 @@ static int eval(Sxpr exp){ 40.310 SxprEval defs[] = { 40.311 { intern("varp.print"), eval_varp_print }, 40.312 { intern("varp.mcaddr"), eval_varp_mcaddr }, 40.313 + { intern("varp.flush"), eval_varp_flush }, 40.314 { intern("vif.add"), eval_vif_add }, 40.315 - { intern("vif.conn"), eval_vif_conn }, 40.316 { intern("vif.del"), eval_vif_del }, 40.317 { intern("vnet.add"), eval_vnet_add }, 40.318 { intern("vnet.del"), eval_vnet_del }, 40.319 { ONONE, NULL } }; 40.320 SxprEval *def; 40.321 40.322 - dprintf(">\n"); 40.323 - err = -EINVAL; 40.324 + iprintf("> "); objprint(iostdout, exp, 0); IOStream_print(iostdout, "\n"); 40.325 + err = -ENOSYS; 40.326 for(def = defs; !NONEP(def->elt); def++){ 40.327 if(sxpr_elementp(exp, def->elt)){ 40.328 err = def->fn(exp); 40.329 break; 40.330 } 40.331 } 40.332 - dprintf("< err=%d\n", err); 40.333 + iprintf("< err=%d\n", err); 40.334 return err; 40.335 } 40.336
41.1 --- a/tools/vnet/vnetd/Makefile Fri Aug 26 10:51:10 2005 +0000 41.2 +++ b/tools/vnet/vnetd/Makefile Fri Aug 26 10:52:53 2005 +0000 41.3 @@ -16,32 +16,29 @@ 41.4 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 41.5 #---------------------------------------------------------------------------- 41.6 41.7 +VNET_ROOT = $(shell cd .. && pwd) 41.8 +include $(VNET_ROOT)/Make.env 41.9 + 41.10 all: vnetd 41.11 41.12 #---------------------------------------------------------------------------- 41.13 41.14 -XEN_ROOT = ../../.. 41.15 include $(XEN_ROOT)/tools/Rules.mk 41.16 41.17 VNETD_INSTALL_DIR = /usr/sbin 41.18 41.19 -LIB_DIR = ../libxutil 41.20 -VNET_DIR = ../vnet-module 41.21 - 41.22 -INCLUDES += -I$(LIB_DIR) 41.23 -INCLUDES += -I$(VNET_DIR) 41.24 +INCLUDES += -I$(LIBXUTIL_DIR) 41.25 +INCLUDES += -I$(VNET_MODULE_DIR) 41.26 41.27 #---------------------------------------------------------------------------- 41.28 # GC. 41.29 -GC_DIR:=../gc/install 41.30 -GC_INCLUDE:= $(GC_DIR)/include 41.31 -GC_LIB_DIR:=$(GC_DIR)/lib 41.32 41.33 INCLUDES += -I$(GC_INCLUDE) 41.34 #LIBS += -L$(GC_LIB_DIR) 41.35 CPPFLAGS += -D USE_GC 41.36 41.37 #---------------------------------------------------------------------------- 41.38 +CFLAGS += -g 41.39 CFLAGS += -Wall 41.40 CFLAGS += $(INCLUDES) $(LIBS) 41.41 41.42 @@ -51,7 +48,7 @@ LDFLAGS += $(LIBS) 41.43 CFLAGS += -Wp,-MD,.$(@F).d 41.44 PROG_DEP = .*.d 41.45 41.46 -vpath %.c $(LIB_DIR) 41.47 +vpath %.c $(LIBXUTIL_DIR) 41.48 41.49 IPATHS:=$(INCLUDES:-I=) 41.50 vpath %.h $(IPATHS) 41.51 @@ -83,9 +80,9 @@ VNETD_SRC+=$(LIB_SRC) 41.52 41.53 VNETD_OBJ := $(VNETD_SRC:.c=.o) 41.54 41.55 -#VNETD_LIBS:= $(GC_LIB_DIR)/libgc.so.1.0.2 41.56 +#VNETD_LIBS:= $(GC_LIB_SO) 41.57 #VNETD_LIBS:= -lgc 41.58 -VNETD_LIBS:= $(GC_LIB_DIR)/libgc.a 41.59 +VNETD_LIBS:= $(GC_LIB_A) 41.60 41.61 vnetd: $(VNETD_OBJ) 41.62 $(CC) $(CFLAGS) -o $@ $^ $(VNETD_LIBS) -ldl -lpthread 41.63 @@ -95,8 +92,8 @@ install: vnetd 41.64 install -m 0755 vnetd $(DESTDIR)$(VNETD_INSTALL_DIR) 41.65 41.66 clean: 41.67 - -rm -f *.a *.o *~ 41.68 - -rm -f vnetd 41.69 - -rm -f $(PROG_DEP) 41.70 + -@$(RM) *.a *.o *~ 41.71 + -@$(RM) vnetd 41.72 + -@$(RM) $(PROG_DEP) 41.73 41.74 -include $(PROG_DEP)
42.1 --- a/tools/vnet/vnetd/vcache.c Fri Aug 26 10:51:10 2005 +0000 42.2 +++ b/tools/vnet/vnetd/vcache.c Fri Aug 26 10:52:53 2005 +0000 42.3 @@ -44,6 +44,8 @@ 42.4 #undef DEBUG 42.5 #include "debug.h" 42.6 42.7 +#include "varp_util.c" 42.8 + 42.9 static VarpCache *vcache = NULL; 42.10 42.11 void IPMessageQueue_init(IPMessageQueue *queue, int maxlen){ 42.12 @@ -97,16 +99,20 @@ void VarpCache_sweep(VarpCache *z, int a 42.13 * @param vmac vmac (in network order) 42.14 * @return 0 on success, error code otherwise 42.15 */ 42.16 -int varp_send(Conn *conn, uint16_t opcode, uint32_t vnet, Vmac *vmac, uint32_t addr){ 42.17 +int varp_send(Conn *conn, uint16_t opcode, VnetId *vnet, Vmac *vmac, VarpAddr *addr){ 42.18 int err = 0; 42.19 int varp_n = sizeof(VarpHdr); 42.20 VarpHdr varph = {}; 42.21 +#ifdef DEBUG 42.22 + char vnetbuf[VNET_ID_BUF]; 42.23 + char addrbuf[VARP_ADDR_BUF]; 42.24 +#endif 42.25 42.26 - varph.vnetmsghdr.id = htons(VARP_ID); 42.27 - varph.vnetmsghdr.opcode = htons(opcode); 42.28 - varph.vnet = vnet; 42.29 - varph.vmac = *vmac; 42.30 - varph.addr = addr; 42.31 + varph.hdr.id = htons(VARP_ID); 42.32 + varph.hdr.opcode = htons(opcode); 42.33 + varph.vnet = *vnet; 42.34 + varph.vmac = *vmac; 42.35 + varph.addr = *addr; 42.36 42.37 if(0){ 42.38 struct sockaddr_in self; 42.39 @@ -117,8 +123,10 @@ int varp_send(Conn *conn, uint16_t opcod 42.40 } 42.41 dprintf("> addr=%s opcode=%d\n", 42.42 inet_ntoa(conn->addr.sin_addr), opcode); 42.43 - dprintf("> vnet=%d vmac=" MACFMT " addr=" IPFMT "\n", 42.44 - ntohl(vnet), MAC6TUPLE(vmac->mac), NIPQUAD(addr)); 42.45 + dprintf("> vnet=%s vmac=" MACFMT " addr=%s\n", 42.46 + VnetId_ntoa(vnet, vnetbuf), 42.47 + MAC6TUPLE(vmac->mac), 42.48 + VarpAddr_ntoa(addr, addrbuf)); 42.49 err = marshal_bytes(conn->out, &varph, varp_n); 42.50 marshal_flush(conn->out); 42.51 dprintf("< err=%d\n", err); 42.52 @@ -157,21 +165,24 @@ int VCEntry_set_flags(VCEntry *z, int fl 42.53 */ 42.54 void VCEntry_print(VCEntry *ventry){ 42.55 if(ventry){ 42.56 - char *c, *d; 42.57 + char *state, *flags; 42.58 + char vnetbuf[VNET_ID_BUF]; 42.59 + char addrbuf[VARP_ADDR_BUF]; 42.60 + 42.61 switch(ventry->state){ 42.62 - case VCACHE_STATE_INCOMPLETE: c = "INC"; break; 42.63 - case VCACHE_STATE_REACHABLE: c = "RCH"; break; 42.64 - case VCACHE_STATE_FAILED: c = "FLD"; break; 42.65 - default: c = "UNK"; break; 42.66 + case VCACHE_STATE_INCOMPLETE: state = "INC"; break; 42.67 + case VCACHE_STATE_REACHABLE: state = "RCH"; break; 42.68 + case VCACHE_STATE_FAILED: state = "FLD"; break; 42.69 + default: state = "UNK"; break; 42.70 } 42.71 - d = (VCEntry_get_flags(ventry, VCACHE_FLAG_PROBING) ? "P" : " "); 42.72 + flags = (VCEntry_get_flags(ventry, VCACHE_FLAG_PROBING) ? "P" : " "); 42.73 42.74 - printf("VENTRY(%p %s %s vnet=%d vmac=" MACFMT " addr=" IPFMT " time=%g)\n", 42.75 + printf("VENTRY(%p %s %s vnet=%s vmac=" MACFMT " addr=%s time=%g)\n", 42.76 ventry, 42.77 - c, d, 42.78 - ntohl(ventry->key.vnet), 42.79 + state, flags, 42.80 + VnetId_ntoa(&ventry->key.vnet, vnetbuf), 42.81 MAC6TUPLE(ventry->key.vmac.mac), 42.82 - NIPQUAD(ventry->addr), 42.83 + VarpAddr_ntoa(&ventry->addr, addrbuf), 42.84 ventry->timestamp); 42.85 } else { 42.86 printf("VENTRY: Null!\n"); 42.87 @@ -239,11 +250,11 @@ int VCEntry_schedule(VCEntry *ventry){ 42.88 * @param vmac virtual MAC address (copied) 42.89 * @return ventry or null 42.90 */ 42.91 -VCEntry * VCEntry_new(uint32_t vnet, Vmac *vmac){ 42.92 +VCEntry * VCEntry_new(VnetId *vnet, Vmac *vmac){ 42.93 VCEntry *z = ALLOCATE(VCEntry); 42.94 z->state = VCACHE_STATE_INCOMPLETE; 42.95 z->timestamp = time_now(); 42.96 - z->key.vnet = vnet; 42.97 + z->key.vnet = *vnet; 42.98 z->key.vmac = *vmac; 42.99 return z; 42.100 } 42.101 @@ -256,15 +267,9 @@ VCEntry * VCEntry_new(uint32_t vnet, Vma 42.102 */ 42.103 Hashcode vcache_key_hash_fn(void *k){ 42.104 VCKey *key = k; 42.105 - Hashcode h; 42.106 - h = hash_2ul(key->vnet, 42.107 - (key->vmac.mac[0] << 24) | 42.108 - (key->vmac.mac[1] << 16) | 42.109 - (key->vmac.mac[2] << 8) | 42.110 - (key->vmac.mac[3] )); 42.111 - h = hash_hul(h, 42.112 - (key->vmac.mac[4] << 8) | 42.113 - (key->vmac.mac[5] )); 42.114 + Hashcode h = 0; 42.115 + h = VnetId_hash(h, &key->vnet); 42.116 + h = Vmac_hash(h, &key->vmac); 42.117 return h; 42.118 } 42.119 42.120 @@ -278,8 +283,8 @@ Hashcode vcache_key_hash_fn(void *k){ 42.121 int vcache_key_equal_fn(void *k1, void *k2){ 42.122 VCKey *key1 = k1; 42.123 VCKey *key2 = k2; 42.124 - return (key1->vnet == key2->vnet) 42.125 - && (memcmp(key1->vmac.mac, key2->vmac.mac, ETH_ALEN) == 0); 42.126 + return (VnetId_eq(&key1->vnet , &key2->vnet) && 42.127 + Vmac_eq(&key1->vmac, &key2->vmac)); 42.128 } 42.129 42.130 void VarpCache_schedule(VarpCache *z); 42.131 @@ -351,7 +356,7 @@ VarpCache * VarpCache_new(void){ 42.132 * @param vmac virtual MAC address (copied) 42.133 * @return new entry or null 42.134 */ 42.135 -VCEntry * VarpCache_add(VarpCache *z, uint32_t vnet, Vmac *vmac){ 42.136 +VCEntry * VarpCache_add(VarpCache *z, VnetId *vnet, Vmac *vmac){ 42.137 VCEntry *ventry; 42.138 HTEntry *entry; 42.139 42.140 @@ -378,8 +383,8 @@ int VarpCache_remove(VarpCache *z, VCEnt 42.141 * @param vmac virtual MAC addres 42.142 * @return entry found or null 42.143 */ 42.144 -VCEntry * VarpCache_lookup(VarpCache *z, uint32_t vnet, Vmac *vmac){ 42.145 - VCKey key = { .vnet = vnet, .vmac = *vmac }; 42.146 +VCEntry * VarpCache_lookup(VarpCache *z, VnetId *vnet, Vmac *vmac){ 42.147 + VCKey key = { .vnet = *vnet, .vmac = *vmac }; 42.148 VCEntry *ventry; 42.149 ventry = HashTable_get(z->table, &key); 42.150 return ventry; 42.151 @@ -389,13 +394,15 @@ void VCEntry_solicit(VCEntry *ventry){ 42.152 dprintf(">\n"); 42.153 if(VCEntry_get_flags(ventry, VCACHE_FLAG_LOCAL_PROBE)){ 42.154 dprintf("> local probe\n"); 42.155 - varp_send(vnetd->bcast_conn, VARP_OP_REQUEST, ventry->key.vnet, &ventry->key.vmac, ventry->addr); 42.156 + varp_send(vnetd->bcast_conn, VARP_OP_REQUEST, 42.157 + &ventry->key.vnet, &ventry->key.vmac, &ventry->addr); 42.158 } 42.159 if(VCEntry_get_flags(ventry, VCACHE_FLAG_REMOTE_PROBE)){ 42.160 ConnList *l; 42.161 dprintf("> remote probe\n"); 42.162 for(l = vnetd->connections; l; l = l->next){ 42.163 - varp_send(l->conn, VARP_OP_REQUEST, ventry->key.vnet, &ventry->key.vmac, ventry->addr); 42.164 + varp_send(l->conn, VARP_OP_REQUEST, 42.165 + &ventry->key.vnet, &ventry->key.vmac, &ventry->addr); 42.166 } 42.167 42.168 } 42.169 @@ -440,7 +447,8 @@ int VCEntry_update(VCEntry *ventry, IPMe 42.170 IPMessage *msg; 42.171 while((msg = IPMessageQueue_pop(&ventry->queue))){ 42.172 dprintf("> announce\n"); 42.173 - varp_send(msg->conn, VARP_OP_ANNOUNCE, ventry->key.vnet, &ventry->key.vmac, ventry->addr); 42.174 + varp_send(msg->conn, VARP_OP_ANNOUNCE, 42.175 + &ventry->key.vnet, &ventry->key.vmac, &ventry->addr); 42.176 } 42.177 } 42.178 exit: 42.179 @@ -459,7 +467,7 @@ int VarpCache_update(VarpCache *z, IPMes 42.180 VCEntry *ventry; 42.181 42.182 dprintf(">\n"); 42.183 - ventry = VarpCache_lookup(z, varph->vnet, &varph->vmac); 42.184 + ventry = VarpCache_lookup(z, &varph->vnet, &varph->vmac); 42.185 if(ventry){ 42.186 err = VCEntry_update(ventry, msg, varph, state); 42.187 } else { 42.188 @@ -503,14 +511,14 @@ void VarpCache_sweep(VarpCache *z, int a 42.189 * @param local whether it's local or not 42.190 */ 42.191 void vcache_forward_varp(VarpHdr *varph, int local){ 42.192 - uint16_t opcode = ntohs(varph->vnetmsghdr.opcode); 42.193 + uint16_t opcode = ntohs(varph->hdr.opcode); 42.194 if(local){ 42.195 ConnList *l; 42.196 for(l = vnetd->connections; l; l = l->next){ 42.197 - varp_send(l->conn, opcode, varph->vnet, &varph->vmac, varph->addr); 42.198 + varp_send(l->conn, opcode, &varph->vnet, &varph->vmac, &varph->addr); 42.199 } 42.200 } else { 42.201 - varp_send(vnetd->bcast_conn, opcode, varph->vnet, &varph->vmac, varph->addr); 42.202 + varp_send(vnetd->bcast_conn, opcode, &varph->vnet, &varph->vmac, &varph->addr); 42.203 } 42.204 } 42.205 42.206 @@ -531,13 +539,13 @@ int vcache_handle_request(IPMessage *msg 42.207 #else 42.208 int vcache_handle_request(IPMessage *msg, VarpHdr *varph, int local){ 42.209 int err = -ENOENT; 42.210 - uint32_t vnet; 42.211 + VnetId *vnet; 42.212 Vmac *vmac; 42.213 VCEntry *ventry = NULL; 42.214 int reply = 0; 42.215 42.216 dprintf(">\n"); 42.217 - vnet = htonl(varph->vnet); 42.218 + vnet = &varph->vnet; 42.219 vmac = &varph->vmac; 42.220 ventry = VarpCache_lookup(vcache, vnet, vmac); 42.221 if(!ventry){ 42.222 @@ -605,13 +613,18 @@ int vcache_handle_message(IPMessage *msg 42.223 VarpHdr *varph = &vmsg->varp.varph; 42.224 42.225 dprintf(">\n"); 42.226 - if(1){ 42.227 +#ifdef DEBUG 42.228 + { 42.229 + char vnetbuf[VNET_ID_BUF]; 42.230 dprintf("> src=%s:%d\n", inet_ntoa(msg->saddr.sin_addr), ntohs(msg->saddr.sin_port)); 42.231 dprintf("> dst=%s:%d\n", inet_ntoa(msg->daddr.sin_addr), ntohs(msg->daddr.sin_port)); 42.232 - dprintf("> opcode=%d vnet=%u vmac=" MACFMT "\n", 42.233 - ntohs(varph->opcode), ntohl(varph->vnet), MAC6TUPLE(varph->vmac.mac)); 42.234 + dprintf("> opcode=%d vnet=%s vmac=" MACFMT "\n", 42.235 + ntohs(varph->opcode), 42.236 + VnetId_ntoa(&varph->vnet, vnetbuf), 42.237 + MAC6TUPLE(varph->vmac.mac)); 42.238 } 42.239 - switch(ntohs(varph->vnetmsghdr.opcode)){ 42.240 +#endif 42.241 + switch(ntohs(varph->hdr.opcode)){ 42.242 case VARP_OP_REQUEST: 42.243 err = vcache_handle_request(msg, varph, local); 42.244 break;
43.1 --- a/tools/vnet/vnetd/vcache.h Fri Aug 26 10:51:10 2005 +0000 43.2 +++ b/tools/vnet/vnetd/vcache.h Fri Aug 26 10:52:53 2005 +0000 43.3 @@ -93,7 +93,7 @@ typedef struct IPMessageQueue { 43.4 /** Key for varp cache entries. */ 43.5 typedef struct VCKey { 43.6 /** Vnet id (network order). */ 43.7 - uint32_t vnet; 43.8 + VnetId vnet; 43.9 /** Virtual MAC address. */ 43.10 Vmac vmac; 43.11 } VCKey; 43.12 @@ -103,7 +103,7 @@ typedef struct VCEntry { 43.13 VCKey key; 43.14 43.15 /** Care-of address for the key. */ 43.16 - uint32_t addr; 43.17 + VarpAddr addr; 43.18 43.19 /** Alias coa if we are a gateway. */ 43.20 //uint32_t gateway; 43.21 @@ -111,7 +111,7 @@ typedef struct VCEntry { 43.22 //uint32_t encaps; 43.23 43.24 /** Where this entry came from. */ 43.25 - uint32_t source; 43.26 + VarpAddr source; 43.27 43.28 /** Last-updated timestamp. */ 43.29 double timestamp;
44.1 --- a/tools/vnet/vnetd/vnetd.c Fri Aug 26 10:51:10 2005 +0000 44.2 +++ b/tools/vnet/vnetd/vnetd.c Fri Aug 26 10:52:53 2005 +0000 44.3 @@ -112,7 +112,6 @@ 44.4 #include <sys/wait.h> 44.5 #include <sys/select.h> 44.6 44.7 -//#include </usr/include/linux/ip.h> // For struct iphdr; 44.8 #include <linux/ip.h> // For struct iphdr; 44.9 44.10 #include <linux/if_ether.h> 44.11 @@ -492,22 +491,16 @@ int vnetd_forward_peer(Conn *conn, int p 44.12 dprintf("> addr=%s protocol=%d n=%d\n", 44.13 inet_ntoa(conn->addr.sin_addr), protocol, data_n); 44.14 string_stream_init(io, &sdata, buf, sizeof(buf)); 44.15 - dprintf("> 10\n"); 44.16 err = marshal_uint16(io, VNET_FWD_ID); 44.17 if(err < 0) goto exit; 44.18 - dprintf("> 20\n"); 44.19 err = marshal_uint16(io, 0); 44.20 if(err < 0) goto exit; 44.21 - dprintf("> 30\n"); 44.22 err = marshal_uint16(io, protocol); 44.23 if(err < 0) goto exit; 44.24 - dprintf("> 40\n"); 44.25 err = marshal_uint16(io, data_n); 44.26 if(err < 0) goto exit; 44.27 - dprintf("> 50\n"); 44.28 err = marshal_bytes(io, data, data_n); 44.29 if(err < 0) goto exit; 44.30 - dprintf("> 60 bytes=%d\n", IOStream_get_written(io)); 44.31 err = IOStream_write(conn->out, buf, IOStream_get_written(io)); 44.32 IOStream_flush(conn->out); 44.33 exit: 44.34 @@ -978,7 +971,7 @@ int vnetd_udp_conn(Vnetd *vnetd, Conn ** 44.35 int err = 0; 44.36 uint32_t addr = INADDR_ANY; 44.37 uint16_t port = vnetd->port; 44.38 - int flags = VSOCK_BIND | VSOCK_REUSE; 44.39 + int flags = (VSOCK_BIND | VSOCK_REUSE); 44.40 err = create_socket(SOCK_DGRAM, addr, port, flags, val); 44.41 return err; 44.42 } 44.43 @@ -1162,7 +1155,7 @@ int vnetd_main(Vnetd *vnetd){ 44.44 err = vnetd_broadcast_conn(vnetd, &vnetd->bcast_conn); 44.45 if(err < 0) goto exit; 44.46 { 44.47 - int flags = VSOCK_BROADCAST | VSOCK_MULTICAST; 44.48 + int flags = (VSOCK_BROADCAST | VSOCK_MULTICAST); 44.49 uint32_t mcaddr = vnetd->mcast_addr.sin_addr.s_addr; 44.50 44.51 err = vnetd_raw_socket(IPPROTO_ETHERIP, flags, mcaddr, &vnetd->etherip_sock);
45.1 --- a/tools/vnet/vnetd/vnetd.h Fri Aug 26 10:51:10 2005 +0000 45.2 +++ b/tools/vnet/vnetd/vnetd.h Fri Aug 26 10:52:53 2005 +0000 45.3 @@ -20,6 +20,7 @@ 45.4 #include <asm/types.h> 45.5 #include <linux/if_ether.h> 45.6 #include "if_varp.h" 45.7 +#include "varp_util.h" 45.8 45.9 #include "connection.h" 45.10 #include "sxpr.h"