Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | |
Jeremy Ronquillo | b27ce4c | 2017-07-17 12:41:28 -0700 | [diff] [blame] | 3 | """ |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 4 | Copyright 2016 Open Networking Foundation ( ONF ) |
Jeremy Ronquillo | b27ce4c | 2017-07-17 12:41:28 -0700 | [diff] [blame] | 5 | |
| 6 | Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>, |
| 7 | the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>, |
| 8 | or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg> |
| 9 | |
| 10 | TestON is free software: you can redistribute it and/or modify |
| 11 | it under the terms of the GNU General Public License as published by |
| 12 | the Free Software Foundation, either version 2 of the License, or |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 13 | ( at your option ) any later version. |
Jeremy Ronquillo | b27ce4c | 2017-07-17 12:41:28 -0700 | [diff] [blame] | 14 | |
| 15 | TestON is distributed in the hope that it will be useful, |
| 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | GNU General Public License for more details. |
| 19 | |
| 20 | You should have received a copy of the GNU General Public License |
| 21 | along with TestON. If not, see <http://www.gnu.org/licenses/>. |
| 22 | """ |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 23 | import os |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 24 | import re |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 25 | import math |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 26 | from optparse import OptionParser |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 27 | from ipaddress import IPv6Network, IPv4Network |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 28 | from mininet.net import Mininet |
| 29 | from mininet.topo import Topo |
Jon Hall | f69e316 | 2020-09-01 09:08:44 -0700 | [diff] [blame] | 30 | from mininet.node import RemoteController, Host, OVSBridge, OVSSwitch |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 31 | from mininet.link import TCLink |
| 32 | from mininet.log import setLogLevel |
| 33 | from mininet.cli import CLI |
| 34 | |
Jon Hall | f69e316 | 2020-09-01 09:08:44 -0700 | [diff] [blame] | 35 | from bmv2 import ONOSBmv2Switch |
| 36 | from stratum import StratumBmv2Switch |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 37 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 38 | # Parse command line options and dump results |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 39 | def parseOptions(): |
| 40 | "Parse command line options" |
| 41 | parser = OptionParser() |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 42 | parser.add_option( '--spine', dest='spine', type='int', default=2, |
| 43 | help='number of spine switches, default=2' ) |
| 44 | parser.add_option( '--leaf', dest='leaf', type='int', default=2, |
| 45 | help='number of leaf switches, default=2' ) |
| 46 | parser.add_option( '--fanout', dest='fanout', type='int', default=2, |
| 47 | help='number of hosts per leaf switch, default=2' ) |
Jonghwan Hyun | 76a02b7 | 2018-01-30 16:40:48 +0900 | [diff] [blame] | 48 | parser.add_option( '--onos-ip', dest='onosIp', type='str', default='', |
| 49 | help='IP address list of ONOS instances, separated by comma(,). Overrides --onos option' ) |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 50 | parser.add_option( '--vlan', dest='vlan', type='int', default=-1, |
| 51 | help='vid of cross connect, default=-1, -1 means utilize default value' ) |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 52 | parser.add_option( '--ipv6', action="store_true", dest='ipv6', |
| 53 | help='hosts are capable to use also ipv6' ) |
Jon Hall | f69e316 | 2020-09-01 09:08:44 -0700 | [diff] [blame] | 54 | parser.add_option( '--switch', dest='switch', type='str', default='ovs', |
| 55 | help='Switch type: ovs, bmv2 (with fabric.p4), stratum' ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 56 | ( options, args ) = parser.parse_args() |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 57 | return options, args |
| 58 | |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 59 | |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 60 | opts, args = parseOptions() |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 61 | |
Jon Hall | f69e316 | 2020-09-01 09:08:44 -0700 | [diff] [blame] | 62 | FABRIC_PIPECONF = "org.onosproject.pipelines.fabric" |
| 63 | |
| 64 | SWITCH_TO_PARAMS_DICT = { |
| 65 | "ovs": dict(cls=OVSSwitch), |
| 66 | "bmv2": dict(cls=ONOSBmv2Switch, pipeconf=FABRIC_PIPECONF), |
| 67 | "stratum": dict(cls=StratumBmv2Switch, pipeconf=FABRIC_PIPECONF, loglevel='debug') |
| 68 | } |
| 69 | if opts.switch not in SWITCH_TO_PARAMS_DICT: |
| 70 | raise Exception("Unknown switch type '%s'" % opts.switch) |
| 71 | SWITCH_PARAMS = SWITCH_TO_PARAMS_DICT[opts.switch] |
| 72 | |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 73 | IP6_SUBNET_CLASS = 120 |
| 74 | IP4_SUBNET_CLASS = 24 |
| 75 | |
| 76 | class LeafAndSpine6( Topo ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 77 | |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 78 | """ |
| 79 | Create Leaf and Spine Topology for IPv4/IPv6 tests. |
| 80 | """ |
| 81 | def __init__( self, spine=2, leaf=2, fanout=2, **opts ): |
| 82 | Topo.__init__( self, **opts ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 83 | spines = {} |
| 84 | leafs = {} |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 85 | """ |
| 86 | We calculate the offset from /120 and from /24 in order to have |
| 87 | a number of /120 and /24 subnets == leaf |
| 88 | """ |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 89 | offset = int( math.ceil( math.sqrt( leaf ) ) ) |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 90 | """ |
| 91 | We calculate the subnets to use and set options |
| 92 | """ |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 93 | ipv6SubnetClass = unicode( '2000::/%s' % ( IP6_SUBNET_CLASS - offset ) ) |
| 94 | ipv6Subnets = list( IPv6Network( ipv6SubnetClass ).subnets( new_prefix=IP6_SUBNET_CLASS ) ) |
| 95 | ipv4SubnetClass = unicode( '10.0.0.0/%s' % ( IP4_SUBNET_CLASS - offset ) ) |
| 96 | ipv4Subnets = list( IPv4Network( ipv4SubnetClass ).subnets( new_prefix=IP4_SUBNET_CLASS ) ) |
| 97 | linkopts = dict( bw=100 ) |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 98 | """ |
| 99 | We create the spine switches |
| 100 | """ |
| 101 | for s in range( spine ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 102 | spines[ s ] = self.addSwitch( 'spine10%s' % ( s + 1 ), |
| 103 | dpid="00000000010%s" % ( s + 1 ) ) |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 104 | """ |
| 105 | We create the leaf switches |
| 106 | """ |
| 107 | for ls in range( leaf ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 108 | leafs[ ls ] = self.addSwitch( 'leaf%s' % ( ls + 1 ), |
| 109 | dpid="00000000000%s" % ( 1 + ls ) ) |
| 110 | ipv6Subnet = ipv6Subnets[ ls ] |
| 111 | ipv6Hosts = list( ipv6Subnet.hosts() ) |
| 112 | ipv4Subnet = ipv4Subnets[ ls ] |
| 113 | ipv4Hosts = list( ipv4Subnet.hosts() ) |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 114 | """ |
| 115 | We add the hosts |
| 116 | """ |
| 117 | for f in range( fanout ): |
| 118 | ipv6 = ipv6Hosts[ f ] |
| 119 | ipv6Gateway = ipv6Hosts[ len( ipv6Hosts ) - 1 ] |
| 120 | ipv4 = ipv4Hosts[ f ] |
| 121 | ipv4Gateway = ipv4Hosts[ len( ipv4Hosts ) - 1 ] |
| 122 | host = self.addHost( |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 123 | name='h%s' % ( ls * fanout + f + 1 ), |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 124 | cls=Ipv6Host, |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 125 | ip="%s/%s" % ( ipv4, IP4_SUBNET_CLASS ), |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 126 | gateway='%s' % ipv4Gateway, |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 127 | ipv6="%s/%s" % ( ipv6, IP6_SUBNET_CLASS ), |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 128 | ipv6Gateway="%s" % ipv6Gateway |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 129 | ) |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 130 | self.addLink( host, leafs[ ls ], **linkopts ) |
| 131 | """ |
| 132 | Connect leaf to all spines |
| 133 | """ |
| 134 | for s in range( spine ): |
| 135 | switch = spines[ s ] |
| 136 | self.addLink( leafs[ ls ], switch, **linkopts ) |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 137 | |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 138 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 139 | class LeafAndSpine( Topo ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 140 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 141 | def __init__( self, spine=2, leaf=2, fanout=2, **opts ): |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 142 | "Create Leaf and Spine Topo." |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 143 | Topo.__init__( self, **opts ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 144 | # Add spine switches |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 145 | spines = {} |
| 146 | leafs = {} |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 147 | for s in range( spine ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 148 | spines[ s ] = self.addSwitch( 'spine10%s' % ( s + 1 ), |
Jon Hall | f69e316 | 2020-09-01 09:08:44 -0700 | [diff] [blame] | 149 | dpid="00000000010%s" % ( s + 1 ), |
| 150 | **SWITCH_PARAMS ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 151 | # Set link speeds to 100Mb/s |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 152 | linkopts = dict( bw=100 ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 153 | # Add Leaf switches |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 154 | for ls in range( leaf ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 155 | leafs[ ls ] = self.addSwitch( 'leaf%s' % ( ls + 1 ), |
Jon Hall | f69e316 | 2020-09-01 09:08:44 -0700 | [diff] [blame] | 156 | dpid="00000000000%s" % ( 1 + ls ), |
| 157 | **SWITCH_PARAMS ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 158 | # Add hosts under a leaf, fanout hosts per leaf switch |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 159 | for f in range( fanout ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 160 | host = self.addHost( 'h%s' % ( ls * fanout + f + 1 ), |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 161 | cls=IpHost, |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 162 | ip='10.0.%s.%s/24' % ( ( ls + 1 ), ( f + 1 ) ), |
| 163 | gateway='10.0.%s.254' % ( ls + 1 ) ) |
Flavio Castro | e168f7f | 2016-06-24 15:53:12 -0700 | [diff] [blame] | 164 | self.addLink( host, leafs[ ls ], **linkopts ) |
| 165 | # Add Xconnect simulation |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 166 | if ls is 0: |
| 167 | in1 = self.addHost( 'in1', cls=IpHost, ip='10.0.1.9/24', mac="00:00:00:00:00:09" ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 168 | self.addLink( in1, leafs[ 0 ], **linkopts ) |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 169 | out1 = self.addHost( 'out1', cls=IpHost, ip='10.0.9.1/24', mac="00:00:00:00:09:01" ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 170 | self.addLink( out1, leafs[ 0 ], **linkopts ) |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 171 | br1 = self.addSwitch( 'br1', cls=OVSBridge ) |
| 172 | self.addLink( br1, leafs[ 0 ], **linkopts ) |
| 173 | vlans = [ 1, 5, 10 ] |
| 174 | for vid in vlans: |
| 175 | olt = self.addHost( 'olt%s' % vid, cls=VLANHost, vlan=vid, |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 176 | ip="10.%s.0.1/24" % vid, mac="00:00:%02d:00:00:01" % vid ) |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 177 | vsg = self.addHost( 'vsg%s' % vid, cls=VLANHost, vlan=vid, |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 178 | ip="10.%s.0.2/24" % vid, mac="00:00:%02d:00:00:02" % vid ) |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 179 | self.addLink( olt, leafs[ 0 ], **linkopts ) |
| 180 | self.addLink( vsg, br1, **linkopts ) |
| 181 | # Connect leaf to all spines |
| 182 | for s in range( spine ): |
| 183 | switch = spines[ s ] |
| 184 | self.addLink( leafs[ ls ], switch, **linkopts ) |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 185 | |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 186 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 187 | class IpHost( Host ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 188 | |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 189 | def __init__( self, name, *args, **kwargs ): |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 190 | super( IpHost, self ).__init__( name, *args, **kwargs ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 191 | gateway = re.split( '\.|/', kwargs[ 'ip' ] ) |
| 192 | gateway[ 3 ] = '254' |
| 193 | self.gateway = '.'.join( gateway[ 0:4 ] ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 194 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 195 | def config( self, **kwargs ): |
| 196 | Host.config( self, **kwargs ) |
| 197 | mtu = "ifconfig " + self.name + "-eth0 mtu 1490" |
| 198 | self.cmd( mtu ) |
| 199 | self.cmd( 'ip route add default via %s' % self.gateway ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 200 | |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 201 | |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 202 | class Ipv6Host( IpHost ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 203 | |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 204 | """ |
| 205 | Abstraction to model an augmented host with a ipv6 |
| 206 | functionalities as well |
| 207 | """ |
| 208 | def __init__( self, name, *args, **kwargs ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 209 | IpHost.__init__( self, name, *args, **kwargs ) |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 210 | |
| 211 | def config( self, **kwargs ): |
| 212 | IpHost.config( self, **kwargs ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 213 | ipv6Cmd = 'ifconfig %s-eth0 inet6 add %s' % ( self.name, kwargs[ 'ipv6' ] ) |
| 214 | ipv6GatewayCmd = 'ip -6 route add default via %s' % kwargs[ 'ipv6Gateway' ] |
| 215 | ipv6MtuCmd = 'ifconfig %s-eth0 inet6 mtu 1490' % ( self.name ) |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 216 | self.cmd( ipv6Cmd ) |
| 217 | self.cmd( ipv6GatewayCmd ) |
| 218 | self.cmd( ipv6MtuCmd ) |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 219 | |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 220 | |
Flavio Castro | e168f7f | 2016-06-24 15:53:12 -0700 | [diff] [blame] | 221 | class VLANHost( Host ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 222 | |
Flavio Castro | e168f7f | 2016-06-24 15:53:12 -0700 | [diff] [blame] | 223 | "Host connected to VLAN interface" |
| 224 | |
| 225 | def config( self, vlan=100, **params ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 226 | """Configure VLANHost according to ( optional ) parameters: |
Flavio Castro | e168f7f | 2016-06-24 15:53:12 -0700 | [diff] [blame] | 227 | vlan: VLAN ID for default interface""" |
| 228 | r = super( VLANHost, self ).config( **params ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 229 | intf = self.defaultIntf() |
Flavio Castro | e168f7f | 2016-06-24 15:53:12 -0700 | [diff] [blame] | 230 | # remove IP from default, "physical" interface |
| 231 | self.cmd( 'ifconfig %s inet 0' % intf ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 232 | intf = self.defaultIntf() |
Flavio Castro | e168f7f | 2016-06-24 15:53:12 -0700 | [diff] [blame] | 233 | # create VLAN interface |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 234 | self.cmd( 'vconfig add %s %d' % ( intf, vlan ) ) |
| 235 | self.cmd( 'ifconfig %s.%d %s' % ( intf, vlan, params[ 'ip' ] ) ) |
Flavio Castro | e168f7f | 2016-06-24 15:53:12 -0700 | [diff] [blame] | 236 | # update the intf name and host's intf map |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 237 | self.cmd( 'ifconfig %s.%d mtu 1480' % ( intf, vlan ) ) |
| 238 | newName = '%s.%d' % ( intf, vlan ) |
| 239 | # update the ( Mininet ) interface to refer to VLAN interface name |
Flavio Castro | e168f7f | 2016-06-24 15:53:12 -0700 | [diff] [blame] | 240 | intf.name = newName |
| 241 | # add VLAN interface to host's name to intf map |
| 242 | self.nameToIntf[ newName ] = intf |
| 243 | |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 244 | |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 245 | class ExtendedCLI( CLI ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 246 | |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 247 | """ |
| 248 | Extends mininet CLI with the following commands: |
| 249 | addvlanhost |
| 250 | addiphost |
| 251 | """ |
| 252 | def do_addhost( self, line ): |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 253 | # Parsing args from CLI |
| 254 | args = line.split() |
| 255 | if len( args ) < 3 or len( args ): |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 256 | "usage: addhost hostname switch **params" |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 257 | hostname, switch = args[ 0 ], args[ 1 ] |
| 258 | params = eval( line.split( ' ', 3 )[ 2 ] ) |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 259 | if 'cls' in params: |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 260 | params[ 'cls' ] = eval( params[ 'cls' ] ) |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 261 | if hostname in self.mn: |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 262 | # error( '%s already exists!\n' % hostname ) |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 263 | return |
| 264 | if switch not in self.mn: |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 265 | # error( '%s does not exist!\n' % switch ) |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 266 | return |
| 267 | print params |
| 268 | host = self.mn.addHostCfg( hostname, **params ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 269 | # switch.attach( link.intf2 ) |
| 270 | # host.config() |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 271 | link = self.mn.addLink( host, switch ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 272 | host.config( **params ) |
Flavio Castro | e168f7f | 2016-06-24 15:53:12 -0700 | [diff] [blame] | 273 | |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 274 | def do_pingall6( self, line ): |
| 275 | "Ping6 between all hosts." |
| 276 | self.mn.pingAll6( line ) |
| 277 | |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 278 | |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 279 | def config( opts ): |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 280 | spine = opts.spine |
| 281 | leaf = opts.leaf |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 282 | fanout = opts.fanout |
Flavio Castro | ab163ca | 2016-07-07 14:05:00 -0700 | [diff] [blame] | 283 | vlan = opts.vlan |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 284 | ipv6 = opts.ipv6 |
Jonghwan Hyun | 76a02b7 | 2018-01-30 16:40:48 +0900 | [diff] [blame] | 285 | if opts.onosIp != '': |
| 286 | controllers = opts.onosIp.split( ',' ) |
| 287 | else: |
| 288 | controllers = ['127.0.0.1'] |
| 289 | |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 290 | if not ipv6: |
| 291 | topo = LeafAndSpine( |
| 292 | spine=spine, |
| 293 | leaf=leaf, |
| 294 | fanout=fanout, |
| 295 | vlan=vlan, |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 296 | ) |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 297 | else: |
| 298 | topo = LeafAndSpine6( |
| 299 | spine=spine, |
| 300 | leaf=leaf, |
| 301 | fanout=fanout, |
| 302 | vlan=vlan, |
| 303 | ipv6=ipv6 |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 304 | ) |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 305 | net = Mininet( topo=topo, link=TCLink, build=False, |
Jonghwan Hyun | 76a02b7 | 2018-01-30 16:40:48 +0900 | [diff] [blame] | 306 | controller=None, autoSetMacs=True ) |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 307 | i = 0 |
| 308 | for ip in controllers: |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 309 | net.addController( "c%s" % ( i ), controller=RemoteController, ip=ip ) |
| 310 | i += 1 |
| 311 | net.build() |
| 312 | net.start() |
Pier | b95002f | 2016-12-05 15:20:42 -0800 | [diff] [blame] | 313 | if not ipv6: |
| 314 | out1 = net.get( 'out1' ) |
Jeremy Ronquillo | 23fb216 | 2017-09-15 14:59:57 -0700 | [diff] [blame] | 315 | out1.cmd( "arp -s 10.0.9.254 10:00:00:00:00:01 -i %s " % ( out1.intf() ) ) |
| 316 | ExtendedCLI( net ) |
| 317 | net.stop() |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 318 | |
Flavio Castro | cc38a54 | 2016-03-03 13:15:46 -0800 | [diff] [blame] | 319 | if __name__ == '__main__': |
Flavio Castro | 5608a39 | 2016-06-22 17:02:35 -0700 | [diff] [blame] | 320 | setLogLevel( 'info' ) |
| 321 | config( opts ) |
| 322 | os.system( 'sudo mn -c' ) |