diff --git a/network/openvswitch/README b/network/openvswitch/README new file mode 100644 index 0000000000..f8f2d09e41 --- /dev/null +++ b/network/openvswitch/README @@ -0,0 +1,19 @@ +Open vSwitch is a production quality, multilayer virtual switch licensed +under the open source Apache 2.0 license. It is designed to enable +massive network automation through programmatic extension, while still +supporting standard management interfaces (e.g. NetFlow, sFlow, RSPAN, +ERSPAN, CLI). In addition, it is designed to support distribution +across multiple physical servers similar to VMware.s vNetwork distributed +vswitch or Cisco.s Nexus 1000V. + +Open vSwitch can operate both as a soft switch running within the +hypervisor, and as the control stack for switching silicon. It has been +ported to multiple virtualization platforms and switching chipsets. It +is the default switch in the Xen Cloud Platform and also supports Xen, +XenServer, KVM, and VirtualBox. The bulk of the code is written in +platform-independent C and is easily ported to other environments. + +This package will build kernel modules that will be uses as replacements +for the bridge modules included with the stock Linux kernel. Open +vSwitch includes a kernel module if you wish to use the standard Linux +bridge utils to manage it. diff --git a/network/openvswitch/doinst.sh b/network/openvswitch/doinst.sh new file mode 100644 index 0000000000..9a89f95fb8 --- /dev/null +++ b/network/openvswitch/doinst.sh @@ -0,0 +1,29 @@ +config() { + NEW="$1" + OLD="$(dirname $NEW)/$(basename $NEW .new)" + # If there's no config file by that name, mv it over: + if [ ! -r $OLD ]; then + mv $NEW $OLD + elif [ "$(cat $OLD|md5sum)" = "$(cat $NEW|md5sum)" ]; then + # toss the redundant copy + rm $NEW + fi + # Otherwise, we leave the .new copy for the admin to consider... +} + +preserve_perms() { + NEW="$1" + OLD="$(dirname $NEW)/$(basename $NEW .new)" + if [ -e $OLD ]; then + cp -a $OLD ${NEW}.incoming + cat $NEW > ${NEW}.incoming + mv ${NEW}.incoming $NEW + fi + config $NEW +} + +preserve_perms etc/rc.d/rc.openvswitch.new + +if [ -x /sbin/depmod ]; then + chroot . /sbin/depmod -a >/dev/null 2>&1 +fi diff --git a/network/openvswitch/openvswitch.SlackBuild b/network/openvswitch/openvswitch.SlackBuild new file mode 100644 index 0000000000..df8fac18d3 --- /dev/null +++ b/network/openvswitch/openvswitch.SlackBuild @@ -0,0 +1,134 @@ +#!/bin/sh + +# Slackware build script for openvswitch + +# Copyright 2008-2011 Christopher Walker +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +PRGNAM=openvswitch +VERSION=1.2.0 +BUILD=${BUILD:-1} +TAG=${TAG:-_SBo} + +MODULEPATH=${MODULEPATH:-/lib/modules/$(uname -r)} + +if [ -z "$ARCH" ]; then + case "$( uname -m )" in + i?86) ARCH=i486 ;; + arm*) ARCH=arm ;; + *) ARCH=$( uname -m ) ;; + esac +fi + +CWD=$(pwd) +TMP=${TMP:-/tmp/SBo} +PKG=$TMP/package-$PRGNAM +OUTPUT=${OUTPUT:-/tmp} + +if [ "$ARCH" = "i486" ]; then + SLKCFLAGS="-O2 -march=i486 -mtune=i686" + LIBDIRSUFFIX="" +elif [ "$ARCH" = "i686" ]; then + SLKCFLAGS="-O2 -march=i686 -mtune=i686" + LIBDIRSUFFIX="" +elif [ "$ARCH" = "x86_64" ]; then + SLKCFLAGS="-O2 -fPIC" + LIBDIRSUFFIX="64" +else + SLKCFLAGS="-O2" + LIBDIRSUFFIX="" +fi + +set -e + +if [ ! -d $MODULEPATH ]; then + echo "Missing module path $MODULEPATH! Exiting script..." + exit +fi + +if [ ! -h $MODULEPATH/build ]; then + echo "Missing source patch $MODULEPATH/build! Exiting script..." + exit +fi + +KERNELPATH=$(readlink $MODULEPATH/build) + +rm -rf $PKG +mkdir -p $TMP $PKG $OUTPUT +cd $TMP +rm -rf $PRGNAM-$VERSION +tar xvf $CWD/$PRGNAM-$VERSION.tar.gz +cd $PRGNAM-$VERSION +chown -R root:root . +chmod -R u+w,go+r-w,a-s . + +CFLAGS="$SLKCFLAGS" \ +CXXFLAGS="$SLKCFLAGS" \ +./configure \ + --prefix=/usr \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --mandir=/usr/man \ + --docdir=/usr/doc/$PRGNAM-$VERSION \ + --with-l26=$KERNELPATH \ + --enable-ndebug \ + --enable-ssl + +make +make DESTDIR=$TMP/package-$PRGNAM install + +find $PKG | xargs file | grep -e "executable" -e "shared object" | grep ELF \ + | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true + +find $PKG/usr/man -type f -exec gzip -9 {} \; +for i in $( find $PKG/usr/man -type l ) ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done + +mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION/{schema,xen} +install -m 644 AUTHORS COPYING ChangeLog CodingStyle INSTALL.KVM \ + INSTALL.Linux INSTALL.RHEL INSTALL.SSL INSTALL.XenServer INSTALL.bridge \ + INSTALL.userspace NOTICE PORTING README README-gcov REPORTING-BUGS \ + SubmittingPatches WHY-OVS \ + $PKG/usr/doc/$PRGNAM-$VERSION +install -m 644 $CWD/xen/vif-openvswitch $CWD/xen/network-openvswitch \ + $CWD/xen/README \ + $PKG/usr/doc/$PRGNAM-$VERSION/xen +install -m 644 vswitchd/vswitch.ovsschema \ + $PKG/usr/doc/$PRGNAM-$VERSION/schema +cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild + +mkdir -p $PKG$MODULEPATH/kernel/extra/openvswitch +install -m 644 datapath/linux/openvswitch_mod.ko \ + $PKG$MODULEPATH/kernel/extra/openvswitch +install -m 644 datapath/linux/brcompat_mod.ko \ + $PKG$MODULEPATH/kernel/extra/openvswitch + +mkdir -p $PKG/etc/openvswitch + +mkdir -p $PKG/etc/rc.d +sed -e "s/@DOCDIR@/\/usr\/doc\/$PRGNAM-$VERSION/g" $CWD/rc.openvswitch > $PKG/etc/rc.d/rc.openvswitch.new + +mkdir -p $PKG/install +cat $CWD/slack-desc > $PKG/install/slack-desc +cat $CWD/doinst.sh > $PKG/install/doinst.sh + +mkdir -p $PKG/var/run/openvswitch + +cd $PKG +/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz} diff --git a/network/openvswitch/openvswitch.info b/network/openvswitch/openvswitch.info new file mode 100644 index 0000000000..3cd5eff0e3 --- /dev/null +++ b/network/openvswitch/openvswitch.info @@ -0,0 +1,10 @@ +PRGNAM="openvswitch" +VERSION="1.2.0" +HOMEPAGE="http://openvswitch.org" +DOWNLOAD="http://openvswitch.org/releases/openvswitch-1.2.0.tar.gz" +MD5SUM="f01a8fc15fb9f12d29cad6ecd3d6dfb9" +DOWNLOAD_x86_64="" +MD5SUM_x86_64="" +MAINTAINER="Christopher Walker" +EMAIL="kris240376@gmail.com" +APPROVED="Niels Horn" diff --git a/network/openvswitch/rc.openvswitch b/network/openvswitch/rc.openvswitch new file mode 100644 index 0000000000..5e0f3d561a --- /dev/null +++ b/network/openvswitch/rc.openvswitch @@ -0,0 +1,68 @@ +#!/bin/sh +# Start/stop/restart openvswitch. + +# To start Open vSwitch automatically at boot, be sure this script is +# executable: +# +# % chmod 755 /etc/rc.d/rc.openvswitch + +# Before you can run Open vSwitch daemon, you must have a database. To +# install an initial database, perform the following as root: +# +# % modprobe openvswitch_mod +# % ovsdb-tool create /etc/openvswitch/ovs-vswitchd.conf.db @DOCDIR@/schema/vswitch.ovsschema +# + +# Module to make Open vSwitch compatible with Linux bridge utils: +BRCOMPAT=0 + +SOCKET=/var/run/openvswitch/db.sock +VSPID=/var/run/openvswitch/ovs-vswitchd.pid +DBPID=/var/run/openvswitch/ovsdb-server.pid + +# Insert kernel driver for Open vSwitch: +/sbin/modprobe openvswitch_mod + +# Insert kernel driver for VLANs: +/sbin/modprobe 8021q + +# Insert kernel driver for bridge util compatibility: +if [ $BRCOMPAT -ne 0 ] ; then + /sbin/modprobe brcompat_mod +fi + +# Start openvswitch: +openvswitch_start() { + echo "Starting openvswitch: /etc/rc.d/rc.openvswitch" + /usr/sbin/ovsdb-server /etc/openvswitch/ovs-vswitchd.conf.db --remote=punix:$SOCKET --detach --pidfile=$DBPID + /usr/bin/ovs-vsctl --no-wait init + /usr/sbin/ovs-vswitchd unix:$SOCKET --detach --pidfile=$VSPID +} + +# Stop openvswitch: +openvswitch_stop() { + echo "Stopping openvswitch: /etc/rc.d/rc.openvswitch" + if [ -e $VSPID ]; then + pid=$(cat $VSPID) + /usr/bin/ovs-appctl -t /var/run/openvswitch/ovs-vswitchd.$pid.ctl exit + fi + if [ -e $DBPID ]; then + pid=$(cat $DBPID) + /usr/bin/ovs-appctl -t /var/run/openvswitch/ovsdb-server.$pid.ctl exit + fi +} + +case "$1" in +'start') + openvswitch_start + ;; +'stop') + openvswitch_stop + ;; +'restart') + openvswitch_stop + openvswitch_start + ;; +*) + echo "usage $0 start|stop|restart" +esac diff --git a/network/openvswitch/slack-desc b/network/openvswitch/slack-desc new file mode 100644 index 0000000000..d302c084c5 --- /dev/null +++ b/network/openvswitch/slack-desc @@ -0,0 +1,19 @@ +# HOW TO EDIT THIS FILE: +# The "handy ruler" below makes it easier to edit a package description. Line +# up the first '|' above the ':' following the base package name, and the '|' on +# the right side marks the last column you can put a character in. You must make +# exactly 11 lines for the formatting to be correct. It's also customary to +# leave one space after the ':'. + + |-----handy-ruler------------------------------------------------------| +openvswitch: openvswitch (multilayer virtual switch) +openvswitch: +openvswitch: Open vSwitch is a production quality, multilayer virtual switch +openvswitch: licensed under the open source Apache 2.0 license. It is designed +openvswitch: to enable massive network automation through programmatic extension, +openvswitch: while still supporting standard management interface (e.g. NetFlow, +openvswitch: sFlow, RSPAN, ERSPAN, CLI). +openvswitch: +openvswitch: Homepage: http://openvswitch.org/ +openvswitch: +openvswitch: diff --git a/network/openvswitch/xen/README b/network/openvswitch/xen/README new file mode 100644 index 0000000000..93889615e7 --- /dev/null +++ b/network/openvswitch/xen/README @@ -0,0 +1,39 @@ +Here are some scripts that I've written for use with Xen at my site. +In order to use these scripts with your Xen installation you'll need to copy +both the network-openvswitch and vif-openvswitch files to your +/etc/xen/scripts directory. You can instruct Xen to use these scripts by +editing your /etc/xen/xend-config.sxp file and specifying these scripts as +the default network-script and vif-script. + +For example, here are the entries in my xend-config.sxp file: + + (network-script 'network-openvswitch netdev=eth2 bridge=ovs0') + + (vif-script 'vif-openvswitch bridge=ovs0') + +If your network interface card and attached network switch support VLAN +tagged traffic, you can place virtual machines within a seperate VLAN by +appending a '.' and the VLAN tag number you wish the domain to use. For +example, to have all domains default to VLAN 2 you can do the following: + + (vif-script 'vif-openvswitch bridge=ovs0.2') + +You can also specify tagged traffic in the domain configuration file. + +If you are hosting a hardware virtualized domain understand that the +/etc/xen/scripts/qemu-ifup script is run instead of the vif-script specified +in the xend-config.sxp file. You'll need to edit this file to add the port +to the vswitch instead of using the brctl (unless of course you are using +the appropriate kernel module to control the vswitch using brctl.) Here is +a snippet from my qemu-ifup to handle hardware virtualized ports: + + if lsmod | grep -c openvswitch_mod 1> /dev/null && ! lsmod | grep -c brcompat_mod 1> /dev/null + then + ovs-vsctl -- --may-exist add-port $bridge $1 + else + brctl addif $bridge $1 || true + fi + +This doesn't handle tagged traffic. I'll leave that as an exercise for you. + +Enjoy. diff --git a/network/openvswitch/xen/network-openvswitch b/network/openvswitch/xen/network-openvswitch new file mode 100644 index 0000000000..45cda0b195 --- /dev/null +++ b/network/openvswitch/xen/network-openvswitch @@ -0,0 +1,124 @@ +#!/bin/bash +#============================================================================ +# Default Xen network start/stop script. +# Xend calls a network script when it starts. +# The script name to use is defined in ${XEN_CONFIG_DIR}/xend-config.sxp +# in the network-script field. +# +# This script creates a virtual switch (default ${netdev}) and adds a +# device (defaults to eth0) to it. The interface that this Open vSwitch +# is created on should not have a working IP address and will be used as +# a switch for Xen domU's. +# +# Usage: +# network-openvswitch (start|stop|status) {VAR=VAL}* +# +# Vars: +# bridge The bridge to use (default xenvs0). +# netdev The interface to add to the bridge (default eth0). This +# device should not be configured with an IP address. If so +# this script will tear down the interface and bring it back up +# without an IP address. +# +# start: +# Creates the bridge as bridge +# Enslaves netdev to bridge +# +# stop: +# Removes netdev from the bridge +# Deletes bridge +# +# status: +# Print addresses, interfaces +# +#============================================================================ + +dir=$(dirname "$0") +. "$dir/logging.sh" +. "$dir/xen-script-common.sh" +. "$dir/xen-network-common.sh" +. "$dir/locking.sh" + +findCommand "$@" +evalVariables "$@" + +netdev=${netdev:-eth0} +bridge=${bridge:-ovs0} + +addr=`ip addr show dev ${netdev} | egrep '^ *inet' | sed -e 's/ *inet //' -e 's/ .*//'` +if [ -n "$addr" ]; then + echo "Invalid device: ${netdev} is up and has a valid IP address!" >&2 + exit 1 +fi + +show_status () { + local dev=$1 + local bridge=$2 + + echo '============================================================' + echo 'vSwitch interfaces' + ovs-vsctl list-ifaces ${bridge} + echo ' ' + echo 'vSwitch ports' + ovs-vsctl list-ports ${bridge} + echo '============================================================' +} + +op_start () { + if [ "${bridge}" = "null" ] ; then + return + fi + + ifconfig "${netdev}" down + ifconfig "${netdev}" 0.0.0.0 up + ovs-vsctl -- --may-exist add-br ${bridge} + ifconfig "${bridge}" 0.0.0.0 up + ovs-vsctl -- --may-exist add-port ${bridge} ${netdev} + + # Remove any stale ports from last time virtual switch was running. + # Open vSwitch has the habit of remembering port settings between + # runs. + for port in $(ovs-vsctl list-ports ${bridge}) + do + if [ "${port}" != "${netdev}" ] + then + ifconfig "${port}" down + ovs-vsctl del-port ${port} + fi + done +} + +op_stop () { + if [ "${bridge}" = "null" ]; then + return + fi + + # Remove all ports from virtual switch. + for port in $(ovs-vsctl list-ports ${bridge}) + do + ifconfig "${port}" down + ovs-vsctl del-port ${port} + done + + ifconfig "${bridge}" down + ovs-vsctl -- --if-exists del-br ${bridge} +} + +case "$command" in + start) + op_start + ;; + + stop) + op_stop + ;; + + status) + show_status ${netdev} ${bridge} + ;; + + *) + echo "Unknown command: $command" >&2 + echo 'Valid commands are: start, stop, status' >&2 + exit 1 +esac diff --git a/network/openvswitch/xen/vif-openvswitch b/network/openvswitch/xen/vif-openvswitch new file mode 100644 index 0000000000..bdcd7c46f7 --- /dev/null +++ b/network/openvswitch/xen/vif-openvswitch @@ -0,0 +1,86 @@ +#!/bin/bash +#============================================================================ +# ${XEN_SCRIPT_DIR}/vif-openvswitch +# +# Script for configuring a vif using Open vSwitch. +# +# Usage: +# vif-openvswitch (add|remove|online|offline) +# +# Environment vars: +# vif vif interface name (required). +# XENBUS_PATH path to this device's details in the XenStore (required). +# +# Read from the store: +# bridge bridge to add the vif to (optional). Defaults to searching for the +# bridge itself. +# +# up: +# Enslaves the vif interface to the bridge. +# +# down: +# Removes the vif interface from the bridge. +#============================================================================ + +dir=$(dirname "$0") +. "$dir/vif-common.sh" + +bridge=${bridge:-} +bridge=$(xenstore_read_default "$XENBUS_PATH/bridge" "$bridge") + +if [ -z "${bridge}" ] +then + bridge=$(ovs-vsctl listbr | cut -d " +" -f 1) + + if [ -z "${bridge}" ] + then + fatal "Could not find bridge and none was specified" + fi +fi + +tag=${tag:-} + +# Domain on VLAN tagged bridge? +RET=0 +ovs-vsctl list-br | grep -c ${bridge} 1>/dev/null 2>&1 || RET=1 +if [ $RET -eq 1 ] +then + if [[ $bridge =~ \.[[:digit:]]{1,4}$ ]] + then + tag=$(echo ${bridge} | cut -d "." -f 2) + bridge=$(echo ${bridge} | cut -d "." -f 1) + else + fatal "Could not find bridge device ${bridge}" + fi +fi + +RET=0 +ovs-vsctl list-br | grep -c ${bridge} 1>/dev/null 2>&1 || RET=1 +if [ $RET -eq 1 ] +then + fatal "Could not find bridge device ${bridge}" +fi + +log debug "Successful vif-bridge $command for ${vif}, bridge ${bridge}." +case "$command" in + online) + ifconfig "${vif}" 0.0.0.0 up + if [ -z $tag ] + then + ovs-vsctl -- --may-exist add-port ${bridge} ${vif} + else + ovs-vsctl -- --may-exist add-port ${bridge} ${vif} tag=${tag} + fi + ;; + + offline) + ovs-vsctl -- --if-exists del-port ${bridge} ${vif} + ifconfig "$vif" 0.0.0.0 down + ;; +esac + +if [ "$command" == "online" ] +then + success +fi