[ONOS-2276] Flow Test Suite
- tests flows with MAC address selectors
- tests flows with IPv4 selectors
- tests flows with vlan selector
Change-Id: I2c38a3449068b220742879b6b952b36e5572b3d3
diff --git a/TestON/drivers/common/api/controller/onosrestdriver.py b/TestON/drivers/common/api/controller/onosrestdriver.py
index 3ff43c7..878e97e 100644
--- a/TestON/drivers/common/api/controller/onosrestdriver.py
+++ b/TestON/drivers/common/api/controller/onosrestdriver.py
@@ -1094,39 +1094,14 @@
main.cleanup()
main.exit()
- def addFlow( self,
- deviceId,
- appId=0,
- ingressPort="",
- egressPort="",
- ethType="",
- ethSrc="",
- ethDst="",
- bandwidth="",
- lambdaAlloc=False,
- ipProto="",
- ipSrc="",
- ipDst="",
- tcpSrc="",
- tcpDst="",
- ip="DEFAULT",
- port="DEFAULT" ):
+ def sendFlow( self, deviceId, flowJson, ip="DEFAULT", port="DEFAULT", debug=False ):
"""
Description:
- Creates a single flow in the specified device
+ Sends a single flow to the specified device. This function exists
+ so you can bypass the addFLow driver and send your own custom flow.
Required:
- * deviceId: id of the device
- Optional:
- * ingressPort: port ingress device
- * egressPort: port of egress device
- * ethType: specify ethType
- * ethSrc: specify ethSrc ( i.e. src mac addr )
- * ethDst: specify ethDst ( i.e. dst mac addr )
- * ipProto: specify ip protocol
- * ipSrc: specify ip source address with mask eg. ip#/24
- * ipDst: specify ip destination address eg. ip#/24
- * tcpSrc: specify tcp source port
- * tcpDst: specify tcp destination port
+ * The flow in json
+ * the device id to add the flow to
Returns:
Returns main.TRUE for successful requests; Returns main.FALSE
if error on requests;
@@ -1135,63 +1110,9 @@
The ip and port option are for the requests input's ip and port
of the ONOS node
"""
+
try:
- flowJson = { "priority":100,
- "isPermanent":"true",
- "timeout":0,
- "deviceId":deviceId,
- "treatment":{"instructions":[]},
- "selector": {"criteria":[]}}
- if appId:
- flowJson[ "appId" ] = appId
- if egressPort:
- flowJson[ 'treatment' ][ 'instructions' ].append(
- { "type":"OUTPUT",
- "port":egressPort } )
- if ingressPort:
- flowJson[ 'selector' ][ 'criteria' ].append(
- { "type":"IN_PORT",
- "port":ingressPort } )
- if ethType == "IPV4":
- flowJson[ 'selector' ][ 'criteria' ].append( {
- "type":"ETH_TYPE",
- "ethType":2048 } )
- elif ethType:
- flowJson[ 'selector' ][ 'criteria' ].append( {
- "type":"ETH_TYPE",
- "ethType":ethType } )
- if ethSrc:
- flowJson[ 'selector' ][ 'criteria' ].append(
- { "type":"ETH_SRC",
- "mac":ethSrc } )
- if ethDst:
- flowJson[ 'selector' ][ 'criteria' ].append(
- { "type":"ETH_DST",
- "mac":ethDst } )
- if ipSrc:
- flowJson[ 'selector' ][ 'criteria' ].append(
- { "type":"IPV4_SRC",
- "ip":ipSrc } )
- if ipDst:
- flowJson[ 'selector' ][ 'criteria' ].append(
- { "type":"IPV4_DST",
- "ip":ipDst } )
- if tcpSrc:
- flowJson[ 'selector' ][ 'criteria' ].append(
- { "type":"TCP_SRC",
- "tcpPort": tcpSrc } )
- if tcpDst:
- flowJson[ 'selector' ][ 'criteria' ].append(
- { "type":"TCP_DST",
- "tcpPort": tcpDst } )
- if ipProto:
- flowJson[ 'selector' ][ 'criteria' ].append(
- { "type":"IP_PROTO",
- "protocol": ipProto } )
- if bandwidth or lambdaAlloc:
- # TODO: Bandwidth and Lambda will be implemented if needed
- raise NotImplementedError
- main.log.debug( "Adding flow: " + self.pprint( flowJson ) )
+ if debug: main.log.debug( "Adding flow: " + self.pprint( flowJson ) )
output = None
if ip == "DEFAULT":
main.log.warn( "No ip given, reverting to ip from topo file" )
@@ -1225,6 +1146,113 @@
main.cleanup()
main.exit()
+ def addFlow( self,
+ deviceId,
+ appId=0,
+ ingressPort="",
+ egressPort="",
+ ethType="",
+ ethSrc="",
+ ethDst="",
+ vlan="",
+ ipProto="",
+ ipSrc=(),
+ ipDst=(),
+ tcpSrc="",
+ tcpDst="",
+ ip="DEFAULT",
+ port="DEFAULT",
+ debug=False ):
+ """
+ Description:
+ Creates a single flow in the specified device
+ Required:
+ * deviceId: id of the device
+ Optional:
+ * ingressPort: port ingress device
+ * egressPort: port of egress device
+ * ethType: specify ethType
+ * ethSrc: specify ethSrc ( i.e. src mac addr )
+ * ethDst: specify ethDst ( i.e. dst mac addr )
+ * ipProto: specify ip protocol
+ * ipSrc: specify ip source address with mask eg. ip#/24
+ as a tuple (type, ip#)
+ * ipDst: specify ip destination address eg. ip#/24
+ as a tuple (type, ip#)
+ * tcpSrc: specify tcp source port
+ * tcpDst: specify tcp destination port
+ Returns:
+ Returns main.TRUE for successful requests; Returns main.FALSE
+ if error on requests;
+ Returns None for exceptions
+ NOTE:
+ The ip and port option are for the requests input's ip and port
+ of the ONOS node
+ """
+ try:
+ flowJson = { "priority":100,
+ "isPermanent":"true",
+ "timeout":0,
+ "deviceId":deviceId,
+ "treatment":{"instructions":[]},
+ "selector": {"criteria":[]}}
+ if appId:
+ flowJson[ "appId" ] = appId
+ if egressPort:
+ flowJson[ 'treatment' ][ 'instructions' ].append( {
+ "type":"OUTPUT",
+ "port":egressPort } )
+ if ingressPort:
+ flowJson[ 'selector' ][ 'criteria' ].append( {
+ "type":"IN_PORT",
+ "port":ingressPort } )
+ if ethType:
+ flowJson[ 'selector' ][ 'criteria' ].append( {
+ "type":"ETH_TYPE",
+ "ethType":ethType } )
+ if ethSrc:
+ flowJson[ 'selector' ][ 'criteria' ].append( {
+ "type":"ETH_SRC",
+ "mac":ethSrc } )
+ if ethDst:
+ flowJson[ 'selector' ][ 'criteria' ].append( {
+ "type":"ETH_DST",
+ "mac":ethDst } )
+ if vlan:
+ flowJson[ 'selector' ][ 'criteria' ].append( {
+ "type":"VLAN_VID",
+ "vlanId":vlan } )
+ if ipSrc:
+ flowJson[ 'selector' ][ 'criteria' ].append( {
+ "type":ipSrc[0],
+ "ip":ipSrc[1] } )
+ if ipDst:
+ flowJson[ 'selector' ][ 'criteria' ].append( {
+ "type":ipDst[0],
+ "ip":ipDst[1] } )
+ if tcpSrc:
+ flowJson[ 'selector' ][ 'criteria' ].append( {
+ "type":"TCP_SRC",
+ "tcpPort": tcpSrc } )
+ if tcpDst:
+ flowJson[ 'selector' ][ 'criteria' ].append( {
+ "type":"TCP_DST",
+ "tcpPort": tcpDst } )
+ if ipProto:
+ flowJson[ 'selector' ][ 'criteria' ].append( {
+ "type":"IP_PROTO",
+ "protocol": ipProto } )
+
+ return self.sendFlow( deviceId=deviceId, flowJson=flowJson, debug=debug )
+
+ except ( AttributeError, TypeError ):
+ main.log.exception( self.name + ": Object not as expected" )
+ return None
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
def removeFlow( self, deviceId, flowId,
ip="DEFAULT", port="DEFAULT" ):
"""
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index f20589e..ff14fbe 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -3124,7 +3124,7 @@
main.cleanup()
main.exit()
- def sendPacket( self, packet=None, timeout=1 ):
+ def sendPacket( self, iface=None, packet=None, timeout=1 ):
"""
Send a packet with either the given scapy packet command, or use the
packet saved in the variable 'packet'.
@@ -3147,6 +3147,9 @@
sendCmd += packet
else:
sendCmd += "packet"
+ if iface:
+ sendCmd += ", iface='{}'".format( iface )
+
sendCmd += ', timeout=' + str( timeout ) + ')'
self.handle.sendline( sendCmd )
self.handle.expect( self.scapyPrompt )
diff --git a/TestON/tests/FUNCflow/Dependency/topo-flow.py b/TestON/tests/FUNCflow/Dependency/topo-flow.py
index 2299d9e..f9d58c1 100755
--- a/TestON/tests/FUNCflow/Dependency/topo-flow.py
+++ b/TestON/tests/FUNCflow/Dependency/topo-flow.py
@@ -14,24 +14,47 @@
from mininet.util import dumpNodeConnections
from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+class VLANHost( Host ):
+ def config( self, vlan=100, **params ):
+ r = super( Host, self ).config( **params )
+ intf = self.defaultIntf()
+ self.cmd( 'ifconfig %s inet 0' % intf )
+ self.cmd( 'vconfig add %s %d' % ( intf, vlan ) )
+ self.cmd( 'ifconfig %s.%d inet %s' % ( intf, vlan, params['ip'] ) )
+ newName = '%s.%d' % ( intf, vlan )
+ intf.name = newName
+ self.nameToIntf[ newName ] = intf
+ return r
+
+class IPv6Host( Host ):
+ def config( self, v6Addr='1000:1/64', **params ):
+ r = super( Host, self ).config( **params )
+ intf = self.defaultIntf()
+ self.cmd( 'ifconfig %s inet 0' % intf )
+ self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) )
+ return r
+
class MyTopo( Topo ):
- def __init__( self ):
+ def __init__( self, **opts ):
# Initialize topology
- Topo.__init__( self )
- # Switch S5 Hosts
- host1=self.addHost( 'h1', ip='10.1.0.1/24' )
- host2=self.addHost( 'h2', ip='10.1.0.2/24' )
- #host3=self.addHost( 'h3', ip='10.1.0.3/24', v6Addr='1000::3/64' )
- #host4=self.addHost( 'h4', ip='10.1.0.4/24', v6Addr='1000::4/64' )
+ Topo.__init__( self, **opts)
+
+ # IPv4 hosts
+ host1=self.addHost( 'h1', ip='10.0.0.1/24' )
+ host2=self.addHost( 'h2', ip='10.0.0.2/24' )
+
+ # VLAN hosts
+ host3=self.addHost( 'h3', ip='10.0.0.3/24', cls=VLANHost, vlan=10 )
+ host4=self.addHost( 'h4', ip='10.0.0.4/24', cls=VLANHost, vlan=10 )
+
s1 = self.addSwitch( 's1' )
- #s2 = self.addSwitch( 's2' )
self.addLink(s1, host1)
self.addLink(s1, host2)
- #self.addLink(s1, host3)
- #self.addLink(s1, host4)
+ self.addLink(s1, host3)
+ self.addLink(s1, host4)
topos = { 'mytopo': ( lambda: MyTopo() ) }
@@ -39,7 +62,7 @@
def setupNetwork():
"Create network"
topo = MyTopo()
- network = Mininet(topo=topo, autoSetMacs=True, controller=None)
+ network = Mininet(topo=topo, autoSetMacs=True, autoStaticArp=True, controller=None)
network.start()
CLI( network )
network.stop()
diff --git a/TestON/tests/FUNCflow/FUNCflow.params b/TestON/tests/FUNCflow/FUNCflow.params
index 0aa8e89..7353e69 100755
--- a/TestON/tests/FUNCflow/FUNCflow.params
+++ b/TestON/tests/FUNCflow/FUNCflow.params
@@ -1,16 +1,19 @@
<PARAMS>
# CASE - Descritpion
+ # 1,2,10,1000,1100,2000,1200,2000,100
# 1 - Variable initialization and optional pull and build ONOS package
# 2 - install ONOS
# 8 - Compare topology
# 9 - Report logs
- # 10 - Start mininet and assign switches to controller
+ # 10 - Start mininet and verify topology
# 66 - Testing Scapy
- # 1000 - Add flows
- # 2000 - Verify flows are in the ADDED state
- # 3000 - Delete flows
- <testcases>1,2,10,11,1000,2000,[66]*3,3000</testcases>
+ # 1000 - Add flows with MAC selectors
+ # 1100 - Add flows with IPv4 selectors
+ # 1200 - Add flows with vlan selector
+ # 2000 - Delete flows
+
+ <testcases>1,2,10,1000,2,1100,2,1200,100</testcases>
<SCALE>
<max>1</max>
@@ -23,19 +26,6 @@
<topology>topo-flow.py</topology>
</DEPENDENCY>
-
- <TOPO>
- <numSwitches>1</numSwitches>
- <numHosts>2</numHosts>
- <numLinks>0</numLinks>
- </TOPO>
-
- <MININET>
- <deviceId>of:0000000000000001</deviceId>
- <hostMac1>00:00:00:00:00:01</hostMac1>
- <hostMac2>00:00:00:00:00:02</hostMac2>
- </MININET>
-
<ENV>
<cellName>productionCell</cellName>
<cellApps>drivers,openflow</cellApps>
@@ -50,8 +40,19 @@
<port>6653</port>
</CTRL>
+ <TEST>
+ <vlan>10</vlan>
+ <ip4Type>2048</ip4Type>
+ <ip6Type>34525</ip6Type>
+ <vlanType>33024</vlanType>
+ <swDPID>of:0000000000000001</swDPID>
+ </TEST>
+
<SLEEP>
<startup>15</startup>
+ <startMN>5</startMN>
+ <addFlow>10</addFlow>
+ <delFlow>10</delFlow>
</SLEEP>
</PARAMS>
diff --git a/TestON/tests/FUNCflow/FUNCflow.py b/TestON/tests/FUNCflow/FUNCflow.py
index 89a7e32..0fa77a2 100644
--- a/TestON/tests/FUNCflow/FUNCflow.py
+++ b/TestON/tests/FUNCflow/FUNCflow.py
@@ -27,24 +27,24 @@
main.cellName = main.params[ 'ENV' ][ 'cellName' ]
main.apps = main.params[ 'ENV' ][ 'cellApps' ]
gitBranch = main.params[ 'GIT' ][ 'branch' ]
+ gitPull = main.params[ 'GIT' ][ 'pull' ]
+ main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
main.dependencyPath = main.testOnDirectory + \
main.params[ 'DEPENDENCY' ][ 'path' ]
- main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
- main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
- main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
- main.numSwitches = int( main.params[ 'TOPO' ][ 'numSwitches' ] )
- main.numHosts = int( main.params[ 'TOPO' ][ 'numHosts' ] )
- main.numLinks = int( main.params[ 'TOPO' ][ 'numLinks' ] )
wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+ main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+ main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
- gitPull = main.params[ 'GIT' ][ 'pull' ]
+ main.startMNSleep = int( main.params[ 'SLEEP' ][ 'startMN' ] )
+ main.addFlowSleep = int( main.params[ 'SLEEP' ][ 'addFlow' ] )
+ main.delFlowSleep = int( main.params[ 'SLEEP' ][ 'delFlow' ] )
+ main.swDPID = main.params[ 'TEST' ][ 'swDPID' ]
main.cellData = {} # for creating cell file
main.CLIs = []
main.ONOSip = []
main.ONOSip = main.ONOSbench.getOnosIps()
- print main.ONOSip
# Assigning ONOS cli handles to a list
for i in range( 1, main.maxNodes + 1 ):
@@ -207,49 +207,33 @@
'''
Start Mininet
'''
- main.case( "Setup mininet and assign switches to controllers" )
+ import json
+
+ main.case( "Setup mininet and compare ONOS topology view to Mininet topology" )
+ main.caseExplanation = "Start mininet with custom topology and compare topology " +\
+ "elements between Mininet and ONOS"
+
main.step( "Setup Mininet Topology" )
topology = main.Mininet1.home + '/custom/' + main.topology
- mnCmd = 'mn --custom ' + topology + ' --mac --arp'
- stepResult1 = main.Mininet1.startNet( mnCmd=mnCmd )
+ stepResult = main.Mininet1.startNet( topoFile=topology )
utilities.assert_equals( expect=main.TRUE,
- actual=stepResult1,
+ actual=stepResult,
onpass="Successfully loaded topology",
onfail="Failed to load topology" )
- main.step( "Assign switches to controllers" )
- for i in range( main.numSwitches ):
- stepResult2 = main.Mininet1.assignSwController(
- sw="s" + str( i+1 ),
- ip=main.ONOSip )
- if not stepResult2:
- break
+ main.step( "Assign switch to controller" )
+ stepResult = main.Mininet1.assignSwController( "s1", main.ONOSip[0] )
utilities.assert_equals( expect=main.TRUE,
- actual=stepResult2,
- onpass="Controller assignment successfull",
- onfail="Controller assignment failed" )
+ actual=stepResult,
+ onpass="Successfully assigned switch to controller",
+ onfail="Failed to assign switch to controller" )
- time.sleep(5)
+ time.sleep( main.startMNSleep )
- caseResult = stepResult1 and stepResult2
- if not caseResult:
- main.cleanup()
- main.exit()
-
- def CASE11( self, main ):
- '''
- Compare topology
- '''
- import json
-
- main.case( "Compare ONOS Topology view to Mininet topology" )
- main.caseExplanation = "Compare topology elements between Mininet" +\
- " and ONOS"
-
- main.step( "Gathering topology information" )
- # TODO: add a paramaterized sleep here
+ main.step( "Conmparing MN topology to ONOS topology" )
+ main.log.info( "Gathering topology information" )
devicesResults = main.TRUE
linksResults = main.TRUE
hostsResults = main.TRUE
@@ -263,7 +247,6 @@
mnLinks = main.Mininet1.getLinks()
mnHosts = main.Mininet1.getHosts()
- main.step( "Conmparing MN topology to ONOS topology" )
for controller in range( main.numCtrls ):
controllerStr = str( controller + 1 )
if devices[ controller ] and ports[ controller ] and\
@@ -309,7 +292,6 @@
" hosts don't match Mininet")
-
def CASE66( self, main ):
'''
Testing scapy
@@ -380,75 +362,301 @@
def CASE1000( self, main ):
'''
- Add flows
+ Add flows with MAC selectors and verify the flows
'''
+ import json
+ import time
- main.step("Add flows through rest")
+ main.case( "Verify flow MAC selectors are correctly compiled" )
+ main.caseExplanation = "Install two flows with only MAC selectors " +\
+ "specified, then verify flows are added in ONOS, finally "+\
+ "send a packet that only specifies the MAC src and dst."
- deviceId = main.params['MININET']['deviceId']
- host1_mac = main.params['MININET']['hostMac1']
- host2_mac = main.params['MININET']['hostMac2']
+ main.step( "Add flows with MAC addresses as the only selectors" )
- # Add flows that connects host1 to host 2
- stepResult = main.ONOSrest.addFlow( deviceId=deviceId,
- egressPort=2,
- ingressPort=1,
- ethSrc=host1_mac,
- ethDst=host2_mac)
+ main.log.info( "Creating host components" )
+ main.Mininet1.createHostComponent( "h1" )
+ main.Mininet1.createHostComponent( "h2" )
+ hosts = [main.h1, main.h2]
+ stepResult = main.TRUE
+ for host in hosts:
+ host.startHostCli()
+ host.startScapy()
+ host.updateSelf()
- stepResult = stepResult and main.ONOSrest.addFlow( deviceId=deviceId,
- egressPort=1,
- ingressPort=2,
- ethSrc=host2_mac,
- ethDst=host1_mac)
+ # Add a flow that connects host1 on port1 to host2 on port2
+ # send output on port2
+ # recieve input on port1
+ egress = 2
+ ingress = 1
+
+ # Add flows that sends packets from port1 to port2 with correct
+ # MAC src and dst addresses
+ main.log.info( "Adding flow with MAC selectors" )
+ stepResult = main.ONOSrest.addFlow( deviceId=main.swDPID,
+ egressPort=egress,
+ ingressPort=ingress,
+ ethSrc=main.h1.hostMac,
+ ethDst=main.h2.hostMac,
+ debug=True )
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
onpass="Successfully added flows",
onfail="Failed add flows" )
- def CASE2000( self, main ):
- '''
- Check flows are ADDED
- '''
- import json
- main.step("Check flows are in the ADDED state")
- main.log.info("Check only the flows added through REST")
+ # Giving ONOS time to add the flows
+ time.sleep( main.addFlowSleep )
+ main.step( "Check flows are in the ADDED state" )
+
+ #TODO: We should check mininet if flows are added as well
+ main.log.info( "Get the flows from ONOS" )
flows = json.loads( main.ONOSrest.flows() )
stepResult = main.TRUE
for f in flows:
if "rest" in f.get("appId"):
- if "ADDED" in f.get("state"):
- stepResult = stepResult and main.ONOSrest.removeFlow( deviceId, flowId )
+ if "ADDED" not in f.get("state"):
+ stepResult = main.FALSE
+ main.log.error( "Flow: %s in state: %s" % (f.get("id"), f.get("state")) )
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
onpass="All flows are in the ADDED state",
- onfail="All flows are in the ADDED state" )
+ onfail="All flows are NOT in the ADDED state" )
- def CASE3000( self, main ):
+ main.step( "Send a packet to verify the flows are correct" )
+
+ # Specify the src and dst MAC addr
+ main.log.info( "Constructing packet" )
+ main.h1.buildEther( src=main.h1.hostMac, dst=main.h2.hostMac )
+
+ # Filter for packets with the correct host name. Otherwise,
+ # the filter we catch any packet that is sent to host2
+ # NOTE: I believe it doesn't matter which host name it is,
+ # as long as its host1 or host2
+ main.log.info( "Starting filter on host2" )
+ main.h2.startFilter( pktFilter="ether host %s" % main.h1.hostMac)
+
+ main.log.info( "Sending packet to host2" )
+ main.h1.sendPacket()
+
+ main.log.info( "Checking filter for our packet" )
+ stepResult = main.h2.checkFilter()
+ if stepResult:
+ main.log.info( "Packet: %s" % main.h2.readPackets() )
+ else: main.h2.killFilter()
+
+ main.log.info( "Clean up host components" )
+ for host in hosts:
+ host.stopScapy()
+ main.Mininet1.removeHostComponent("h1")
+ main.Mininet1.removeHostComponent("h2")
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully sent a packet",
+ onfail="Failed to send a packet" )
+
+ def CASE1100( self, main ):
'''
- Delete flows that were added through REST
+ Add flows with IPv4 selectors and verify the flows
'''
import json
- main.step("Remove flows")
- main.log.info("Remove the flows that were added through rest")
+ import time
+ main.case( "Verify flow IP selectors are correctly compiled" )
+ main.caseExplanation = "Install two flows with only IP selectors " +\
+ "specified, then verify flows are added in ONOS, finally "+\
+ "send a packet that only specifies the IP src and dst."
+
+ main.step( "Add flows with IPv4 addresses as the only selectors" )
+
+ main.log.info( "Creating host components" )
+ main.Mininet1.createHostComponent( "h1" )
+ main.Mininet1.createHostComponent( "h2" )
+ hosts = [main.h1, main.h2]
+ stepResult = main.TRUE
+ for host in hosts:
+ host.startHostCli()
+ host.startScapy()
+ host.updateSelf()
+
+ # Add a flow that connects host1 on port1 to host2 on port2
+ # send output on port2
+ # recieve input on port1
+ egress = 2
+ ingress = 1
+ # IPv4 etherType = 0x800
+ IPv4=2048
+
+ # Add flows that connects host1 to host2
+ main.log.info( "Add flow with port ingress 1 to port egress 2" )
+ stepResult = main.ONOSrest.addFlow( deviceId=main.swDPID,
+ egressPort=egress,
+ ingressPort=ingress,
+ ethType=IPv4,
+ ipSrc=("IPV4_SRC", main.h1.hostIp+"/32"),
+ ipDst=("IPV4_DST", main.h2.hostIp+"/32"),
+ debug=True )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully added flows",
+ onfail="Failed add flows" )
+
+ # Giving ONOS time to add the flow
+ time.sleep( main.addFlowSleep )
+
+ main.step( "Check flow is in the ADDED state" )
+
+ main.log.info( "Get the flows from ONOS" )
flows = json.loads( main.ONOSrest.flows() )
stepResult = main.TRUE
for f in flows:
if "rest" in f.get("appId"):
- flowId = f.get("id")
- deviceId = f.get("deviceId")
- stepResult = stepResult and main.ONOSrest.removeFlow( deviceId, flowId )
+ if "ADDED" not in f.get("state"):
+ stepResult = main.FALSE
+ main.log.error( "Flow: %s in state: %s" % (f.get("id"), f.get("state")) )
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
- onpass="Successfully removed all rest flows",
- onfail="Failed to remove rest flows" )
+ onpass="All flows are in the ADDED state",
+ onfail="All flows are NOT in the ADDED state" )
+
+ main.step( "Send a packet to verify the flow is correct" )
+
+ main.log.info( "Constructing packet" )
+ # No need for the MAC src dst
+ main.h1.buildEther( dst=main.h2.hostMac )
+ main.h1.buildIP( src=main.h1.hostIp, dst=main.h2.hostIp )
+
+ main.log.info( "Starting filter on host2" )
+ # Defaults to ip
+ main.h2.startFilter()
+
+ main.log.info( "Sending packet to host2" )
+ main.h1.sendPacket()
+
+ main.log.info( "Checking filter for our packet" )
+ stepResult = main.h2.checkFilter()
+ if stepResult:
+ main.log.info( "Packet: %s" % main.h2.readPackets() )
+ else: main.h2.killFilter()
+
+ main.log.info( "Clean up host components" )
+ for host in hosts:
+ host.stopScapy()
+ main.Mininet1.removeHostComponent("h1")
+ main.Mininet1.removeHostComponent("h2")
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully sent a packet",
+ onfail="Failed to send a packet" )
+
+ def CASE1200( self, main ):
+ '''
+ Add flow with VLAN selector and verify the flow
+ '''
+ import json
+ import time
+
+ main.case( "Verify VLAN selector is correctly compiled" )
+ main.caseExplanation = "Install one flow with only the VLAN selector " +\
+ "specified, then verify the flow is added in ONOS, and finally "+\
+ "broadcast a packet with the correct VLAN tag."
+
+ # We do this here to utilize the hosts information
+ main.log.info( "Creating host components" )
+ main.Mininet1.createHostComponent( "h3" )
+ main.Mininet1.createHostComponent( "h4" )
+ hosts = [main.h3, main.h4]
+ stepResult = main.TRUE
+ for host in hosts:
+ host.startHostCli()
+ host.startScapy()
+ host.updateSelf()
+
+
+ main.step( "Add a flow with the VLAN tag as the only selector" )
+
+ # Add flows that connects the two vlan hosts h3 and h4
+ # Host 3 is on port 3 and host 4 is on port 4
+ vlan = main.params[ 'TEST' ][ 'vlan' ]
+ egress = 4
+ ingress = 3
+ # VLAN ethType = 0x8100
+ ethType = 33024
+
+ # Add only one flow because we don't need a response
+ main.log.info( "Add flow with port ingress 1 to port egress 2" )
+ stepResult = main.ONOSrest.addFlow( deviceId=main.swDPID,
+ egressPort=egress,
+ ingressPort=ingress,
+ ethType=ethType,
+ vlan=vlan,
+ debug=True )
+
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully added flow",
+ onfail="Failed add flows" )
+
+ # Giving ONOS time to add the flows
+ time.sleep( main.addFlowSleep )
+
+ main.step( "Check flows are in the ADDED state" )
+
+ main.log.info( "Get the flows from ONOS" )
+ flows = json.loads( main.ONOSrest.flows() )
+
+ stepResult = main.TRUE
+ for f in flows:
+ if "rest" in f.get("appId"):
+ if "ADDED" not in f.get("state"):
+ stepResult = main.FALSE
+ main.log.error( "Flow: %s in state: %s" % (f.get("id"), f.get("state")) )
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="All flows are in the ADDED state",
+ onfail="All flows are NOT in the ADDED state" )
+
+ main.step( "Send a packet to verify the flow are correct" )
+
+ # The receiving interface
+ recIface = "{}-eth0.{}".format(main.h4.name, vlan)
+ main.log.info( "Starting filter on host2" )
+ # Filter is setup to catch any packet on the vlan interface with the correct vlan tag
+ main.h4.startFilter( ifaceName=recIface, pktFilter="" )
+
+ # Broadcast the packet on the vlan interface. We only care if the flow forwards
+ # the packet with the correct vlan tag, not if the mac addr is correct
+ BROADCAST = "FF:FF:FF:FF:FF:FF"
+ sendIface = "{}-eth0.{}".format(main.h3.name, vlan)
+ main.log.info( "Broadcasting the packet with a vlan tag" )
+ main.h3.sendPacket( iface=sendIface, packet="Ether(dst='{}')/Dot1Q(vlan={})".format(BROADCAST, vlan))
+
+ main.log.info( "Checking filter for our packet" )
+ stepResult = main.h4.checkFilter()
+ if stepResult:
+ main.log.info( "Packet: %s" % main.h4.readPackets() )
+ else: main.h4.killFilter()
+
+ main.log.info( "Clean up host components" )
+ for host in hosts:
+ host.stopScapy()
+ main.Mininet1.removeHostComponent("h3")
+ main.Mininet1.removeHostComponent("h4")
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully sent a packet",
+ onfail="Failed to send a packet" )
def CASE100( self, main ):
'''