Merge pull request #26 from mininet/devel/install-oneiric
Devel/install oneiric
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
mnexec
|
mnexec
|
||||||
*.pyc
|
*.pyc
|
||||||
|
*~
|
||||||
mininet.egg-info
|
mininet.egg-info
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ disable-msg-cat=IR
|
|||||||
#enable-msg=
|
#enable-msg=
|
||||||
|
|
||||||
# Disable the message(s) with the given id(s).
|
# Disable the message(s) with the given id(s).
|
||||||
disable-msg=W0704,C0103,W0231,E1102,W0511,W0142,R0902,R0903,R0904,R0913,R0914,R0801
|
disable=W0704,C0103,W0231,E1102,W0511,W0142,R0902,R0903,R0904,R0913,R0914,R0801,I0011
|
||||||
|
|
||||||
|
|
||||||
[REPORTS]
|
[REPORTS]
|
||||||
|
|||||||
@@ -602,7 +602,7 @@ class MiniEdit( Frame ):
|
|||||||
cleanUpScreens()
|
cleanUpScreens()
|
||||||
self.net = None
|
self.net = None
|
||||||
|
|
||||||
def xterm( self, ignore=None ):
|
def xterm( self, _ignore=None ):
|
||||||
"Make an xterm when a button is pressed."
|
"Make an xterm when a button is pressed."
|
||||||
if ( self.selection is None or
|
if ( self.selection is None or
|
||||||
self.net is None or
|
self.net is None or
|
||||||
|
|||||||
+7
-7
@@ -116,19 +116,19 @@ class Node( object ):
|
|||||||
self.shell = None
|
self.shell = None
|
||||||
|
|
||||||
# Subshell I/O, commands and control
|
# Subshell I/O, commands and control
|
||||||
def read( self, bytes=1024 ):
|
def read( self, maxbytes=1024 ):
|
||||||
"""Buffered read from node, non-blocking.
|
"""Buffered read from node, non-blocking.
|
||||||
bytes: maximum number of bytes to return"""
|
maxbytes: maximum number of bytes to return"""
|
||||||
count = len( self.readbuf )
|
count = len( self.readbuf )
|
||||||
if count < bytes:
|
if count < maxbytes:
|
||||||
data = os.read( self.stdout.fileno(), bytes - count )
|
data = os.read( self.stdout.fileno(), maxbytes - count )
|
||||||
self.readbuf += data
|
self.readbuf += data
|
||||||
if bytes >= len( self.readbuf ):
|
if maxbytes >= len( self.readbuf ):
|
||||||
result = self.readbuf
|
result = self.readbuf
|
||||||
self.readbuf = ''
|
self.readbuf = ''
|
||||||
else:
|
else:
|
||||||
result = self.readbuf[ :bytes ]
|
result = self.readbuf[ :maxbytes ]
|
||||||
self.readbuf = self.readbuf[ bytes: ]
|
self.readbuf = self.readbuf[ maxbytes: ]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def readline( self ):
|
def readline( self ):
|
||||||
|
|||||||
+3
-3
@@ -136,13 +136,13 @@ def createLink( node1, node2, port1=None, port2=None ):
|
|||||||
|
|
||||||
# IP and Mac address formatting and parsing
|
# IP and Mac address formatting and parsing
|
||||||
|
|
||||||
def _colonHex( val, bytes ):
|
def _colonHex( val, count ):
|
||||||
"""Generate colon-hex string.
|
"""Generate colon-hex string.
|
||||||
val: input as unsigned int
|
val: input as unsigned int
|
||||||
bytes: number of bytes to convert
|
count: number of bytes to convert
|
||||||
returns: chStr colon-hex string"""
|
returns: chStr colon-hex string"""
|
||||||
pieces = []
|
pieces = []
|
||||||
for i in range( bytes - 1, -1, -1 ):
|
for i in range( count - 1, -1, -1 ):
|
||||||
piece = ( ( 0xff << ( i * 8 ) ) & val ) >> ( i * 8 )
|
piece = ( ( 0xff << ( i * 8 ) ) & val ) >> ( i * 8 )
|
||||||
pieces.append( '%02x' % piece )
|
pieces.append( '%02x' % piece )
|
||||||
chStr = ':'.join( pieces )
|
chStr = ':'.join( pieces )
|
||||||
|
|||||||
+64
-38
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Mininet install script for Debian
|
# Mininet install script for Ubuntu (and Debian Lenny)
|
||||||
# Brandon Heller (brandonh@stanford.edu)
|
# Brandon Heller (brandonh@stanford.edu)
|
||||||
|
|
||||||
# Fail on error
|
# Fail on error
|
||||||
@@ -11,8 +11,22 @@ set -o nounset
|
|||||||
# Location of CONFIG_NET_NS-enabled kernel(s)
|
# Location of CONFIG_NET_NS-enabled kernel(s)
|
||||||
KERNEL_LOC=http://www.openflow.org/downloads/mininet
|
KERNEL_LOC=http://www.openflow.org/downloads/mininet
|
||||||
|
|
||||||
|
# Attempt to identify Linux release
|
||||||
|
|
||||||
|
DIST=Unknown
|
||||||
|
RELEASE=Unknown
|
||||||
|
CODENAME=Unknown
|
||||||
test -e /etc/debian_version && DIST="Debian"
|
test -e /etc/debian_version && DIST="Debian"
|
||||||
grep Ubuntu /etc/lsb-release &> /dev/null && DIST="Ubuntu"
|
grep Ubuntu /etc/lsb-release &> /dev/null && DIST="Ubuntu"
|
||||||
|
if [ "$DIST" = "Ubuntu" ] || [ "$DIST" = "Debian" ]; then
|
||||||
|
sudo apt-get install -y lsb-release
|
||||||
|
fi
|
||||||
|
if which lsb_release &> /dev/null; then
|
||||||
|
DIST=`lsb_release -is`
|
||||||
|
RELEASE=`lsb_release -rs`
|
||||||
|
CODENAME=`lsb_release -cs`
|
||||||
|
fi
|
||||||
|
echo "Detected Linux distribution: $DIST $RELEASE $CODENAME"
|
||||||
|
|
||||||
# Kernel params
|
# Kernel params
|
||||||
|
|
||||||
@@ -21,30 +35,32 @@ if [ "$DIST" = "Debian" ]; then
|
|||||||
KERNEL_HEADERS=linux-headers-${KERNEL_NAME}_${KERNEL_NAME}-10.00.Custom_i386.deb
|
KERNEL_HEADERS=linux-headers-${KERNEL_NAME}_${KERNEL_NAME}-10.00.Custom_i386.deb
|
||||||
KERNEL_IMAGE=linux-image-${KERNEL_NAME}_${KERNEL_NAME}-10.00.Custom_i386.deb
|
KERNEL_IMAGE=linux-image-${KERNEL_NAME}_${KERNEL_NAME}-10.00.Custom_i386.deb
|
||||||
elif [ "$DIST" = "Ubuntu" ]; then
|
elif [ "$DIST" = "Ubuntu" ]; then
|
||||||
|
if [ "$RELEASE" = "10.04" ]; then
|
||||||
|
KERNEL_NAME='3.0.0-15-generic'
|
||||||
|
else
|
||||||
KERNEL_NAME=`uname -r`
|
KERNEL_NAME=`uname -r`
|
||||||
|
fi
|
||||||
KERNEL_HEADERS=linux-headers-${KERNEL_NAME}
|
KERNEL_HEADERS=linux-headers-${KERNEL_NAME}
|
||||||
else
|
else
|
||||||
echo "Install.sh currently only supports Ubuntu and Debian."
|
echo "Install.sh currently only supports Ubuntu and Debian."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Detected Linux distribution: $DIST"
|
|
||||||
|
|
||||||
# Kernel Deb pkg to be removed:
|
# Kernel Deb pkg to be removed:
|
||||||
KERNEL_IMAGE_OLD=linux-image-2.6.26-2-686
|
KERNEL_IMAGE_OLD=linux-image-2.6.26-2-686
|
||||||
|
|
||||||
DRIVERS_DIR=/lib/modules/${KERNEL_NAME}/kernel/drivers/net
|
DRIVERS_DIR=/lib/modules/${KERNEL_NAME}/kernel/drivers/net
|
||||||
|
|
||||||
OVS_RELEASE=v1.1.1
|
OVS_RELEASE=v1.2.2
|
||||||
OVS_DIR=~/openvswitch
|
OVS_SRC=~/openvswitch
|
||||||
OVS_KMOD=openvswitch_mod.ko
|
OVS_BUILD=$OVS_SRC/build-$KERNEL_NAME
|
||||||
|
OVS_KMODS=($OVS_BUILD/datapath/linux/{openvswitch_mod.ko,brcompat_mod.ko})
|
||||||
|
|
||||||
function kernel {
|
function kernel {
|
||||||
echo "Install Mininet-compatible kernel"
|
echo "Install Mininet-compatible kernel if necessary"
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
|
|
||||||
if [ "$DIST" = "Debian" ]; then
|
if [ "$DIST" = "Debian" ]; then
|
||||||
|
|
||||||
# The easy approach: download pre-built linux-image and linux-headers packages:
|
# The easy approach: download pre-built linux-image and linux-headers packages:
|
||||||
wget -c $KERNEL_LOC/$KERNEL_HEADERS
|
wget -c $KERNEL_LOC/$KERNEL_HEADERS
|
||||||
wget -c $KERNEL_LOC/$KERNEL_IMAGE
|
wget -c $KERNEL_LOC/$KERNEL_IMAGE
|
||||||
@@ -63,9 +79,13 @@ function kernel {
|
|||||||
# Ensure /boot/grub/menu.lst boots with initrd image:
|
# Ensure /boot/grub/menu.lst boots with initrd image:
|
||||||
sudo update-grub
|
sudo update-grub
|
||||||
|
|
||||||
# The default should be the new kernel. Otherwise, you may need to modify /boot/grub/menu.lst to set the default to the entry corresponding to the kernel you just installed.
|
# The default should be the new kernel. Otherwise, you may need to modify
|
||||||
|
# /boot/grub/menu.lst to set the default to the entry corresponding to the
|
||||||
|
# kernel you just installed.
|
||||||
|
fi
|
||||||
|
if [ "$DIST" = "Ubuntu" ] && [ "$RELEASE" = "10.04" ]; then
|
||||||
|
sudo apt-get -y install linux-image-$KERNEL_NAME
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function kernel_clean {
|
function kernel_clean {
|
||||||
@@ -84,12 +104,13 @@ function mn_deps {
|
|||||||
sudo aptitude install -y gcc make screen psmisc xterm ssh iperf iproute \
|
sudo aptitude install -y gcc make screen psmisc xterm ssh iperf iproute \
|
||||||
python-setuptools python-networkx
|
python-setuptools python-networkx
|
||||||
|
|
||||||
if [ "$DIST" = "Ubuntu" ] && [ "`lsb_release -sr`" = "10.04" ]; then
|
if [ "$DIST" = "Ubuntu" ] && [ "$RELEASE" = "10.04" ]; then
|
||||||
echo "Upgrading networkx to avoid deprecation warning"
|
echo "Upgrading networkx to avoid deprecation warning"
|
||||||
sudo easy_install --upgrade networkx
|
sudo easy_install --upgrade networkx
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#Add sysctl parameters as noted in the INSTALL file to increase kernel limits to support larger setups:
|
# Add sysctl parameters as noted in the INSTALL file to increase kernel
|
||||||
|
# limits to support larger setups:
|
||||||
sudo su -c "cat $HOME/mininet/util/sysctl_addon >> /etc/sysctl.conf"
|
sudo su -c "cat $HOME/mininet/util/sysctl_addon >> /etc/sysctl.conf"
|
||||||
|
|
||||||
# Load new sysctl settings:
|
# Load new sysctl settings:
|
||||||
@@ -111,7 +132,8 @@ function of {
|
|||||||
echo "Installing OpenFlow and its tools..."
|
echo "Installing OpenFlow and its tools..."
|
||||||
|
|
||||||
cd ~/
|
cd ~/
|
||||||
sudo apt-get install -y git-core automake m4 pkg-config libtool make libc6-dev autoconf autotools-dev gcc
|
sudo apt-get install -y git-core automake m4 pkg-config libtool \
|
||||||
|
make libc6-dev autoconf autotools-dev gcc
|
||||||
git clone git://openflowswitch.org/openflow.git
|
git clone git://openflowswitch.org/openflow.git
|
||||||
cd ~/openflow
|
cd ~/openflow
|
||||||
|
|
||||||
@@ -134,7 +156,8 @@ function of {
|
|||||||
mkdir -p ~/.wireshark
|
mkdir -p ~/.wireshark
|
||||||
cp ~/mininet/util/colorfilters ~/.wireshark
|
cp ~/mininet/util/colorfilters ~/.wireshark
|
||||||
|
|
||||||
# Remove avahi-daemon, which may cause unwanted discovery packets to be sent during tests, near link status changes:
|
# Remove avahi-daemon, which may cause unwanted discovery packets to be
|
||||||
|
# sent during tests, near link status changes:
|
||||||
sudo apt-get remove -y avahi-daemon
|
sudo apt-get remove -y avahi-daemon
|
||||||
|
|
||||||
# Disable IPv6. Add to /etc/modprobe.d/blacklist:
|
# Disable IPv6. Add to /etc/modprobe.d/blacklist:
|
||||||
@@ -146,12 +169,12 @@ function of {
|
|||||||
sudo sh -c "echo 'blacklist net-pf-10\nblacklist ipv6' >> $BLACKLIST"
|
sudo sh -c "echo 'blacklist net-pf-10\nblacklist ipv6' >> $BLACKLIST"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Install OpenVSwitch
|
# Install Open vSwitch
|
||||||
# Instructions derived from OVS INSTALL, INSTALL.OpenFlow and README files.
|
# Instructions derived from OVS INSTALL, INSTALL.OpenFlow and README files.
|
||||||
function ovs {
|
function ovs {
|
||||||
echo "Installing OpenVSwitch..."
|
echo "Installing Open vSwitch..."
|
||||||
|
|
||||||
if [ "$DIST" = "Debian" ]; then
|
if [ "$DIST" = "Debian" ] && [ "$CODENAME" == "lenny" ]; then
|
||||||
sudo aptitude -y install pkg-config gcc make git-core python-dev libssl-dev
|
sudo aptitude -y install pkg-config gcc make git-core python-dev libssl-dev
|
||||||
# Install Autoconf 2.63+ backport from Debian Backports repo:
|
# Install Autoconf 2.63+ backport from Debian Backports repo:
|
||||||
# Instructions from http://backports.org/dokuwiki/doku.php?id=instructions
|
# Instructions from http://backports.org/dokuwiki/doku.php?id=instructions
|
||||||
@@ -168,7 +191,7 @@ function ovs {
|
|||||||
# Install OVS from release
|
# Install OVS from release
|
||||||
cd ~/
|
cd ~/
|
||||||
git clone git://openvswitch.org/openvswitch
|
git clone git://openvswitch.org/openvswitch
|
||||||
cd $OVS_DIR
|
cd $OVS_SRC
|
||||||
git checkout $OVS_RELEASE
|
git checkout $OVS_RELEASE
|
||||||
./boot.sh
|
./boot.sh
|
||||||
BUILDDIR=/lib/modules/${KERNEL_NAME}/build
|
BUILDDIR=/lib/modules/${KERNEL_NAME}/build
|
||||||
@@ -176,10 +199,14 @@ function ovs {
|
|||||||
echo "Creating build sdirectory $BUILDDIR"
|
echo "Creating build sdirectory $BUILDDIR"
|
||||||
sudo mkdir -p $BUILDDIR
|
sudo mkdir -p $BUILDDIR
|
||||||
fi
|
fi
|
||||||
opts="--with-l26=$BUILDDIR"
|
opts="--with-linux=$BUILDDIR"
|
||||||
./configure $opts
|
mkdir -p $OVS_BUILD
|
||||||
|
cd $OVS_BUILD
|
||||||
|
../configure $opts
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
|
# openflowd is deprecated, but for now copy it in
|
||||||
|
sudo cp tests/test-openflowd /usr/local/bin/ovs-openflowd
|
||||||
}
|
}
|
||||||
|
|
||||||
# Install NOX with tutorial files
|
# Install NOX with tutorial files
|
||||||
@@ -187,7 +214,8 @@ function nox {
|
|||||||
echo "Installing NOX w/tutorial files..."
|
echo "Installing NOX w/tutorial files..."
|
||||||
|
|
||||||
# Install NOX deps:
|
# Install NOX deps:
|
||||||
sudo apt-get -y install autoconf automake g++ libtool python python-twisted swig libxerces-c2-dev libssl-dev make
|
sudo apt-get -y install autoconf automake g++ libtool python python-twisted \
|
||||||
|
swig libssl-dev make
|
||||||
if [ "$DIST" = "Debian" ]; then
|
if [ "$DIST" = "Debian" ]; then
|
||||||
sudo apt-get -y install libboost1.35-dev
|
sudo apt-get -y install libboost1.35-dev
|
||||||
elif [ "$DIST" = "Ubuntu" ]; then
|
elif [ "$DIST" = "Ubuntu" ]; then
|
||||||
@@ -198,21 +226,22 @@ function nox {
|
|||||||
# Install NOX optional deps:
|
# Install NOX optional deps:
|
||||||
sudo apt-get install -y libsqlite3-dev python-simplejson
|
sudo apt-get install -y libsqlite3-dev python-simplejson
|
||||||
|
|
||||||
#Install NOX:
|
# Fetch NOX destiny
|
||||||
cd ~/
|
cd ~/
|
||||||
git clone git://openflowswitch.org/nox-tutorial noxcore
|
git clone git://noxrepo.org/nox noxcore
|
||||||
cd noxcore
|
cd noxcore
|
||||||
|
git checkout -b destiny remotes/origin/destiny
|
||||||
|
|
||||||
# With later autoconf versions this doesn't quite work:
|
# Apply patches
|
||||||
./boot.sh --apps-core || true
|
git checkout -b tutorial-destiny
|
||||||
if [ "$DIST" = "Debian" ]; then
|
git am ~/mininet/util/nox-patches/*.patch
|
||||||
# So use this instead:
|
|
||||||
autoreconf --install --force
|
# Build
|
||||||
fi
|
./boot.sh
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
../configure --with-python=yes
|
../configure
|
||||||
make
|
make -j3
|
||||||
#make check
|
#make check
|
||||||
|
|
||||||
# Add NOX_CORE_DIR env var:
|
# Add NOX_CORE_DIR env var:
|
||||||
@@ -293,16 +322,13 @@ function other {
|
|||||||
function modprobe {
|
function modprobe {
|
||||||
echo "Setting up modprobe for OVS kmod..."
|
echo "Setting up modprobe for OVS kmod..."
|
||||||
|
|
||||||
sudo cp $OVS_DIR/datapath/linux-2.6/$OVS_KMOD $DRIVERS_DIR
|
sudo cp $OVS_KMODS $DRIVERS_DIR
|
||||||
sudo depmod -a ${KERNEL_NAME}
|
sudo depmod -a ${KERNEL_NAME}
|
||||||
}
|
}
|
||||||
|
|
||||||
function all {
|
function all {
|
||||||
echo "Running all commands..."
|
echo "Running all commands..."
|
||||||
if [ "$DIST" != "Ubuntu" ]; then
|
|
||||||
# Ubuntu ships with Mininet-compatible kernel
|
|
||||||
kernel
|
kernel
|
||||||
fi
|
|
||||||
mn_deps
|
mn_deps
|
||||||
of
|
of
|
||||||
ovs
|
ovs
|
||||||
@@ -326,7 +352,7 @@ function vm_clean {
|
|||||||
history -c # note this won't work if you have multiple bash sessions
|
history -c # note this won't work if you have multiple bash sessions
|
||||||
rm -f ~/.bash_history # need to clear in memory and remove on disk
|
rm -f ~/.bash_history # need to clear in memory and remove on disk
|
||||||
rm -f ~/.ssh/id_rsa* ~/.ssh/known_hosts
|
rm -f ~/.ssh/id_rsa* ~/.ssh/known_hosts
|
||||||
sudo rm -f ~/.ssh/authorized_keys2
|
sudo rm -f ~/.ssh/authorized_keys*
|
||||||
|
|
||||||
# Remove Mininet files
|
# Remove Mininet files
|
||||||
#sudo rm -f /lib/modules/python2.5/site-packages/mininet*
|
#sudo rm -f /lib/modules/python2.5/site-packages/mininet*
|
||||||
@@ -347,8 +373,8 @@ function usage {
|
|||||||
printf 'Usage: %s [-acdfhkmntvxy]\n\n' $(basename $0) >&2
|
printf 'Usage: %s [-acdfhkmntvxy]\n\n' $(basename $0) >&2
|
||||||
|
|
||||||
printf 'This install script attempts to install useful packages\n' >&2
|
printf 'This install script attempts to install useful packages\n' >&2
|
||||||
printf 'for Mininet. It should (hopefully) work on Ubuntu 10.04 and\n' >&2
|
printf 'for Mininet. It should (hopefully) work on Ubuntu 10.04, 11.10\n' >&2
|
||||||
printf 'Debian 5.0 (Lenny). If you run into trouble, try\n' >&2
|
printf 'and Debian 5.0 (Lenny). If you run into trouble, try\n' >&2
|
||||||
printf 'installing one thing at a time, and looking at the \n' >&2
|
printf 'installing one thing at a time, and looking at the \n' >&2
|
||||||
printf 'specific installation function in this script.\n\n' >&2
|
printf 'specific installation function in this script.\n\n' >&2
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,298 @@
|
|||||||
|
From 5c9610ffb88c89b0f36359ad3c7547831482a3ff Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bob Lantz <rlantz@cs.stanford.edu>
|
||||||
|
Date: Fri, 3 Feb 2012 14:48:58 -0800
|
||||||
|
Subject: [PATCH] OpenFlow tutorial port nox-destiny.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/nox/coreapps/examples/Makefile.am | 2 +-
|
||||||
|
src/nox/coreapps/examples/tutorial/Makefile.am | 25 ++++
|
||||||
|
src/nox/coreapps/examples/tutorial/meta.json | 12 ++
|
||||||
|
src/nox/coreapps/examples/tutorial/pytutorial.py | 67 +++++++++++
|
||||||
|
src/nox/coreapps/examples/tutorial/tutorial.cc | 134 ++++++++++++++++++++++
|
||||||
|
5 files changed, 239 insertions(+), 1 deletions(-)
|
||||||
|
create mode 100644 src/nox/coreapps/examples/tutorial/Makefile.am
|
||||||
|
create mode 100644 src/nox/coreapps/examples/tutorial/__init__.py
|
||||||
|
create mode 100644 src/nox/coreapps/examples/tutorial/meta.json
|
||||||
|
create mode 100644 src/nox/coreapps/examples/tutorial/pytutorial.py
|
||||||
|
create mode 100644 src/nox/coreapps/examples/tutorial/tutorial.cc
|
||||||
|
|
||||||
|
diff --git a/src/nox/coreapps/examples/Makefile.am b/src/nox/coreapps/examples/Makefile.am
|
||||||
|
index 126f32e..1a0458c 100644
|
||||||
|
--- a/src/nox/coreapps/examples/Makefile.am
|
||||||
|
+++ b/src/nox/coreapps/examples/Makefile.am
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
include ../../../Make.vars
|
||||||
|
|
||||||
|
-SUBDIRS = t
|
||||||
|
+SUBDIRS = tutorial t
|
||||||
|
|
||||||
|
EXTRA_DIST =\
|
||||||
|
meta.json\
|
||||||
|
diff --git a/src/nox/coreapps/examples/tutorial/Makefile.am b/src/nox/coreapps/examples/tutorial/Makefile.am
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..51cf921
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/nox/coreapps/examples/tutorial/Makefile.am
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+include ../../../../Make.vars
|
||||||
|
+
|
||||||
|
+EXTRA_DIST =\
|
||||||
|
+ meta.xml \
|
||||||
|
+ __init__.py \
|
||||||
|
+ pytutorial.py
|
||||||
|
+
|
||||||
|
+if PY_ENABLED
|
||||||
|
+AM_CPPFLAGS += $(PYTHON_CPPFLAGS)
|
||||||
|
+endif # PY_ENABLED
|
||||||
|
+
|
||||||
|
+pkglib_LTLIBRARIES = \
|
||||||
|
+ tutorial.la
|
||||||
|
+
|
||||||
|
+tutorial_la_CPPFLAGS = $(AM_CPPFLAGS) -I $(top_srcdir)/src/nox -I $(top_srcdir)/src/nox/coreapps/
|
||||||
|
+tutorial_la_SOURCES = tutorial.cc
|
||||||
|
+tutorial_la_LDFLAGS = -module -export-dynamic
|
||||||
|
+
|
||||||
|
+NOX_RUNTIMEFILES = meta.json \
|
||||||
|
+ __init__.py \
|
||||||
|
+ pytutorial.py
|
||||||
|
+
|
||||||
|
+all-local: nox-all-local
|
||||||
|
+clean-local: nox-clean-local
|
||||||
|
+install-exec-hook: nox-install-local
|
||||||
|
diff --git a/src/nox/coreapps/examples/tutorial/__init__.py b/src/nox/coreapps/examples/tutorial/__init__.py
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e69de29
|
||||||
|
diff --git a/src/nox/coreapps/examples/tutorial/meta.json b/src/nox/coreapps/examples/tutorial/meta.json
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..7a9f227
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/nox/coreapps/examples/tutorial/meta.json
|
||||||
|
@@ -0,0 +1,12 @@
|
||||||
|
+{
|
||||||
|
+ "components": [
|
||||||
|
+ {
|
||||||
|
+ "name": "tutorial",
|
||||||
|
+ "library": "tutorial"
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ "name": "pytutorial",
|
||||||
|
+ "python": "nox.coreapps.examples.tutorial.pytutorial"
|
||||||
|
+ }
|
||||||
|
+ ]
|
||||||
|
+}
|
||||||
|
diff --git a/src/nox/coreapps/examples/tutorial/pytutorial.py b/src/nox/coreapps/examples/tutorial/pytutorial.py
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..1e21c0b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/nox/coreapps/examples/tutorial/pytutorial.py
|
||||||
|
@@ -0,0 +1,67 @@
|
||||||
|
+# Tutorial Controller
|
||||||
|
+# Starts as a hub, and your job is to turn this into a learning switch.
|
||||||
|
+
|
||||||
|
+import logging
|
||||||
|
+
|
||||||
|
+from nox.lib.core import *
|
||||||
|
+import nox.lib.openflow as openflow
|
||||||
|
+from nox.lib.packet.ethernet import ethernet
|
||||||
|
+from nox.lib.packet.packet_utils import mac_to_str, mac_to_int
|
||||||
|
+
|
||||||
|
+log = logging.getLogger('nox.coreapps.tutorial.pytutorial')
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class pytutorial(Component):
|
||||||
|
+
|
||||||
|
+ def __init__(self, ctxt):
|
||||||
|
+ Component.__init__(self, ctxt)
|
||||||
|
+ # Use this table to store MAC addresses in the format of your choice;
|
||||||
|
+ # Functions already imported, including mac_to_str, and mac_to_int,
|
||||||
|
+ # should prove useful for converting the byte array provided by NOX
|
||||||
|
+ # for packet MAC destination fields.
|
||||||
|
+ # This table is initialized to empty when your module starts up.
|
||||||
|
+ self.mac_to_port = {} # key: MAC addr; value: port
|
||||||
|
+
|
||||||
|
+ def learn_and_forward(self, dpid, inport, packet, buf, bufid):
|
||||||
|
+ """Learn MAC src port mapping, then flood or send unicast."""
|
||||||
|
+
|
||||||
|
+ # Initial hub behavior: flood packet out everything but input port.
|
||||||
|
+ # Comment out the line below when starting the exercise.
|
||||||
|
+ self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
|
||||||
|
+
|
||||||
|
+ # Starter psuedocode for learning switch exercise below: you'll need to
|
||||||
|
+ # replace each pseudocode line with more specific Python code.
|
||||||
|
+
|
||||||
|
+ # Learn the port for the source MAC
|
||||||
|
+ #self.mac_to_port = <fill in>
|
||||||
|
+ #if (destination MAC of the packet is known):
|
||||||
|
+ # Send unicast packet to known output port
|
||||||
|
+ #self.send_openflow( <fill in params> )
|
||||||
|
+ # Later, only after learning controller works:
|
||||||
|
+ # push down flow entry and remove the send_openflow command above.
|
||||||
|
+ #self.install_datapath_flow( <fill in params> )
|
||||||
|
+ #else:
|
||||||
|
+ #flood packet out everything but the input port
|
||||||
|
+ #self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
|
||||||
|
+
|
||||||
|
+ def packet_in_callback(self, dpid, inport, reason, len, bufid, packet):
|
||||||
|
+ """Packet-in handler"""
|
||||||
|
+ if not packet.parsed:
|
||||||
|
+ log.debug('Ignoring incomplete packet')
|
||||||
|
+ else:
|
||||||
|
+ self.learn_and_forward(dpid, inport, packet, packet.arr, bufid)
|
||||||
|
+
|
||||||
|
+ return CONTINUE
|
||||||
|
+
|
||||||
|
+ def install(self):
|
||||||
|
+ self.register_for_packet_in(self.packet_in_callback)
|
||||||
|
+
|
||||||
|
+ def getInterface(self):
|
||||||
|
+ return str(pytutorial)
|
||||||
|
+
|
||||||
|
+def getFactory():
|
||||||
|
+ class Factory:
|
||||||
|
+ def instance(self, ctxt):
|
||||||
|
+ return pytutorial(ctxt)
|
||||||
|
+
|
||||||
|
+ return Factory()
|
||||||
|
diff --git a/src/nox/coreapps/examples/tutorial/tutorial.cc b/src/nox/coreapps/examples/tutorial/tutorial.cc
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e7240cc
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/nox/coreapps/examples/tutorial/tutorial.cc
|
||||||
|
@@ -0,0 +1,134 @@
|
||||||
|
+#include "component.hh"
|
||||||
|
+#include "config.h"
|
||||||
|
+#include "packet-in.hh"
|
||||||
|
+#include "flow.hh"
|
||||||
|
+#include "assert.hh"
|
||||||
|
+#include "netinet++/ethernetaddr.hh"
|
||||||
|
+#include "netinet++/ethernet.hh"
|
||||||
|
+#include <boost/shared_array.hpp>
|
||||||
|
+#include <boost/bind.hpp>
|
||||||
|
+#ifdef LOG4CXX_ENABLED
|
||||||
|
+#include <boost/format.hpp>
|
||||||
|
+#include "log4cxx/logger.h"
|
||||||
|
+#else
|
||||||
|
+#include "vlog.hh"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+using namespace std;
|
||||||
|
+using namespace vigil;
|
||||||
|
+using namespace vigil::container;
|
||||||
|
+
|
||||||
|
+namespace
|
||||||
|
+{
|
||||||
|
+ static Vlog_module lg("tutorial");
|
||||||
|
+
|
||||||
|
+ /** Learning switch.
|
||||||
|
+ */
|
||||||
|
+ class tutorial
|
||||||
|
+ : public Component
|
||||||
|
+ {
|
||||||
|
+ public:
|
||||||
|
+ /** Constructor.
|
||||||
|
+ */
|
||||||
|
+ tutorial(const Context* c, const json_object* node)
|
||||||
|
+ : Component(c)
|
||||||
|
+ { }
|
||||||
|
+
|
||||||
|
+ /** Configuration.
|
||||||
|
+ * Add handler for packet-in event.
|
||||||
|
+ */
|
||||||
|
+ void configure(const Configuration*)
|
||||||
|
+ {
|
||||||
|
+ register_handler<Packet_in_event>
|
||||||
|
+ (boost::bind(&tutorial::handle, this, _1));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /** Just simply install.
|
||||||
|
+ */
|
||||||
|
+ void install()
|
||||||
|
+ {
|
||||||
|
+ lg.dbg(" Install called ");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /** Function to setup flow.
|
||||||
|
+ */
|
||||||
|
+ void setup_flow(Flow& flow, datapathid datapath_id ,
|
||||||
|
+ uint32_t buffer_id, uint16_t out_port)
|
||||||
|
+ {
|
||||||
|
+ ofp_flow_mod* ofm;
|
||||||
|
+ size_t size = sizeof *ofm + sizeof(ofp_action_output);
|
||||||
|
+ boost::shared_array<char> raw_of(new char[size]);
|
||||||
|
+ ofm = (ofp_flow_mod*) raw_of.get();
|
||||||
|
+
|
||||||
|
+ ofm->header.version = OFP_VERSION;
|
||||||
|
+ ofm->header.type = OFPT_FLOW_MOD;
|
||||||
|
+ ofm->header.length = htons(size);
|
||||||
|
+ ofm->match.wildcards = htonl(0);
|
||||||
|
+ ofm->match.in_port = htons(flow.in_port);
|
||||||
|
+ ofm->match.dl_vlan = flow.dl_vlan;
|
||||||
|
+ memcpy(ofm->match.dl_src, flow.dl_src.octet, sizeof ofm->match.dl_src);
|
||||||
|
+ memcpy(ofm->match.dl_dst, flow.dl_dst.octet, sizeof ofm->match.dl_dst);
|
||||||
|
+ ofm->match.dl_type = flow.dl_type;
|
||||||
|
+ ofm->match.nw_src = flow.nw_src;
|
||||||
|
+ ofm->match.nw_dst = flow.nw_dst;
|
||||||
|
+ ofm->match.nw_proto = flow.nw_proto;
|
||||||
|
+ ofm->match.tp_src = flow.tp_src;
|
||||||
|
+ ofm->match.tp_dst = flow.tp_dst;
|
||||||
|
+ ofm->command = htons(OFPFC_ADD);
|
||||||
|
+ ofm->buffer_id = htonl(buffer_id);
|
||||||
|
+ ofm->idle_timeout = htons(5);
|
||||||
|
+ ofm->hard_timeout = htons(OFP_FLOW_PERMANENT);
|
||||||
|
+ ofm->priority = htons(OFP_DEFAULT_PRIORITY);
|
||||||
|
+ ofp_action_output& action = *((ofp_action_output*)ofm->actions);
|
||||||
|
+ memset(&action, 0, sizeof(ofp_action_output));
|
||||||
|
+ action.type = htons(OFPAT_OUTPUT);
|
||||||
|
+ action.len = htons(sizeof(ofp_action_output));
|
||||||
|
+ action.max_len = htons(0);
|
||||||
|
+ action.port = htons(out_port);
|
||||||
|
+ send_openflow_command(datapath_id, &ofm->header, true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /** Function to handle packets.
|
||||||
|
+ * @param datapath_id datapath id of switch
|
||||||
|
+ * @param in_port port packet is received
|
||||||
|
+ * @param buffer_id buffer id of packet
|
||||||
|
+ * @param source source mac address in host order
|
||||||
|
+ * @param destination destination mac address in host order
|
||||||
|
+ */
|
||||||
|
+ void handle_packet(datapathid datapath_id, uint16_t in_port, uint32_t buffer_id,
|
||||||
|
+ uint64_t source, uint64_t destination)
|
||||||
|
+ {
|
||||||
|
+ send_openflow_packet(datapath_id, buffer_id, OFPP_FLOOD,
|
||||||
|
+ in_port, true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /** Packet-on handler.
|
||||||
|
+ */
|
||||||
|
+ Disposition handle(const Event& e)
|
||||||
|
+ {
|
||||||
|
+ const Packet_in_event& pi = assert_cast<const Packet_in_event&>(e);
|
||||||
|
+ uint32_t buffer_id = pi.buffer_id;
|
||||||
|
+ Flow flow(pi.in_port, *pi.get_buffer());
|
||||||
|
+
|
||||||
|
+ // drop LLDP packets
|
||||||
|
+ if (flow.dl_type == ethernet::LLDP)
|
||||||
|
+ return CONTINUE;
|
||||||
|
+
|
||||||
|
+ // pass handle of unicast packet, else flood
|
||||||
|
+ if (!flow.dl_src.is_multicast())
|
||||||
|
+ handle_packet(pi.datapath_id, pi.in_port, buffer_id,
|
||||||
|
+ flow.dl_src.hb_long(), flow.dl_dst.hb_long());
|
||||||
|
+ else
|
||||||
|
+ send_openflow_packet(pi.datapath_id, buffer_id, OFPP_FLOOD,
|
||||||
|
+ pi.in_port, true);
|
||||||
|
+
|
||||||
|
+ return CONTINUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private:
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+REGISTER_COMPONENT(container::Simple_component_factory<tutorial>,
|
||||||
|
+ tutorial);
|
||||||
|
+
|
||||||
|
+} // unnamed namespace
|
||||||
|
--
|
||||||
|
1.7.5.4
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
This patch adds the OpenFlow tutorial module source code to nox-destiny.
|
||||||
Reference in New Issue
Block a user