From be1ed1036333f8a104cd073a40a05c7add346481 Mon Sep 17 00:00:00 2001 From: Brian O'Connor Date: Wed, 27 Aug 2014 03:58:36 -0700 Subject: [PATCH 1/3] adding vlanhost.py --- examples/vlanhost.py | 83 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 examples/vlanhost.py diff --git a/examples/vlanhost.py b/examples/vlanhost.py new file mode 100644 index 0000000..bf3e69c --- /dev/null +++ b/examples/vlanhost.py @@ -0,0 +1,83 @@ +""" +vlanhost.py: Host subclass that uses a VLAN tag for the default interface. + +Dependencies: + This class depends on the "vlan" package + $ sudo apt-get install vlan + +Usage (example uses VLAN ID=1000): + From the command line: + sudo mn --custom vlanhost.py --host vlan,vlan=1000 + + From a script (see exampleUsage function below): + from functools import partial + from vlanhost import VLANHost + + .... + + host = partial( VLANHost, vlan=1000 ) + net = Mininet( host=host, ... ) + + Directly running this script: + sudo python vlanhost.py 1000 + +""" + +from mininet.node import Host + +class VLANHost( Host ): + + def config( self, vlan=100, **params ): + """Configure VLANHost according to (optional) parameters: + vlan: VLAN ID for default interface""" + + r = super( Host, self ).config( **params ) + + intf = self.defaultIntf() + # remove IP from default, "physical" interface + self.cmd( 'ifconfig %s inet 0' % intf ) + # create VLAN interface + self.cmd( 'vconfig add %s %d' % ( intf, vlan ) ) + # assign the host's IP to the VLAN interface + self.cmd( 'ifconfig %s.%d inet %s' % ( intf, vlan, params['ip'] ) ) + # update the intf name and host's intf map + newName = '%s.%d' % ( intf, vlan ) + # update the (Mininet) interface to refer to VLAN interface name + intf.name = newName + # add VLAN interface to host's name to intf map + self.nameToIntf[ newName ] = intf + + return r + +hosts = { 'vlan': VLANHost } + + +def exampleUsage( vlan ): + """Simple example of how VLANHost can be used in a script""" + # This is where the magic happens... + host = partial( VLANHost, vlan=vlan ) + # vlan (type: int): VLAN ID to be used by all hosts + + # Start a basic network using our VLANHost + topo = SingleSwitchTopo( k=2 ) + net = Mininet( host=host, topo=topo ) + net.start() + CLI( net ) + net.stop() + +if __name__ == '__main__': + import sys + from functools import partial + + from mininet.net import Mininet + from mininet.cli import CLI + from mininet.topo import SingleSwitchTopo + + try: + vlan = int( sys.argv[ 1 ] ) + except Exception: + print 'Usage: vlanhost.py \n' + print 'Using VLAN ID=100...' + vlan = 100 + + exampleUsage( vlan ) From fe8358add26f17e54e0875416f6676ed6680bf32 Mon Sep 17 00:00:00 2001 From: Brian O'Connor Date: Wed, 27 Aug 2014 23:07:37 -0700 Subject: [PATCH 2/3] chmod +x vlanhost.py --- examples/vlanhost.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 examples/vlanhost.py diff --git a/examples/vlanhost.py b/examples/vlanhost.py old mode 100644 new mode 100755 From d334c1ccfe016ae521b6c9422127f00f96e9897a Mon Sep 17 00:00:00 2001 From: Brian O'Connor Date: Thu, 28 Aug 2014 02:48:46 -0700 Subject: [PATCH 3/3] adding test for vlanhost.py and adding vlantopo example --- examples/README.md | 11 ++++++-- examples/test/test_vlanhost.py | 50 ++++++++++++++++++++++++++++++++++ examples/vlanhost.py | 40 +++++++++++++++++++++++---- 3 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 examples/test/test_vlanhost.py diff --git a/examples/README.md b/examples/README.md index 96e30d7..0369e5b 100644 --- a/examples/README.md +++ b/examples/README.md @@ -79,6 +79,11 @@ This example shows how to connect a Mininet network to the Internet using NAT. It also answers the eternal question "why can't I ping `google.com`?" +#### numberedports.py + +This example verifies the mininet ofport numbers match up to the ovs port numbers. +It also verifies that the port numbers match up to the interface numbers + #### popen.py: This example monitors a number of hosts using `host.popen()` and @@ -118,7 +123,7 @@ memory and `sysctl` configuration (see `INSTALL`.) This example creates a 64-host tree network, and attempts to check full connectivity using `ping`, for different switch/datapath types. -#### numberedports.py +#### vlanhost.py: + +An example of how to subclass Host to use a VLAN on its primary interface. -This example verifies the mininet ofport numbers match up to the ovs port numbers. -It also verifies that the port numbers match up to the interface numbers diff --git a/examples/test/test_vlanhost.py b/examples/test/test_vlanhost.py new file mode 100644 index 0000000..b57f0d0 --- /dev/null +++ b/examples/test/test_vlanhost.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +""" +Test for vlanhost.py +""" + +import unittest +import pexpect +import sys +from mininet.util import quietRun + +class testVLANHost( unittest.TestCase ): + + prompt = 'mininet>' + + @unittest.skipIf( '-quick' in sys.argv, 'long test' ) + def testVLANTopo( self ): + "Test connectivity (or lack thereof) between hosts in VLANTopo" + p = pexpect.spawn( 'python -m mininet.examples.vlanhost' ) + p.expect( self.prompt ) + p.sendline( 'pingall 1' ) #ping timeout=1 + p.expect( '(\d+)% dropped', timeout=30 ) # there should be 24 failed pings + percent = int( p.match.group( 1 ) ) if p.match else -1 + p.expect( self.prompt ) + p.sendline( 'exit' ) + p.wait() + self.assertEqual( percent, 80 ) + + def testSpecificVLAN( self ): + "Test connectivity between hosts on a specific VLAN" + vlan = 1001 + p = pexpect.spawn( 'python -m mininet.examples.vlanhost %d' % vlan ) + p.expect( self.prompt ) + + p.sendline( 'h1 ping -c 1 h2' ) + p.expect ( '(\d+)% packet loss' ) + percent = int( p.match.group( 1 ) ) if p.match else -1 + p.expect( self.prompt ) + + p.sendline( 'h1 ifconfig' ) + i = p.expect( ['h1-eth0.%d' % vlan, pexpect.TIMEOUT ], timeout=2 ) + p.expect( self.prompt ) + + p.sendline( 'exit' ) + p.wait() + self.assertEqual( percent, 0 ) # no packet loss on ping + self.assertEqual( i, 0 ) # check vlan intf is present + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/examples/vlanhost.py b/examples/vlanhost.py index bf3e69c..a917402 100755 --- a/examples/vlanhost.py +++ b/examples/vlanhost.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python """ vlanhost.py: Host subclass that uses a VLAN tag for the default interface. @@ -24,6 +25,7 @@ Usage (example uses VLAN ID=1000): """ from mininet.node import Host +from mininet.topo import Topo class VLANHost( Host ): @@ -52,7 +54,7 @@ class VLANHost( Host ): hosts = { 'vlan': VLANHost } -def exampleUsage( vlan ): +def exampleAllHosts( vlan ): """Simple example of how VLANHost can be used in a script""" # This is where the magic happens... host = partial( VLANHost, vlan=vlan ) @@ -65,6 +67,30 @@ def exampleUsage( vlan ): CLI( net ) net.stop() +class VLANStarTopo( Topo ): + """Example topology that uses host in multiple VLANs""" + + def build( self, k=2, n=2, vlanBase=100 ): + s1 = self.addSwitch( 's1' ) + for i in range( k ): + vlan = vlanBase + i + for j in range(n): + name = 'h%d-%d' % ( j+1, vlan ) + h = self.addHost( name, cls=VLANHost, vlan=vlan ) + self.addLink( h, s1 ) + for j in range( n ): + h = self.addHost( 'h%d' % (j+1) ) + self.addLink( h, s1 ) + + +def exampleCustomTags( vlan ): + """Simple example that exercises VLANStarTopo""" + + net = Mininet( topo=VLANStarTopo() ) + net.start() + CLI( net ) + net.stop() + if __name__ == '__main__': import sys from functools import partial @@ -72,12 +98,16 @@ if __name__ == '__main__': from mininet.net import Mininet from mininet.cli import CLI from mininet.topo import SingleSwitchTopo + from mininet.log import setLogLevel + + setLogLevel( 'info' ) try: vlan = int( sys.argv[ 1 ] ) except Exception: - print 'Usage: vlanhost.py \n' - print 'Using VLAN ID=100...' - vlan = 100 + vlan = None - exampleUsage( vlan ) + if vlan: + exampleAllHosts( vlan ) + else: + exampleCustomTags( vlan )