diff --git a/examples/README.md b/examples/README.md index 45eabb434315053f91694324d8a06c6034b7b04b..74e25b8f3c3e0591ab33af18f322d8adba3ab780 100644 --- a/examples/README.md +++ b/examples/README.md @@ -84,6 +84,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 @@ -123,7 +128,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 0000000000000000000000000000000000000000..b57f0d04ebf725295f8f68b416e78ef20ef7cefe --- /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 new file mode 100755 index 0000000000000000000000000000000000000000..a9174029d524b8efdb011cc48ba4abc7d8349aad --- /dev/null +++ b/examples/vlanhost.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python +""" +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 +from mininet.topo import Topo + +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 exampleAllHosts( 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() + +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 + + 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: + vlan = None + + if vlan: + exampleAllHosts( vlan ) + else: + exampleCustomTags( vlan )