From f7c2df251389b906c9d5d06c105a62d992f72df6 Mon Sep 17 00:00:00 2001 From: Brandon Heller Date: Sat, 9 Jan 2010 21:11:25 -0800 Subject: [PATCH] Support OpenVSwitch in kernel-mode --- bin/mn_run.py | 5 +++-- mininet/net.py | 4 ++-- mininet/node.py | 59 ++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/bin/mn_run.py b/bin/mn_run.py index 10519ac..ffa49e1 100755 --- a/bin/mn_run.py +++ b/bin/mn_run.py @@ -16,7 +16,7 @@ except ImportError: from mininet.logging_mod import lg, LEVELS from mininet.net import Mininet, init from mininet.node import KernelSwitch, Host, Controller, ControllerParams, NOX -from mininet.node import RemoteController, UserSwitch +from mininet.node import RemoteController, UserSwitch, OVSKernelSwitch from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo # built in topologies, created only when run @@ -39,7 +39,8 @@ if USE_RIPCORD: SWITCH_DEF = 'kernel' SWITCHES = {'kernel': KernelSwitch, - 'user': UserSwitch} + 'user': UserSwitch, + 'ovsk': OVSKernelSwitch} HOST_DEF = 'process' HOSTS = {'process': Host} diff --git a/mininet/net.py b/mininet/net.py index 1a40a8b..ec1e9ea 100755 --- a/mininet/net.py +++ b/mininet/net.py @@ -53,7 +53,7 @@ import sys from time import sleep from mininet.logging_mod import lg -from mininet.node import KernelSwitch +from mininet.node import KernelSwitch, OVSKernelSwitch from mininet.util import quietRun, fixLimits from mininet.util import make_veth_pair, move_intf, retry, MOVEINTF_DELAY from mininet.xterm import cleanUpScreens, makeXterms @@ -135,7 +135,7 @@ class Mininet(object): sw_dpid = None if self.auto_set_macs: sw_dpid = dpid - if self.switch is KernelSwitch: + if self.switch is KernelSwitch or self.switch is OVSKernelSwitch: sw = self.switch('s_' + self.topo.name(dpid), dp = self.dps, dpid = sw_dpid) self.dps += 1 diff --git a/mininet/node.py b/mininet/node.py index 581c05b..8281bef 100644 --- a/mininet/node.py +++ b/mininet/node.py @@ -306,8 +306,6 @@ class UserSwitch(Switch): class KernelSwitch(Switch): '''Kernel-space switch. - Much faster than user-space! - Currently only works in the root namespace. ''' @@ -348,7 +346,7 @@ class KernelSwitch(Switch): self.execed = False def stop(self): - '''Terminate reference kernel datapath.''' + '''Terminate kernel datapath.''' quietRun('dpctl deldp nl:%i' % self.dp) # In theory the interfaces should go away after we shut down. # However, this takes time, so we're better off to remove them @@ -360,6 +358,61 @@ class KernelSwitch(Switch): lg.info('.') +class OVSKernelSwitch(Switch): + '''Open VSwitch kernel-space switch. + + Currently only works in the root namespace. + ''' + + def __init__(self, name, dp = None, dpid = None): + '''Init. + + @param name + @param dp netlink id (0, 1, 2, ...) + @param dpid datapath ID as unsigned int; random value if None + ''' + Switch.__init__(self, name, inNamespace = False) + self.dp = dp + self.dpid = dpid + + def start(self, controllers): + '''Start up kernel datapath.''' + ofplog = '/tmp/' + self.name + '-ofp.log' + quietRun('ifconfig lo up') + # Delete local datapath if it exists; + # then create a new one monitoring the given interfaces + quietRun('ovs-dpctl del-dp dp%i' % self.dp) + self.cmdPrint('ovs-dpctl add-dp dp%i' % self.dp) + if self.dpid: + intf = 'dp' % self.dp + mac_str = macColonHex(self.dpid) + self.cmd(['ifconfig', intf, 'hw', 'ether', mac_str]) + + if len(self.ports) != max(self.ports.keys()) + 1: + raise Exception('only contiguous, zero-indexed port ranges' + 'supported: %s' % self.ports) + intfs = [self.ports[port] for port in self.ports.keys()] + self.cmdPrint('ovs-dpctl add-if dp' + str(self.dp) + ' ' + + ' '.join(intfs)) + # Run protocol daemon + self.cmdPrint('ovs-openflowd dp' + str(self.dp) + ' tcp:' + + controllers['c0'].IP() + ':' + + ' --fail=closed 1> ' + ofplog + ' 2>' + ofplog + ' &') + self.execed = False + + def stop(self): + '''Terminate kernel datapath.''' + quietRun('ovs-dpctl del-dp dp%i' % self.dp) + # In theory the interfaces should go away after we shut down. + # However, this takes time, so we're better off to remove them + # explicitly so that we won't get errors if we run before they + # have been removed by the kernel. Unfortunately this is very slow. + self.cmd('kill %ovs-openflowd') + for intf in self.intfs: + quietRun('ip link del ' + intf) + lg.info('.') + + class Controller(Node): '''A Controller is a Node that is running (or has execed) an OpenFlow controller.'''