├── .cproject ├── .gitignore ├── .nedfolders ├── .oppbuildspec ├── .project ├── Makefile ├── README.md ├── WHATSNEW.md ├── doc └── inet4-migration-notes │ ├── README.md │ ├── inet3patch_for_openflow_migration_test.patch │ └── inet4patch_for_openflow_migration_test.patch ├── images └── openflow │ ├── OpenFlow-Logo-small.png │ ├── OpenFlow-Logo.png │ ├── OpenFlow-Logo2.png │ └── spanning-tree.png ├── license.txt ├── scenarios ├── .tkenvlog ├── .tkenvrc ├── fattree │ ├── .tkenvrc │ ├── Scenario_DynamicFatTree_ARP_Ping_Drop.ini │ ├── Scenario_DynamicFatTree_ARP_Ping_Drop_Clients.ini │ ├── Scenario_DynamicFatTree_ARP_Ping_Drop_Load.ini │ ├── Scenario_DynamicFatTree_ARP_Ping_Drop_Load_Refined.ini │ ├── Scenario_DynamicFatTree_ARP_Traffic_Drop.ini │ ├── Scenario_DynamicFatTree_Ping_Clients.ini │ ├── Scenario_DynamicFatTree_Ping_Drop.ini │ ├── Scenario_DynamicFatTree_Ping_Flood.ini │ ├── Scenario_DynamicFatTree_Traffic_Drop.ini │ ├── Scenario_DynamicFatTree_Traffic_Flood.ini │ ├── example.ini │ └── ipv4config.xml ├── hyperflow │ ├── fattree │ │ ├── .tkenvrc │ │ ├── Scenario_DynamicFatTree_ARP_HF_Ping_2C.ini │ │ ├── Scenario_DynamicFatTree_ARP_HF_Ping_3C.ini │ │ ├── Scenario_DynamicFatTree_ARP_HF_Ping_4C.ini │ │ ├── Scenario_DynamicFatTree_ARP_HF_Ping_5C.ini │ │ ├── Scenario_DynamicFatTree_HF_Ping_2C.ini │ │ ├── Scenario_DynamicFatTree_HF_Ping_3C.ini │ │ ├── Scenario_DynamicFatTree_HF_Ping_4C.ini │ │ ├── Scenario_DynamicFatTree_HF_Ping_5C.ini │ │ ├── Scenario_DynamicFatTree_HF_Ping_Flood_2C.ini │ │ ├── Scenario_DynamicFatTree_HF_Ping_Flood_3C.ini │ │ ├── Scenario_DynamicFatTree_HF_Ping_Flood_4C.ini │ │ ├── Scenario_DynamicFatTree_HF_Ping_Flood_5C.ini │ │ └── ipv4config.xml │ └── usa │ │ ├── .tkenvrc │ │ ├── Scenario_USA_ARP_HF_Ping_2C.ini │ │ ├── Scenario_USA_ARP_HF_Ping_3C.ini │ │ ├── Scenario_USA_ARP_HF_Ping_4C.ini │ │ ├── Scenario_USA_ARP_HF_Ping_5C.ini │ │ ├── Scenario_USA_HF_Ping_2C.ini │ │ ├── Scenario_USA_HF_Ping_3C.ini │ │ ├── Scenario_USA_HF_Ping_4C.ini │ │ ├── Scenario_USA_HF_Ping_5C.ini │ │ ├── Scenario_USA_HF_Ping_Flood_2C.ini │ │ ├── Scenario_USA_HF_Ping_Flood_3C.ini │ │ ├── Scenario_USA_HF_Ping_Flood_4C.ini │ │ ├── Scenario_USA_HF_Ping_Flood_5C.ini │ │ └── ipv4config.xml ├── kandoo │ ├── fattree │ │ ├── .tkenvlog │ │ ├── .tkenvrc │ │ ├── Scenario_DynamicFatTree_ARP_KN_PingLocal_2CK4.ini │ │ ├── Scenario_DynamicFatTree_ARP_KN_PingLocal_3C.ini │ │ ├── Scenario_DynamicFatTree_ARP_KN_Ping_2C.ini │ │ ├── Scenario_DynamicFatTree_ARP_KN_Ping_3C.ini │ │ ├── Scenario_DynamicFatTree_ARP_KN_Ping_4C.ini │ │ ├── Scenario_DynamicFatTree_ARP_KN_Ping_5C.ini │ │ ├── TestScenario_DynamicFatTree_ARP_KN_Ping_4C.ini │ │ └── ipv4config.xml │ └── usa │ │ ├── .tkenvlog │ │ ├── .tkenvrc │ │ ├── Scenario_USA_ARP_KN_Ping_2C.ini │ │ ├── Scenario_USA_ARP_KN_Ping_3C.ini │ │ ├── Scenario_USA_ARP_KN_Ping_4C.ini │ │ ├── Scenario_USA_ARP_KN_Ping_5C.ini │ │ └── ipv4config.xml ├── networks │ ├── Agis.ned │ ├── Agis_KN.ned │ ├── Arn.ned │ ├── Arn_KN.ned │ ├── Arnes.ned │ ├── Arnes_KN.ned │ ├── Arpanet19723.ned │ ├── Arpanet19723_KN.ned │ ├── Arpanet19728.ned │ ├── Arpanet19728_KN.ned │ ├── AttMpls.ned │ ├── AttMpls_KN.ned │ ├── Bbnplanet.ned │ ├── Bbnplanet_KN.ned │ ├── BeyondTheNetwork.ned │ ├── BeyondTheNetwork_KN.ned │ ├── Bics.ned │ ├── Bics_KN.ned │ ├── Biznet.ned │ ├── Biznet_KN.ned │ ├── Bren.ned │ ├── Bren_KN.ned │ ├── BtNorthAmerica.ned │ ├── BtNorthAmerica_KN.ned │ ├── Cernet.ned │ ├── Cernet_KN.ned │ ├── Cesnet200304.ned │ ├── Cesnet200304_KN.ned │ ├── Cesnet200511.ned │ ├── Cesnet200511_KN.ned │ ├── Cesnet200603.ned │ ├── Cesnet200603_KN.ned │ ├── Cesnet200706.ned │ ├── Cesnet200706_KN.ned │ ├── Chinanet.ned │ ├── Chinanet_KN.ned │ ├── CrlNetworkServices.ned │ ├── CrlNetworkServices_KN.ned │ ├── Darkstrand.ned │ ├── Darkstrand_KN.ned │ ├── Digex.ned │ ├── Digex_KN.ned │ ├── Evolink.ned │ ├── Evolink_KN.ned │ ├── Geant2001.ned │ ├── Geant2001_KN.ned │ ├── Geant2009.ned │ ├── Geant2009_KN.ned │ ├── Geant2010.ned │ ├── Geant2010_KN.ned │ ├── Geant2012.ned │ ├── Geant2012_KN.ned │ ├── Grnet.ned │ ├── Grnet_KN.ned │ ├── GtsCzechRepublic.ned │ ├── GtsCzechRepublic_KN.ned │ ├── GtsPoland.ned │ ├── GtsPoland_KN.ned │ ├── GtsSlovakia.ned │ ├── GtsSlovakia_KN.ned │ ├── Iij.ned │ ├── Iij_KN.ned │ ├── Integra.ned │ ├── Integra_KN.ned │ ├── Janetbackbone.ned │ ├── Janetbackbone_KN.ned │ ├── KentmanFeb2008.ned │ ├── KentmanFeb2008_KN.ned │ ├── KentmanJan2011.ned │ ├── KentmanJan2011_KN.ned │ ├── LambdaNet.ned │ ├── LambdaNet_KN.ned │ ├── Litnet.ned │ ├── Litnet_KN.ned │ ├── NetworkUsa.ned │ ├── NetworkUsa_KN.ned │ ├── Niif.ned │ ├── Niif_KN.ned │ ├── PionierL3.ned │ ├── PionierL3_KN.ned │ ├── Renater2006.ned │ ├── Renater2006_KN.ned │ ├── Renater2008.ned │ ├── Renater2008_KN.ned │ ├── Renater2010.ned │ ├── Renater2010_KN.ned │ ├── Rnp.ned │ ├── Rnp_KN.ned │ ├── Roedunet.ned │ ├── Roedunet_KN.ned │ ├── Sanet.ned │ ├── Sanet_KN.ned │ ├── Scenario_DynamicFatTree.ned │ ├── Scenario_DynamicFatTree_HF.ned │ ├── Scenario_DynamicFatTree_KN.ned │ ├── Scenario_TestCase.ned │ ├── Scenario_TestCaseDiamond.ned │ ├── Scenario_TestCaseKandooDiamond.ned │ ├── Scenario_TestCaseKandooSplit.ned │ ├── Scenario_USA.ned │ ├── Scenario_USA_HF.ned │ ├── Scenario_USA_KN.ned │ ├── Sunet.ned │ ├── Sunet_KN.ned │ ├── SwitchL3.ned │ ├── SwitchL3_KN.ned │ ├── Xspedius.ned │ └── Xspedius_KN.ned ├── package.ned ├── testcases │ ├── .tkenvlog │ ├── .tkenvrc │ ├── Scenario_TestCase_ARPResponder.ini │ ├── Scenario_TestCase_BalancedMinHop.ini │ ├── Scenario_TestCase_Diamond.ini │ ├── Scenario_TestCase_Forwarding.ini │ ├── Scenario_TestCase_Hub.ini │ ├── Scenario_TestCase_HyperFlow_ARPResponder.ini │ ├── Scenario_TestCase_HyperFlow_Forwarding.ini │ ├── Scenario_TestCase_KandooDiamond.ini │ ├── Scenario_TestCase_KandooSplit.ini │ ├── Scenario_TestCase_LLDP.ini │ ├── Scenario_TestCase_LearningSwitch.ini │ ├── Scenario_TestCase_TrafficGenerator.ini │ ├── example.ini │ └── ipv4config.xml ├── topologyzoo │ ├── .tkenvrc │ ├── Agis.ini │ ├── Agis_KN.ini │ ├── Arn.ini │ ├── Arn_KN.ini │ ├── Arnes.ini │ ├── Arnes_KN.ini │ ├── Arpanet19723.ini │ ├── Arpanet19723_KN.ini │ ├── Arpanet19728.ini │ ├── Arpanet19728_KN.ini │ ├── AttMpls.ini │ ├── AttMpls_KN.ini │ ├── Bbnplanet.ini │ ├── Bbnplanet_KN.ini │ ├── BeyondTheNetwork.ini │ ├── BeyondTheNetwork_KN.ini │ ├── Bics.ini │ ├── Bics_KN.ini │ ├── Biznet.ini │ ├── Biznet_KN.ini │ ├── Bren.ini │ ├── Bren_KN.ini │ ├── BtNorthAmerica.ini │ ├── BtNorthAmerica_KN.ini │ ├── Cernet.ini │ ├── Cernet_KN.ini │ ├── Cesnet200304.ini │ ├── Cesnet200304_KN.ini │ ├── Cesnet200511.ini │ ├── Cesnet200511_KN.ini │ ├── Cesnet200603.ini │ ├── Cesnet200603_KN.ini │ ├── Cesnet200706.ini │ ├── Cesnet200706_KN.ini │ ├── Chinanet.ini │ ├── Chinanet_KN.ini │ ├── CrlNetworkServices.ini │ ├── CrlNetworkServices_KN.ini │ ├── Darkstrand.ini │ ├── Darkstrand_KN.ini │ ├── Digex.ini │ ├── Digex_KN.ini │ ├── Evolink.ini │ ├── Evolink_KN.ini │ ├── Geant2001.ini │ ├── Geant2001_KN.ini │ ├── Geant2009.ini │ ├── Geant2009_KN.ini │ ├── Geant2010.ini │ ├── Geant2010_KN.ini │ ├── Geant2012.ini │ ├── Geant2012_KN.ini │ ├── Grnet.ini │ ├── Grnet_KN.ini │ ├── GtsCzechRepublic.ini │ ├── GtsCzechRepublic_KN.ini │ ├── GtsPoland.ini │ ├── GtsPoland_KN.ini │ ├── GtsSlovakia.ini │ ├── GtsSlovakia_KN.ini │ ├── Iij.ini │ ├── Iij_KN.ini │ ├── Integra.ini │ ├── Integra_KN.ini │ ├── Janetbackbone.ini │ ├── Janetbackbone_KN.ini │ ├── KentmanFeb2008.ini │ ├── KentmanFeb2008_KN.ini │ ├── KentmanJan2011.ini │ ├── KentmanJan2011_KN.ini │ ├── LambdaNet.ini │ ├── LambdaNet_KN.ini │ ├── Litnet.ini │ ├── Litnet_KN.ini │ ├── NetworkUsa.ini │ ├── NetworkUsa_KN.ini │ ├── Niif.ini │ ├── Niif_KN.ini │ ├── PionierL3.ini │ ├── PionierL3_KN.ini │ ├── Renater2006.ini │ ├── Renater2006_KN.ini │ ├── Renater2008.ini │ ├── Renater2008_KN.ini │ ├── Renater2010.ini │ ├── Renater2010_KN.ini │ ├── Rnp.ini │ ├── Rnp_KN.ini │ ├── Roedunet.ini │ ├── Roedunet_KN.ini │ ├── Sanet.ini │ ├── Sanet_KN.ini │ ├── Sunet.ini │ ├── Sunet_KN.ini │ ├── SwitchL3.ini │ ├── SwitchL3_KN.ini │ ├── Xspedius.ini │ ├── Xspedius_KN.ini │ └── ipv4config.xml └── usa │ ├── .tkenvlog │ ├── .tkenvrc │ ├── Scenario_USA_ARP_Ping_Drop.ini │ ├── Scenario_USA_ARP_Ping_Drop_Clients_Packets.ini │ ├── Scenario_USA_ARP_Ping_Drop_Load.ini │ ├── Scenario_USA_ARP_Ping_Drop_Load_Refined.ini │ ├── Scenario_USA_ARP_Traffic_Drop.ini │ ├── Scenario_USA_Ping_Drop.ini │ ├── Scenario_USA_Ping_Drop_Clients_Packets.ini │ ├── Scenario_USA_Ping_Flood.ini │ ├── Scenario_USA_Traffic_Drop.ini │ ├── Scenario_USA_Traffic_Flood.ini │ └── ipv4config.xml ├── setenv ├── src ├── openflow │ ├── controllerApps │ │ ├── ARPResponder.cc │ │ ├── ARPResponder.h │ │ ├── ARPResponder.ned │ │ ├── AbstractControllerApp.cc │ │ ├── AbstractControllerApp.h │ │ ├── AbstractTCPControllerApp.cc │ │ ├── AbstractTCPControllerApp.h │ │ ├── AbstractTCPControllerApp.ned │ │ ├── Hub.cc │ │ ├── Hub.h │ │ ├── Hub.ned │ │ ├── IControllerApp.ned │ │ ├── LLDPAgent.cc │ │ ├── LLDPAgent.h │ │ ├── LLDPAgent.ned │ │ ├── LLDPBalancedMinHop.cc │ │ ├── LLDPBalancedMinHop.h │ │ ├── LLDPBalancedMinHop.ned │ │ ├── LLDPForwarding.cc │ │ ├── LLDPForwarding.h │ │ ├── LLDPForwarding.ned │ │ ├── LLDPMib.cc │ │ ├── LLDPMib.h │ │ ├── LLDPMibGraph.cc │ │ ├── LLDPMibGraph.h │ │ ├── LearningSwitch.cc │ │ ├── LearningSwitch.h │ │ └── LearningSwitch.ned │ ├── hostApps │ │ ├── LocalityPingAppRandom.cc │ │ ├── LocalityPingAppRandom.h │ │ ├── LocalityPingAppRandom.ned │ │ ├── PingAppRandom.cc │ │ ├── PingAppRandom.h │ │ ├── PingAppRandom.ned │ │ ├── TCPTrafficGeneratorApp.cc │ │ ├── TCPTrafficGeneratorApp.h │ │ ├── TCPTrafficGeneratorApp.ned │ │ ├── TCPTrafficSinkApp.ned │ │ ├── localityGroupConfigFatTree2ControllersK4.txt │ │ ├── localityGroupConfigFatTree3ControllersK6.txt │ │ └── randomFlowSizesCleaned1.txt.tar.gz │ ├── hyperflow │ │ ├── HF_ARPResponder.cc │ │ ├── HF_ARPResponder.h │ │ ├── HF_ARPResponder.ned │ │ ├── HF_LLDPAgent.cc │ │ ├── HF_LLDPAgent.h │ │ ├── HF_LLDPAgent.ned │ │ ├── HF_ReFire_Wrapper.cc │ │ ├── HF_ReFire_Wrapper.h │ │ ├── HyperFlowAgent.cc │ │ ├── HyperFlowAgent.h │ │ ├── HyperFlowAgent.ned │ │ ├── HyperFlowStructs.h │ │ ├── HyperFlowSynchronizer.cc │ │ ├── HyperFlowSynchronizer.h │ │ ├── HyperFlowSynchronizer.ned │ │ └── Hyper_Flow_Synchronizer.ned │ ├── kandoo │ │ ├── KN_ARPResponder.cc │ │ ├── KN_ARPResponder.h │ │ ├── KN_ARPResponder.ned │ │ ├── KN_LLDPAgent.cc │ │ ├── KN_LLDPAgent.h │ │ ├── KN_LLDPAgent.ned │ │ ├── KN_LLDPBalancedMinHop.cc │ │ ├── KN_LLDPBalancedMinHop.h │ │ ├── KN_LLDPBalancedMinHop.ned │ │ ├── KN_LLDPForwarding.cc │ │ ├── KN_LLDPForwarding.h │ │ ├── KN_LLDPForwarding.ned │ │ ├── KandooAgent.cc │ │ ├── KandooAgent.h │ │ └── KandooAgent.ned │ ├── messages │ │ ├── HF_ChangeNotification.msg │ │ ├── HF_Packet.msg │ │ ├── HF_ReportIn.msg │ │ ├── HF_SyncReply.msg │ │ ├── HF_SyncRequest.msg │ │ ├── KN_Packet.msg │ │ ├── LLDP.msg │ │ ├── OFP_Features_Reply.msg │ │ ├── OFP_Features_Request.msg │ │ ├── OFP_Flow_Mod.msg │ │ ├── OFP_Hello.msg │ │ ├── OFP_Initialize_Handshake.msg │ │ ├── OFP_Packet_In.msg │ │ ├── OFP_Packet_Out.msg │ │ ├── OFP_Port_Mod.msg │ │ ├── OpenFlowStructs.msg │ │ └── Open_Flow_Message.msg │ ├── nodes │ │ ├── DistanceChannel.ned │ │ ├── DynamicFatTree.ned │ │ ├── Fat_Tree.ned │ │ └── Open_Flow_Domain.ned │ ├── openflow │ │ ├── controller │ │ │ ├── IOpenFlowController.ned │ │ │ ├── OF_Controller.cc │ │ │ ├── OF_Controller.h │ │ │ ├── OF_Controller.ned │ │ │ ├── Open_Flow_Controller.ned │ │ │ ├── Switch_Info.cc │ │ │ └── Switch_Info.h │ │ ├── protocol │ │ │ ├── OF100MatchBuilder.cc │ │ │ ├── OF100MatchBuilder.h │ │ │ ├── OF100MessageFactory.cc │ │ │ ├── OF100MessageFactory.h │ │ │ ├── OFMatchFactory.cc │ │ │ ├── OFMatchFactory.h │ │ │ ├── OFMessageFactory.cc │ │ │ ├── OFMessageFactory.h │ │ │ ├── OpenFlow.h │ │ │ ├── openflow_100.h │ │ │ ├── openflow_135.h │ │ │ ├── openflow_141.h │ │ │ └── openflow_151.h │ │ └── switch │ │ │ ├── Buffer.cc │ │ │ ├── Buffer.h │ │ │ ├── Flow_Table.cc │ │ │ ├── Flow_Table.h │ │ │ ├── Flow_Table_Entry.cc │ │ │ ├── Flow_Table_Entry.h │ │ │ ├── IOpenFlowRelayUnit.ned │ │ │ ├── OF_Switch.cc │ │ │ ├── OF_Switch.h │ │ │ ├── OF_Switch.ned │ │ │ ├── Open_Flow_Switch.ned │ │ │ └── flowtable │ │ │ ├── IOpenFlowFlowTable.ned │ │ │ ├── OF100_FlowTableEntry.cc │ │ │ ├── OF100_FlowTableEntry.h │ │ │ ├── OF_FlowTable.cc │ │ │ ├── OF_FlowTable.h │ │ │ ├── OF_FlowTable.ned │ │ │ ├── OF_FlowTableEntry.cc │ │ │ └── OF_FlowTableEntry.h │ ├── package.ned │ └── utility │ │ ├── ARP_Wrapper.cc │ │ ├── ARP_Wrapper.h │ │ ├── ControllerInvolvementFilter.h │ │ ├── ControllerInvolvementFilter.ned │ │ ├── ControllerInvolvmentFilter.cc │ │ ├── KandooStructs.h │ │ ├── LLDP_Wrapper.cc │ │ ├── LLDP_Wrapper.h │ │ ├── OpenFlowGraphAnalyzer.cc │ │ ├── OpenFlowGraphAnalyzer.h │ │ ├── OpenFlowGraphAnalyzer.ned │ │ ├── StaticSpanningTree.cc │ │ ├── StaticSpanningTree.h │ │ └── StaticSpanningTree.ned └── run_openflow └── test ├── fingerprint ├── README ├── fingerprinttest ├── inet4_fingerprinttest └── scenarios.csv └── smoke ├── README ├── gen_runallexamples.pl ├── scenarios.csv └── smoketest /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore generated files 2 | .settings/ 3 | *_m.h 4 | *_m.cc 5 | /src/Makefile 6 | /src/Makefile.vc 7 | /doc/doxy 8 | /doc/neddoc 9 | /doc/index.html 10 | /FeatureBuildTest 11 | 12 | # settings 13 | *.qtenvrc 14 | *.tkenvrc 15 | *.tkenvlog 16 | *.cmdenv-log 17 | 18 | #results 19 | /examples/*/results/ 20 | /examples/*/*/results/ 21 | /examples/*/*/*/results/ 22 | *.vci 23 | *.vec 24 | *.sca 25 | *.anf 26 | 27 | #tests 28 | /tests/*/work/ 29 | 30 | # ignore binary files 31 | /out 32 | *.so 33 | *.dylib 34 | *.dll 35 | *.a 36 | *.lib 37 | *.exe 38 | *.o 39 | *.obj 40 | 41 | # local files not to be committed 42 | .oppfeaturestate 43 | .nedexclusions 44 | src/*/features.h 45 | 46 | # ignore backup and temp files 47 | *.tmp* 48 | 49 | #ignore Apple files 50 | .DS_Store 51 | 52 | test/smoke/test\.out 53 | 54 | src/openflow/hostApps/randomFlowSizesCleaned1\.txt 55 | *.def 56 | test/fingerprint/results/ 57 | *.out 58 | *.ERROR 59 | -------------------------------------------------------------------------------- /.nedfolders: -------------------------------------------------------------------------------- 1 | src 2 | scenarios 3 | -------------------------------------------------------------------------------- /.oppbuildspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | OpenFlow 4 | 5 | 6 | inet 7 | 8 | 9 | 10 | org.omnetpp.cdt.MakefileBuilder 11 | 12 | 13 | 14 | 15 | org.omnetpp.scave.builder.vectorfileindexer 16 | 17 | 18 | 19 | 20 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 21 | clean,full,incremental, 22 | 23 | 24 | 25 | 26 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 27 | full,incremental, 28 | 29 | 30 | 31 | 32 | 33 | org.eclipse.cdt.core.cnature 34 | org.eclipse.cdt.core.ccnature 35 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 36 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 37 | org.omnetpp.main.omnetppnature 38 | 39 | 40 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #Try to detect INET if variable is not set 2 | ifndef INET_PROJ 3 | ifneq ($(wildcard ../inet),) 4 | INET_PROJ=../../inet 5 | else 6 | $(error "Cannot find INET framework in the usual location. You have to set the PATH to INET in the INET_PROJ variable") 7 | endif 8 | endif 9 | all: checkmakefiles 10 | cd src && $(MAKE) 11 | 12 | clean: checkmakefiles 13 | cd src && $(MAKE) clean 14 | 15 | cleanall: checkmakefiles 16 | cd src && $(MAKE) MODE=release clean 17 | cd src && $(MAKE) MODE=debug clean 18 | rm -f src/Makefile 19 | 20 | makefiles: 21 | cd src && opp_makemake --make-so -f --deep --no-deep-includes -O out -KINET_PROJ=../../inet -I. -I$$\(INET_PROJ\)/src -L$$\(INET_PROJ\)/src -lINET$$\(D\) 22 | 23 | checkmakefiles: 24 | @if [ ! -f src/Makefile ]; then \ 25 | echo; \ 26 | echo '======================================================================='; \ 27 | echo 'src/Makefile does not exist. Please use "make makefiles" to generate it!'; \ 28 | echo '======================================================================='; \ 29 | echo; \ 30 | exit 1; \ 31 | fi 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenFlow model for OMNeT++ and the INET Framework 2 | 3 | Simulation model of the OpenFlow system based on the OpenFlow switch 4 | specification 1.0. 5 | 6 | Software Defined Networking (SDN) is a new paradigm for communication networks 7 | which separates the control plane from the data plane of forwarding elements. 8 | This way, SDN constitutes a flexible architecture that allows quick and easy 9 | configuration of network devices. OpenFlow is a well-known implementation of the 10 | SDN concept and offers a high flexibility in the routing of network flows. 11 | 12 | The model was originally presented at the 6th International Workshop on OMNeT++ 13 | by authors Dominik Klein and Michael Jarschel of University of Würzburg, for 14 | INET-2.0 and OMNeT++ 4.2. In later years, the code was ported to newer INET and 15 | OMNeT++ versions independently by multiple teams and individuals, resulting in 16 | several forked repositories. A notable fork is maintained by the CoRE research 17 | group at the HAW-Hamburg (Hamburg University of Applied Sciences), extended to 18 | work together with the CoRE simulation models. This repository has also taken 19 | the CoRE group's fork as a starting point. 20 | 21 | Links: 22 | * [OMNeT++2013 paper](https://www.informatik.uni-wuerzburg.de/fileadmin/10030300/sonstiges/paper-acm_with_font.pdf) 23 | * [Presentation slides](https://www.informatik.uni-wuerzburg.de/fileadmin/10030300/sonstiges/20130305-dklein-OpenFlow-Implementaiton-02.ppsx) 24 | * [Original Git repository](https://github.com/lsinfo3/ofomnet) 25 | * [CoRE fork](https://github.com/CoRE-RG/openflow) 26 | -------------------------------------------------------------------------------- /WHATSNEW.md: -------------------------------------------------------------------------------- 1 | OpenFlow-20250605 2 | ----------------- 3 | 4 | * Ported to INET-4.x. See `inet4-migration-notes/` for details. Incorporates migration work by Alfonso Ariza Quintana. 5 | * Renamed `AbstractControllerApp` NED type to `IControllerApp` 6 | * Added NED documentation for several undocumented modules 7 | * Tested with omnetpp-6.1 and inet-4.5.4 and 4.4.2. 8 | 9 | 10 | OpenFlow-20250602 11 | ----------------- 12 | 13 | Patch release for OpenFlow 20240124. 14 | 15 | * Added `setenv` script 16 | * Updated `fingerprinttest` script, added network-level (~tNl) fingerprints 17 | * ARPResponder: fix: do not add preamble and SFD to frame length 18 | * StaticSpanningTree: fixed wrong numInitStages 19 | * Fill in OFB_IN_PORT in internal messages 20 | * More assertions in the code 21 | * Compatible with omnetpp-6.1 and inet-3.8.5 22 | 23 | 24 | OpenFlow-20240124 25 | ----------------- 26 | 27 | This repo started as a fork of the CoRE research group's OpenFlow fork, and this release represents their last version. 28 | 29 | * Identical to [CoRE-RG/OpenFlow's nightly/2024-01-24_15-05-30](https://github.com/CoRE-RG/OpenFlow/releases/tag/nightly%2F2024-01-24_15-05-30). 30 | * Compatible with omnetpp-6.0.3 and inet-3.8.3 -------------------------------------------------------------------------------- /doc/inet4-migration-notes/inet3patch_for_openflow_migration_test.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/inet/transportlayer/tcp/TCP.ned b/src/inet/transportlayer/tcp/TCP.ned 2 | index bce68dec39..d3de7fbb11 100644 3 | --- a/src/inet/transportlayer/tcp/TCP.ned 4 | +++ b/src/inet/transportlayer/tcp/TCP.ned 5 | @@ -202,7 +202,7 @@ simple TCP like ITCP 6 | parameters: 7 | int advertisedWindow = default(14*this.mss); // in bytes, corresponds with the maximal receiver buffer capacity (Note: normally, NIC queues should be at least this size) 8 | bool delayedAcksEnabled = default(false); // delayed ACK algorithm (RFC 1122) enabled/disabled 9 | - bool nagleEnabled = default(true); // Nagle's algorithm (RFC 896) enabled/disabled 10 | + bool nagleEnabled = default(false); // Nagle's algorithm (RFC 896) enabled/disabled 11 | bool limitedTransmitEnabled = default(false); // Limited Transmit algorithm (RFC 3042) enabled/disabled (can be used for TCPReno/TCPTahoe/TCPNewReno/TCPNoCongestionControl) 12 | bool increasedIWEnabled = default(false); // Increased Initial Window (RFC 3390) enabled/disabled 13 | bool sackSupport = default(false); // Selective Acknowledgment (RFC 2018, 2883, 3517) support (header option) (SACK will be enabled for a connection if both endpoints support it) 14 | -------------------------------------------------------------------------------- /doc/inet4-migration-notes/inet4patch_for_openflow_migration_test.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/inet/transportlayer/tcp/Tcp.ned b/src/inet/transportlayer/tcp/Tcp.ned 2 | index 437f92bcbb..f16d58b861 100644 3 | --- a/src/inet/transportlayer/tcp/Tcp.ned 4 | +++ b/src/inet/transportlayer/tcp/Tcp.ned 5 | @@ -186,7 +186,7 @@ simple Tcp like ITcp 6 | string crcMode @enum("declared", "computed") = default("declared"); 7 | int advertisedWindow = default(14*this.mss); // in bytes, corresponds with the maximal receiver buffer capacity (Note: normally, NIC queues should be at least this size) 8 | bool delayedAcksEnabled = default(false); // delayed ACK algorithm (RFC 1122) enabled/disabled 9 | - bool nagleEnabled = default(true); // Nagle's algorithm (RFC 896) enabled/disabled 10 | + bool nagleEnabled = default(false); // Nagle's algorithm (RFC 896) enabled/disabled 11 | bool limitedTransmitEnabled = default(false); // Limited Transmit algorithm (RFC 3042) enabled/disabled (can be used for TcpReno/TcpTahoe/TcpNewReno/TcpNoCongestionControl) 12 | bool increasedIWEnabled = default(false); // Increased Initial Window (RFC 3390) enabled/disabled 13 | bool sackSupport = default(false); // Selective Acknowledgment (RFC 2018, 2883, 3517) support (header option) (SACK will be enabled for a connection if both endpoints support it) 14 | diff --git a/src/inet/transportlayer/tcp/TcpConnectionUtil.cc b/src/inet/transportlayer/tcp/TcpConnectionUtil.cc 15 | index a1b2b0e8d8..8e7f0dba40 100644 16 | --- a/src/inet/transportlayer/tcp/TcpConnectionUtil.cc 17 | +++ b/src/inet/transportlayer/tcp/TcpConnectionUtil.cc 18 | @@ -889,6 +889,7 @@ bool TcpConnection::sendData(uint32_t congestionWindow) 19 | // start sending 'bytesToSend' bytes 20 | EV_INFO << "May send " << bytesToSend << " bytes (effectiveWindow " << effectiveWin << ", in buffer " << buffered << " bytes)\n"; 21 | 22 | + 23 | // send whole segments 24 | while (bytesToSend >= effectiveMss) { 25 | uint32_t sentBytes = sendSegment(effectiveMss); 26 | @@ -904,8 +905,11 @@ bool TcpConnection::sendData(uint32_t congestionWindow) 27 | bool containsFin = state->send_fin && (state->snd_nxt + bytesToSend) == state->snd_fin_seq; 28 | if (state->nagle_enabled && unacknowledgedData && !containsFin) 29 | EV_WARN << "Cannot send (last) segment due to Nagle, not enough data for a full segment\n"; 30 | - else 31 | - sendSegment(bytesToSend); 32 | + else { 33 | + buffered = sendQueue->getBytesAvailable(state->snd_nxt); 34 | + if ((bytesToSend == buffered && buffered > 0) || (old_snd_nxt == state->snd_nxt)) 35 | + sendSegment(bytesToSend); 36 | + } 37 | } 38 | 39 | if (old_snd_nxt == state->snd_nxt) 40 | -------------------------------------------------------------------------------- /images/openflow/OpenFlow-Logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inet-framework/openflow/5624978a34bac600123bba2e7f19f5800697d6e3/images/openflow/OpenFlow-Logo-small.png -------------------------------------------------------------------------------- /images/openflow/OpenFlow-Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inet-framework/openflow/5624978a34bac600123bba2e7f19f5800697d6e3/images/openflow/OpenFlow-Logo.png -------------------------------------------------------------------------------- /images/openflow/OpenFlow-Logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inet-framework/openflow/5624978a34bac600123bba2e7f19f5800697d6e3/images/openflow/OpenFlow-Logo2.png -------------------------------------------------------------------------------- /images/openflow/spanning-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inet-framework/openflow/5624978a34bac600123bba2e7f19f5800697d6e3/images/openflow/spanning-tree.png -------------------------------------------------------------------------------- /scenarios/.tkenvrc: -------------------------------------------------------------------------------- 1 | # Partial OMNeT++/Tkenv config file -- see $HOME/.tkenvrc as well 2 | config default-configname {} 3 | config default-runnumber {} 4 | 5 | -------------------------------------------------------------------------------- /scenarios/fattree/.tkenvrc: -------------------------------------------------------------------------------- 1 | # Partial OMNeT++/Tkenv config file -- see $HOME/.tkenvrc as well 2 | config default-configname {} 3 | config default-runnumber {} 4 | 5 | -------------------------------------------------------------------------------- /scenarios/fattree/Scenario_DynamicFatTree_Ping_Clients.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_DynamicFatTree 3 | 4 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 5 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 6 | 7 | sim-time-limit = 300s 8 | repeat = 4 9 | seed-set = ${repetition} 10 | 11 | **.fat_tree.K = (${k= 4,6,8}) 12 | 13 | **.rtt.result-recording-modes = +vector,-stats 14 | **.queueSize.result-recording-modes = +vector,+stats 15 | **.bufferSize.result-recording-modes = +vector,+stats 16 | **.waitingTime.result-recording-modes = +vector,+stats 17 | 18 | **.packets.result-recording-modes = +count 19 | **.packetBytes.result-recording-modes = +sum 20 | **.packets*.scalar-recording = true 21 | **.packetBytes*.scalar-recording = true 22 | 23 | **.numPacketIn*.scalar-recording = true 24 | 25 | **.bufferSize*.vector-recording = true 26 | **.queueSize*.vector-recording = true 27 | **.waitingTime*.vector-recording = true 28 | 29 | **.nodeInNumPaths**.scalar-recording = true 30 | **.avgPathLength.scalar-recording = true 31 | **.minPathLength.scalar-recording = true 32 | **.maxPathLength.scalar-recording = true 33 | **.numClients.scalar-recording = true 34 | **.numPaths.scalar-recording = true 35 | 36 | **.flowTable**.scalar-recording = true 37 | 38 | **.app[*].rtt*.vector-recording = true 39 | 40 | **.controllerApps[*].*.scalar-recording = true 41 | **.app[*].numLost*.scalar-recording = true 42 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 43 | 44 | **.vector-recording = false 45 | **.scalar-recording = false 46 | 47 | 48 | **.spanningTree.startNode = 4 49 | **.highlightActivePorts = true 50 | 51 | 52 | # random ping application 53 | **.client[*].numApps = 1 54 | **.client[*].app[*].typename = "PingAppRandom" 55 | **.client[*].app[*].sendInterval = (${pingInterval= 0.25,0.5,1,1.5,2}s) 56 | **.client[*].app[*].startTime = uniform(100s,120s) 57 | 58 | 59 | # openflow parameters 60 | **.coreLayerSwitches[*].OF_Switch.connectAddress = "open_flow_controller1" 61 | **.coreLayerSwitches[*].OF_Switch.connectAt = uniform(0s,1s) 62 | 63 | **.aggLayerSwitches[*].OF_Switch.connectAddress = "open_flow_controller1" 64 | **.aggLayerSwitches[*].OF_Switch.connectAt = uniform(0s,1s) 65 | 66 | **.edgeLayerSwitches[*].OF_Switch.connectAddress = "open_flow_controller1" 67 | **.edgeLayerSwitches[*].OF_Switch.connectAt = uniform(0s,1s) 68 | 69 | 70 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 71 | **.OF_Switch.bufferCapacity = 3712 72 | 73 | **.OF_Switch.serviceTime = 0.000035s 74 | 75 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 76 | **.open_flow_controller*.serviceTime = 0.000005556s 77 | 78 | 79 | **.open_flow_controller*.numControllerApps = 2 80 | **.open_flow_controller*.controllerApps[0].typename = "LLDPBalancedMinHop" 81 | #refer to beacon leraning switch code 82 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 5 83 | 84 | **.open_flow_controller*.controllerApps[1].typename = "LLDPAgent" 85 | **.open_flow_controller*.controllerApps[1].flowModIdleTimeOut = 140 86 | 87 | 88 | # NIC configuration 89 | **.ppp[*].queue.packetCapacity = 10 # in routers 90 | 91 | 92 | #linux mint 15 std value 93 | **.arp.cacheTimeout = 60s 94 | 95 | # configure control and data plane interfaces separately 96 | *.configurator.config = xmldoc("ipv4config.xml") 97 | -------------------------------------------------------------------------------- /scenarios/fattree/example.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_DynamicFatTree 3 | 4 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 5 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 6 | 7 | sim-time-limit = 300s 8 | repeat = 1 9 | seed-set = ${repetition} 10 | 11 | **.fat_tree.K = 2 12 | 13 | **.rtt.result-recording-modes = +vector,-stats 14 | **.queueSize.result-recording-modes = +vector,+stats 15 | **.bufferSize.result-recording-modes = +vector,+stats 16 | **.waitingTime.result-recording-modes = +vector,+stats 17 | 18 | **.packets.result-recording-modes = +count 19 | **.packetBytes.result-recording-modes = +sum 20 | **.packets*.scalar-recording = true 21 | **.packetBytes*.scalar-recording = true 22 | 23 | **.numPacketIn*.scalar-recording = true 24 | 25 | **.bufferSize*.vector-recording = true 26 | **.queueSize*.vector-recording = true 27 | **.waitingTime*.vector-recording = true 28 | 29 | **.nodeInNumPaths**.scalar-recording = true 30 | **.avgPathLength.scalar-recording = true 31 | **.minPathLength.scalar-recording = true 32 | **.maxPathLength.scalar-recording = true 33 | **.numClients.scalar-recording = true 34 | **.numPaths.scalar-recording = true 35 | 36 | **.flowTable**.scalar-recording = true 37 | 38 | **.app[*].rtt*.vector-recording = true 39 | 40 | **.controllerApps[*].*.scalar-recording = true 41 | **.app[*].numLost*.scalar-recording = true 42 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 43 | 44 | **.vector-recording = false 45 | **.scalar-recording = false 46 | 47 | 48 | **.spanningTree.startNode = 4 49 | **.highlightActivePorts = true 50 | 51 | 52 | # random ping application 53 | **.client[*].numApps = 1 54 | **.client[*].app[*].typename = "PingAppRandom" 55 | **.client[*].app[*].sendInterval = (0.25s) 56 | **.client[*].app[*].startTime = uniform(100s,120s) 57 | 58 | 59 | # openflow parameters 60 | **.coreLayerSwitches[*].OF_Switch.connectAddress = "open_flow_controller1" 61 | **.coreLayerSwitches[*].OF_Switch.connectAt = uniform(0s,1s) 62 | 63 | **.aggLayerSwitches[*].OF_Switch.connectAddress = "open_flow_controller1" 64 | **.aggLayerSwitches[*].OF_Switch.connectAt = uniform(0s,1s) 65 | 66 | **.edgeLayerSwitches[*].OF_Switch.connectAddress = "open_flow_controller1" 67 | **.edgeLayerSwitches[*].OF_Switch.connectAt = uniform(0s,1s) 68 | 69 | 70 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 71 | **.OF_Switch.bufferCapacity = 3712 72 | 73 | **.OF_Switch.serviceTime = 0.000035s 74 | 75 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 76 | **.open_flow_controller*.serviceTime = 0.000005556s 77 | 78 | 79 | **.open_flow_controller*.numControllerApps = 2 80 | **.open_flow_controller*.controllerApps[0].typename = "LLDPBalancedMinHop" 81 | #refer to beacon leraning switch code 82 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 5 83 | 84 | **.open_flow_controller*.controllerApps[1].typename = "LLDPAgent" 85 | **.open_flow_controller*.controllerApps[1].flowModIdleTimeOut = 140 86 | 87 | 88 | # NIC configuration 89 | **.ppp[*].queue.packetCapacity = 10 # in routers 90 | 91 | 92 | #linux mint 15 std value 93 | **.arp.cacheTimeout = 60s 94 | 95 | *.configurator.config = xmldoc("ipv4config.xml") 96 | #*.configurator.addStaticRoutes = false 97 | #**.displayAddresses = true 98 | #**.arpType = "GlobalARP" 99 | -------------------------------------------------------------------------------- /scenarios/fattree/ipv4config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /scenarios/hyperflow/fattree/.tkenvrc: -------------------------------------------------------------------------------- 1 | # Partial OMNeT++/Tkenv config file -- see $HOME/.tkenvrc as well 2 | config default-configname {} 3 | config default-runnumber {} 4 | 5 | -------------------------------------------------------------------------------- /scenarios/hyperflow/fattree/ipv4config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /scenarios/hyperflow/usa/.tkenvrc: -------------------------------------------------------------------------------- 1 | # Partial OMNeT++/Tkenv config file -- see $HOME/.tkenvrc as well 2 | config default-configname {} 3 | config default-runnumber {} 4 | 5 | -------------------------------------------------------------------------------- /scenarios/hyperflow/usa/ipv4config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /scenarios/kandoo/fattree/.tkenvrc: -------------------------------------------------------------------------------- 1 | # Partial OMNeT++/Tkenv config file -- see $HOME/.tkenvrc as well 2 | config default-configname {} 3 | config default-runnumber {} 4 | 5 | -------------------------------------------------------------------------------- /scenarios/kandoo/fattree/ipv4config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /scenarios/kandoo/usa/.tkenvlog: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | 3 | 4 | Tcl error: moduleinspector.cc#631: ptr0x4795770 not found 5 | while executing 6 | "error "$tag not found"" 7 | (procedure "ModuleInspector:getSubmodCoords" line 4) 8 | invoked from within 9 | "ModuleInspector:getSubmodCoords $c $modptr" 10 | (procedure "ModuleInspector:drawNextEventMarker" line 2) 11 | invoked from within 12 | "ModuleInspector:drawNextEventMarker .network.c ptr0x4795770 1" 13 | 14 | 15 | -------------------------------------------------------------------------------- /scenarios/kandoo/usa/.tkenvrc: -------------------------------------------------------------------------------- 1 | # Partial OMNeT++/Tkenv config file -- see $HOME/.tkenvrc as well 2 | config default-configname {} 3 | config default-runnumber {} 4 | 5 | -------------------------------------------------------------------------------- /scenarios/kandoo/usa/ipv4config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /scenarios/networks/Scenario_DynamicFatTree.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.scenarios.networks; 4 | 5 | import inet.common.misc.ThruputMeteringChannel; 6 | import inet.networklayer.configurator.ipv4.Ipv4NetworkConfigurator; 7 | import openflow.nodes.DynamicFatTree; 8 | import openflow.openflow.controller.Open_Flow_Controller; 9 | import openflow.utility.OpenFlowGraphAnalyzer; 10 | import openflow.utility.StaticSpanningTree; 11 | import inet.node.ethernet.Eth40G; 12 | 13 | network Scenario_DynamicFatTree 14 | { 15 | @display("bgb=842,642;"); 16 | 17 | 18 | types: 19 | channel backboneline extends ThruputMeteringChannel 20 | { 21 | delay = 1us; 22 | datarate = 40Gbps; 23 | thruputDisplayFormat = "u"; 24 | } 25 | submodules: 26 | 27 | spanningTree: StaticSpanningTree { 28 | @display("p=458,190"); 29 | } 30 | 31 | openFlowGraphAnalyzer: OpenFlowGraphAnalyzer { 32 | @display("p=458,270"); 33 | } 34 | 35 | configurator: Ipv4NetworkConfigurator { 36 | parameters: 37 | @display("p=198,190"); 38 | } 39 | 40 | open_flow_controller1: Open_Flow_Controller { 41 | @display("p=322,190"); 42 | } 43 | 44 | fat_tree: DynamicFatTree { 45 | @display("p=322,367;is=vl"); 46 | } 47 | 48 | connections allowunconnected: 49 | 50 | fat_tree.gateCPlane++ <--> backboneline <--> open_flow_controller1.ethg++; 51 | } 52 | -------------------------------------------------------------------------------- /scenarios/networks/Scenario_DynamicFatTree_HF.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.scenarios.networks; 4 | 5 | import inet.common.misc.ThruputMeteringChannel; 6 | import inet.networklayer.configurator.ipv4.Ipv4NetworkConfigurator; 7 | import inet.node.ethernet.EthernetSwitch; 8 | import openflow.hyperflow.Hyper_Flow_Synchronizer; 9 | import openflow.nodes.DynamicFatTree; 10 | import openflow.openflow.controller.Open_Flow_Controller; 11 | import openflow.utility.OpenFlowGraphAnalyzer; 12 | import openflow.utility.StaticSpanningTree; 13 | 14 | 15 | network Scenario_DynamicFatTree_HF 16 | { 17 | parameters: 18 | int numControllers = default(1); 19 | @display("bgb=842,642;"); 20 | 21 | 22 | types: 23 | channel backboneline extends ThruputMeteringChannel 24 | { 25 | delay = 1us; 26 | datarate = 40Gbps; 27 | thruputDisplayFormat = "u"; 28 | } 29 | submodules: 30 | 31 | spanningTree: StaticSpanningTree { 32 | @display("p=503,345"); 33 | } 34 | 35 | openFlowGraphAnalyzer: OpenFlowGraphAnalyzer { 36 | @display("p=637,345"); 37 | } 38 | 39 | 40 | configurator: Ipv4NetworkConfigurator { 41 | parameters: 42 | @display("p=198,345"); 43 | } 44 | 45 | open_flow_controller1: Open_Flow_Controller if numControllers >=1 { 46 | @display("p=184,226"); 47 | } 48 | 49 | open_flow_controller2: Open_Flow_Controller if numControllers >=2 { 50 | @display("p=172,110"); 51 | } 52 | 53 | open_flow_controller3: Open_Flow_Controller if numControllers >=3 { 54 | @display("p=271,39"); 55 | } 56 | 57 | 58 | open_flow_controller4: Open_Flow_Controller if numControllers >=4 { 59 | @display("p=503,110"); 60 | } 61 | 62 | open_flow_controller5: Open_Flow_Controller if numControllers >=5 { 63 | @display("p=503,226"); 64 | } 65 | 66 | hf_synchronizer: Hyper_Flow_Synchronizer { 67 | @display("p=447,39"); 68 | } 69 | 70 | fat_tree: DynamicFatTree { 71 | @display("p=358,344;is=vl"); 72 | } 73 | 74 | etherSwitch: EthernetSwitch { 75 | @display("p=358,141"); 76 | } 77 | 78 | 79 | connections allowunconnected: 80 | 81 | etherSwitch.ethg++ <--> backboneline <--> open_flow_controller1.ethg++ if numControllers >=1; 82 | etherSwitch.ethg++ <--> backboneline <--> open_flow_controller2.ethg++ if numControllers >=2; 83 | etherSwitch.ethg++ <--> backboneline <--> open_flow_controller3.ethg++ if numControllers >=3; 84 | etherSwitch.ethg++ <--> backboneline <--> open_flow_controller4.ethg++ if numControllers >=4; 85 | etherSwitch.ethg++ <--> backboneline <--> open_flow_controller5.ethg++ if numControllers >=5; 86 | 87 | etherSwitch.ethg++ <--> backboneline <--> hf_synchronizer.ethg++; 88 | 89 | fat_tree.gateCPlane++ <--> backboneline <--> etherSwitch.ethg++; 90 | } 91 | -------------------------------------------------------------------------------- /scenarios/networks/Scenario_DynamicFatTree_KN.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.scenarios.networks; 4 | 5 | import inet.common.misc.ThruputMeteringChannel; 6 | import inet.networklayer.configurator.ipv4.Ipv4NetworkConfigurator; 7 | import inet.node.ethernet.EthernetSwitch; 8 | import openflow.nodes.DynamicFatTree; 9 | import openflow.openflow.controller.Open_Flow_Controller; 10 | import openflow.utility.OpenFlowGraphAnalyzer; 11 | import openflow.utility.StaticSpanningTree; 12 | 13 | 14 | network Scenario_DynamicFatTree_KN 15 | { 16 | parameters: 17 | int numControllers = default(1); 18 | @display("bgb=842,642;"); 19 | 20 | 21 | types: 22 | channel backboneline extends ThruputMeteringChannel 23 | { 24 | delay = 1us; 25 | datarate = 40Gbps; 26 | thruputDisplayFormat = "u"; 27 | } 28 | submodules: 29 | 30 | spanningTree: StaticSpanningTree { 31 | @display("p=503,345"); 32 | } 33 | 34 | openFlowGraphAnalyzer: OpenFlowGraphAnalyzer { 35 | @display("p=637,345"); 36 | } 37 | 38 | 39 | configurator: Ipv4NetworkConfigurator { 40 | parameters: 41 | @display("p=198,345"); 42 | } 43 | 44 | open_flow_controller1: Open_Flow_Controller if numControllers >=1 { 45 | @display("p=184,226"); 46 | } 47 | 48 | open_flow_controller2: Open_Flow_Controller if numControllers >=2 { 49 | @display("p=172,110"); 50 | } 51 | 52 | open_flow_controller3: Open_Flow_Controller if numControllers >=3 { 53 | @display("p=271,39"); 54 | } 55 | 56 | 57 | open_flow_controller4: Open_Flow_Controller if numControllers >=4 { 58 | @display("p=503,110"); 59 | } 60 | 61 | open_flow_controller5: Open_Flow_Controller if numControllers >=5 { 62 | @display("p=503,226"); 63 | } 64 | 65 | root: Open_Flow_Controller { 66 | @display("p=447,39"); 67 | } 68 | 69 | fat_tree: DynamicFatTree { 70 | @display("p=358,344;is=vl"); 71 | } 72 | 73 | etherSwitch: EthernetSwitch { 74 | @display("p=358,141"); 75 | } 76 | 77 | 78 | connections allowunconnected: 79 | 80 | etherSwitch.ethg++ <--> backboneline <--> open_flow_controller1.ethg++ if numControllers >=1; 81 | etherSwitch.ethg++ <--> backboneline <--> open_flow_controller2.ethg++ if numControllers >=2; 82 | etherSwitch.ethg++ <--> backboneline <--> open_flow_controller3.ethg++ if numControllers >=3; 83 | etherSwitch.ethg++ <--> backboneline <--> open_flow_controller4.ethg++ if numControllers >=4; 84 | etherSwitch.ethg++ <--> backboneline <--> open_flow_controller5.ethg++ if numControllers >=5; 85 | 86 | etherSwitch.ethg++ <--> backboneline <--> root.ethg++; 87 | 88 | fat_tree.gateCPlane++ <--> backboneline <--> etherSwitch.ethg++; 89 | } 90 | -------------------------------------------------------------------------------- /scenarios/package.ned: -------------------------------------------------------------------------------- 1 | package openflow.scenarios; 2 | 3 | @license(LGPL); 4 | -------------------------------------------------------------------------------- /scenarios/testcases/.tkenvlog: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | 3 | 4 | Tcl error: moduleinspector.cc#631: ptr0x2f5ad50 not found 5 | while executing 6 | "error "$tag not found"" 7 | (procedure "ModuleInspector:getSubmodCoords" line 4) 8 | invoked from within 9 | "ModuleInspector:getSubmodCoords $c $modptr" 10 | (procedure "ModuleInspector:drawNextEventMarker" line 2) 11 | invoked from within 12 | "ModuleInspector:drawNextEventMarker .network.c ptr0x2f5ad50 1" 13 | 14 | 15 | ---------------------------------------------------------------------- 16 | 17 | 18 | Tcl error: moduleinspector.cc#631: ptr0x2f747d0 not found 19 | while executing 20 | "error "$tag not found"" 21 | (procedure "ModuleInspector:getSubmodCoords" line 4) 22 | invoked from within 23 | "ModuleInspector:getSubmodCoords $c $modptr" 24 | (procedure "ModuleInspector:drawNextEventMarker" line 2) 25 | invoked from within 26 | "ModuleInspector:drawNextEventMarker .network.c ptr0x2f747d0 1" 27 | 28 | 29 | -------------------------------------------------------------------------------- /scenarios/testcases/.tkenvrc: -------------------------------------------------------------------------------- 1 | # Partial OMNeT++/Tkenv config file -- see $HOME/.tkenvrc as well 2 | config default-configname {} 3 | config default-runnumber {} 4 | 5 | -------------------------------------------------------------------------------- /scenarios/testcases/Scenario_TestCase_ARPResponder.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_TestCase 3 | 4 | 5 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 6 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 7 | 8 | sim-time-limit = 1800s 9 | repeat = 1 10 | seed-set = ${repetition} 11 | 12 | **.numControllers = 1 13 | 14 | **.numClients = 1 15 | 16 | 17 | **.rtt.result-recording-modes = +vector,-stats 18 | **.queueSize.result-recording-modes = +vector,+stats 19 | **.bufferSize.result-recording-modes = +vector,+stats 20 | **.waitingTime.result-recording-modes = +vector,+stats 21 | 22 | **.packets.result-recording-modes = +count 23 | **.packetBytes.result-recording-modes = +sum 24 | **.packets*.scalar-recording = true 25 | **.packetBytes*.scalar-recording = true 26 | 27 | **.numPacketIn*.scalar-recording = true 28 | 29 | **.bufferSize*.vector-recording = true 30 | **.queueSize*.vector-recording = true 31 | **.waitingTime*.vector-recording = true 32 | 33 | **.flowTable**.scalar-recording = true 34 | 35 | **.app[*].rtt*.vector-recording = true 36 | 37 | 38 | **.controllerApps[*].*.scalar-recording = true 39 | **.app[*].numLost*.scalar-recording = true 40 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 41 | 42 | **.vector-recording = false 43 | **.scalar-recording = false 44 | 45 | 46 | **.spanningTree.startNode = 4 47 | **.highlightActivePorts = true 48 | 49 | # random ping application 50 | **.client*[*].numApps = 1 51 | **.client*[*].app[*].typename = "PingAppRandom" 52 | **.client*[*].app[*].sendInterval = 2s 53 | **.client*[*].app[*].startTime = uniform(100s,120s) 54 | 55 | 56 | 57 | #openflow params 58 | **.open_flow_switch*.OF_Switch.connectAddress = "open_flow_controller1" 59 | **.open_flow_switch*.OF_Switch.connectAt = uniform(0s,1s) 60 | **.open_flow_switch*.etherMAC[*].mac.promiscuous = true 61 | 62 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 63 | **.OF_Switch.bufferCapacity = 3712 64 | 65 | 66 | **.OF_Switch.serviceTime = 0.000035s * (${switchServiceTimeFactor= 1,130,140,150,152,154,156,158,160,170,180,190,200}) 67 | 68 | 69 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 70 | **.open_flow_controller*.serviceTime = 0.000005556s *(${controllerServiceTimeFactor= 1,130,140,150,152,154,156,158,160,170,180,190,200 !switchServiceTimeFactor}) 71 | 72 | 73 | **.open_flow_controller*.numControllerApps = 3 74 | **.open_flow_controller*.controllerApps[0].typename = "LLDPForwarding" 75 | #refer to beacon leraning switch code 76 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 5 77 | **.open_flow_controller*.controllerApps[0].ignoreArpRequests = true 78 | 79 | **.open_flow_controller*.controllerApps[1].typename = "LLDPAgent" 80 | **.open_flow_controller*.controllerApps[1].flowModIdleTimeOut = 140 81 | 82 | **.open_flow_controller*.controllerApps[2].typename = "ARPResponder" 83 | 84 | 85 | # NIC configuration 86 | **.ppp[*].queue.packetCapacity = 10 # in routers 87 | **.open_flow_switch*.tcp.mss = 800 88 | 89 | 90 | #linux mint 15 std value 91 | **.arp.cacheTimeout = 60s 92 | 93 | # configure control and data plane interfaces separately 94 | *.configurator.config = xmldoc("ipv4config.xml") 95 | -------------------------------------------------------------------------------- /scenarios/testcases/Scenario_TestCase_BalancedMinHop.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_TestCase 3 | 4 | 5 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 6 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 7 | 8 | sim-time-limit = 1800s 9 | repeat = 1 10 | seed-set = ${repetition} 11 | 12 | **.numControllers = 1 13 | 14 | **.numClients = 1 15 | 16 | 17 | **.rtt.result-recording-modes = +vector,-stats 18 | **.queueSize.result-recording-modes = +vector,+stats 19 | **.bufferSize.result-recording-modes = +vector,+stats 20 | **.waitingTime.result-recording-modes = +vector,+stats 21 | 22 | **.packets.result-recording-modes = +count 23 | **.packetBytes.result-recording-modes = +sum 24 | **.packets*.scalar-recording = true 25 | **.packetBytes*.scalar-recording = true 26 | 27 | **.numPacketIn*.scalar-recording = true 28 | 29 | **.bufferSize*.vector-recording = true 30 | **.queueSize*.vector-recording = true 31 | **.waitingTime*.vector-recording = true 32 | 33 | **.flowTable**.scalar-recording = true 34 | 35 | **.app[*].rtt*.vector-recording = true 36 | 37 | 38 | **.controllerApps[*].*.scalar-recording = true 39 | **.app[*].numLost*.scalar-recording = true 40 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 41 | 42 | **.vector-recording = false 43 | **.scalar-recording = false 44 | 45 | 46 | **.spanningTree.startNode = 4 47 | **.highlightActivePorts = true 48 | 49 | # random ping application 50 | **.client*[*].numApps = 1 51 | **.client*[*].app[*].typename = "PingAppRandom" 52 | **.client*[*].app[*].sendInterval = 2s 53 | **.client*[*].app[*].startTime = uniform(100s,120s) 54 | 55 | 56 | 57 | #openflow params 58 | **.open_flow_switch*.OF_Switch.connectAddress = "open_flow_controller1" 59 | **.open_flow_switch*.OF_Switch.connectAt = uniform(0s,1s) 60 | **.open_flow_switch*.etherMAC[*].mac.promiscuous = true 61 | 62 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 63 | **.OF_Switch.bufferCapacity = 3712 64 | 65 | **.OF_Switch.serviceTime = 0.000035s * (${switchServiceTimeFactor= 1,130,140,150,152,154,156,158,160,170,180,190,200}) 66 | 67 | 68 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 69 | **.open_flow_controller*.serviceTime = 0.000005556s *(${controllerServiceTimeFactor= 1,130,140,150,152,154,156,158,160,170,180,190,200 !switchServiceTimeFactor}) 70 | 71 | 72 | 73 | **.open_flow_controller*.numControllerApps = 2 74 | **.open_flow_controller*.controllerApps[0].typename = "LLDPBalancedMinHop" 75 | #refer to beacon leraning switch code 76 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 5 77 | **.open_flow_controller*.controllerApps[0].dropIfNoRouteFound = false 78 | 79 | **.open_flow_controller*.controllerApps[1].typename = "LLDPAgent" 80 | **.open_flow_controller*.controllerApps[1].flowModIdleTimeOut = 140 81 | 82 | 83 | # NIC configuration 84 | **.ppp[*].queue.packetCapacity = 10 # in routers 85 | **.open_flow_switch*.tcp.mss = 800 86 | 87 | 88 | #linux mint 15 std value 89 | **.arp.cacheTimeout = 60s 90 | 91 | # configure control and data plane interfaces separately 92 | *.configurator.config = xmldoc("ipv4config.xml") 93 | -------------------------------------------------------------------------------- /scenarios/testcases/Scenario_TestCase_Forwarding.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_TestCase 3 | 4 | 5 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 6 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 7 | 8 | sim-time-limit = 1800s 9 | repeat = 1 10 | seed-set = ${repetition} 11 | 12 | **.numControllers = 1 13 | 14 | **.numClients = 1 15 | 16 | **.rtt.result-recording-modes = +vector,-stats 17 | **.queueSize.result-recording-modes = +vector,+stats 18 | **.bufferSize.result-recording-modes = +vector,+stats 19 | **.waitingTime.result-recording-modes = +vector,+stats 20 | 21 | **.packets.result-recording-modes = +count 22 | **.packetBytes.result-recording-modes = +sum 23 | **.packets*.scalar-recording = true 24 | **.packetBytes*.scalar-recording = true 25 | 26 | **.numPacketIn*.scalar-recording = true 27 | 28 | **.bufferSize*.vector-recording = true 29 | **.queueSize*.vector-recording = true 30 | **.waitingTime*.vector-recording = true 31 | 32 | **.flowTable**.scalar-recording = true 33 | 34 | **.app[*].rtt*.vector-recording = true 35 | 36 | 37 | **.controllerApps[*].*.scalar-recording = true 38 | **.app[*].numLost*.scalar-recording = true 39 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 40 | 41 | **.vector-recording = false 42 | **.scalar-recording = false 43 | 44 | 45 | **.spanningTree.startNode = 4 46 | **.highlightActivePorts = true 47 | 48 | # random ping application 49 | **.client*[*].numApps = 1 50 | **.client*[*].app[*].typename = "PingAppRandom" 51 | **.client*[*].app[*].sendInterval = 2s 52 | **.client*[*].app[*].startTime = uniform(100s,120s) 53 | 54 | 55 | 56 | #openflow params 57 | **.open_flow_switch*.OF_Switch.connectAddress = "open_flow_controller1" 58 | **.open_flow_switch*.OF_Switch.connectAt = uniform(0s,1s) 59 | **.open_flow_switch*.etherMAC[*].mac.promiscuous = true 60 | 61 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 62 | **.OF_Switch.bufferCapacity = 3712 63 | 64 | 65 | **.OF_Switch.serviceTime = 0.000035s * (${switchServiceTimeFactor= 1,130,140,150,152,154,156,158,160,170,180,190,200}) 66 | 67 | 68 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 69 | **.open_flow_controller*.serviceTime = 0.000005556s *(${controllerServiceTimeFactor= 1,130,140,150,152,154,156,158,160,170,180,190,200 !switchServiceTimeFactor}) 70 | 71 | 72 | **.open_flow_controller*.numControllerApps = 2 73 | **.open_flow_controller*.controllerApps[0].typename = "LLDPForwarding" 74 | #refer to beacon leraning switch code 75 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 5 76 | **.open_flow_controller*.controllerApps[0].dropIfNoRouteFound = false 77 | 78 | **.open_flow_controller*.controllerApps[1].typename = "LLDPAgent" 79 | **.open_flow_controller*.controllerApps[1].flowModIdleTimeOut = 140 80 | 81 | 82 | # NIC configuration 83 | **.ppp[*].queue.packetCapacity = 10 # in routers 84 | **.open_flow_switch*.tcp.mss = 800 85 | 86 | 87 | #linux mint 15 std value 88 | **.arp.cacheTimeout = 60s 89 | 90 | # configure control and data plane interfaces separately 91 | *.configurator.config = xmldoc("ipv4config.xml") 92 | -------------------------------------------------------------------------------- /scenarios/testcases/Scenario_TestCase_LLDP.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_TestCase 3 | 4 | 5 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 6 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 7 | 8 | sim-time-limit = 1800s 9 | repeat = 1 10 | seed-set = ${repetition} 11 | 12 | **.numControllers = 1 13 | 14 | **.numClients = 1 15 | 16 | 17 | **.rtt.result-recording-modes = +vector,-stats 18 | **.queueSize.result-recording-modes = +vector,+stats 19 | **.bufferSize.result-recording-modes = +vector,+stats 20 | **.waitingTime.result-recording-modes = +vector,+stats 21 | 22 | **.packets.result-recording-modes = +count 23 | **.packetBytes.result-recording-modes = +sum 24 | **.packets*.scalar-recording = true 25 | **.packetBytes*.scalar-recording = true 26 | 27 | **.numPacketIn*.scalar-recording = true 28 | 29 | **.bufferSize*.vector-recording = true 30 | **.queueSize*.vector-recording = true 31 | **.waitingTime*.vector-recording = true 32 | 33 | **.flowTable**.scalar-recording = true 34 | 35 | **.app[*].rtt*.vector-recording = true 36 | 37 | 38 | **.controllerApps[*].*.scalar-recording = true 39 | **.app[*].numLost*.scalar-recording = true 40 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 41 | 42 | **.vector-recording = false 43 | **.scalar-recording = false 44 | 45 | 46 | **.spanningTree.startNode = 4 47 | **.highlightActivePorts = true 48 | 49 | 50 | 51 | 52 | #openflow params 53 | **.open_flow_switch*.OF_Switch.connectAddress = "open_flow_controller1" 54 | **.open_flow_switch*.OF_Switch.connectAt = uniform(0s,1s) 55 | **.open_flow_switch*.etherMAC[*].mac.promiscuous = true 56 | 57 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 58 | **.OF_Switch.bufferCapacity = 3712 59 | 60 | 61 | **.OF_Switch.serviceTime = 0.000035s * (${switchServiceTimeFactor= 1,130,140,150,152,154,156,158,160,170,180,190,200}) 62 | 63 | 64 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 65 | **.open_flow_controller*.serviceTime = 0.000005556s *(${controllerServiceTimeFactor= 1,130,140,150,152,154,156,158,160,170,180,190,200 !switchServiceTimeFactor}) 66 | 67 | 68 | **.open_flow_controller*.numControllerApps = 1 69 | 70 | **.open_flow_controller*.controllerApps[0].typename = "LLDPAgent" 71 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 140 72 | 73 | 74 | # NIC configuration 75 | **.ppp[*].queue.packetCapacity = 10 # in routers 76 | **.open_flow_switch*.tcp.mss = 800 77 | 78 | 79 | #linux mint 15 std value 80 | **.arp.cacheTimeout = 60s 81 | 82 | # configure control and data plane interfaces separately 83 | *.configurator.config = xmldoc("ipv4config.xml") 84 | -------------------------------------------------------------------------------- /scenarios/testcases/Scenario_TestCase_LearningSwitch.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_TestCase 3 | 4 | 5 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 6 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 7 | 8 | sim-time-limit = 1800s 9 | repeat = 1 10 | seed-set = ${repetition} 11 | 12 | **.numControllers = 1 13 | 14 | **.numClients = 1 15 | 16 | 17 | **.rtt.result-recording-modes = +vector,-stats 18 | **.queueSize.result-recording-modes = +vector,+stats 19 | **.bufferSize.result-recording-modes = +vector,+stats 20 | **.waitingTime.result-recording-modes = +vector,+stats 21 | 22 | **.packets.result-recording-modes = +count 23 | **.packetBytes.result-recording-modes = +sum 24 | **.packets*.scalar-recording = true 25 | **.packetBytes*.scalar-recording = true 26 | 27 | **.numPacketIn*.scalar-recording = true 28 | 29 | **.bufferSize*.vector-recording = true 30 | **.queueSize*.vector-recording = true 31 | **.waitingTime*.vector-recording = true 32 | 33 | **.flowTable**.scalar-recording = true 34 | 35 | **.app[*].rtt*.vector-recording = true 36 | 37 | 38 | **.controllerApps[*].*.scalar-recording = true 39 | **.app[*].numLost*.scalar-recording = true 40 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 41 | 42 | **.vector-recording = false 43 | **.scalar-recording = false 44 | 45 | 46 | **.spanningTree.startNode = 4 47 | **.highlightActivePorts = true 48 | 49 | # random ping application 50 | **.client*[*].numApps = 1 51 | **.client*[*].app[*].typename = "PingAppRandom" 52 | **.client*[*].app[*].sendInterval = 2s 53 | **.client*[*].app[*].startTime = uniform(100s,120s) 54 | 55 | 56 | 57 | #openflow params 58 | **.open_flow_switch*.OF_Switch.connectAddress = "open_flow_controller1" 59 | **.open_flow_switch*.OF_Switch.connectAt = uniform(0s,1s) 60 | **.open_flow_switch*.etherMAC[*].mac.promiscuous = true 61 | 62 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 63 | **.OF_Switch.bufferCapacity = 3712 64 | 65 | **.OF_Switch.serviceTime = 0.000035s * (${switchServiceTimeFactor= 1,130,140,150,152,154,156,158,160,170,180,190,200}) 66 | 67 | 68 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 69 | **.open_flow_controller*.serviceTime = 0.000005556s *(${controllerServiceTimeFactor= 1,130,140,150,152,154,156,158,160,170,180,190,200 !switchServiceTimeFactor}) 70 | 71 | 72 | 73 | **.open_flow_controller*.numControllerApps = 1 74 | **.open_flow_controller*.controllerApps[0].typename = "LearningSwitch" 75 | 76 | 77 | # NIC configuration 78 | **.ppp[*].queue.packetCapacity = 10 # in routers 79 | **.open_flow_switch*.tcp.mss = 800 80 | 81 | 82 | #linux mint 15 std value 83 | **.arp.cacheTimeout = 60s 84 | 85 | # configure control and data plane interfaces separately 86 | *.configurator.config = xmldoc("ipv4config.xml") 87 | -------------------------------------------------------------------------------- /scenarios/testcases/ipv4config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /scenarios/topologyzoo/.tkenvrc: -------------------------------------------------------------------------------- 1 | # Partial OMNeT++/Tkenv config file -- see $HOME/.tkenvrc as well 2 | config default-configname {cfg1} 3 | config default-runnumber {0} 4 | 5 | -------------------------------------------------------------------------------- /scenarios/topologyzoo/ipv4config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /scenarios/usa/.tkenvlog: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | 3 | 4 | Tcl error: moduleinspector.cc#631: ptr0x3c331a0 not found 5 | while executing 6 | "error "$tag not found"" 7 | (procedure "ModuleInspector:getSubmodCoords" line 4) 8 | invoked from within 9 | "ModuleInspector:getSubmodCoords $c $modptr" 10 | (procedure "ModuleInspector:drawNextEventMarker" line 2) 11 | invoked from within 12 | "ModuleInspector:drawNextEventMarker .network.c ptr0x3c331a0 1" 13 | 14 | 15 | -------------------------------------------------------------------------------- /scenarios/usa/.tkenvrc: -------------------------------------------------------------------------------- 1 | # Partial OMNeT++/Tkenv config file -- see $HOME/.tkenvrc as well 2 | config default-configname {} 3 | config default-runnumber {} 4 | 5 | -------------------------------------------------------------------------------- /scenarios/usa/Scenario_USA_ARP_Ping_Drop_Clients_Packets.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_USA 3 | debug-on-errors = true 4 | 5 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 6 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 7 | 8 | sim-time-limit = 1800s 9 | repeat = 4 10 | seed-set = ${repetition} 11 | 12 | 13 | **.numClients = (${numOfClients= 1,2,3,4,5}) 14 | 15 | 16 | **.rtt.result-recording-modes = +vector,-stats 17 | **.queueSize.result-recording-modes = +vector,+stats 18 | **.bufferSize.result-recording-modes = +vector,+stats 19 | **.waitingTime.result-recording-modes = +vector,+stats 20 | 21 | **.packets.result-recording-modes = +count 22 | **.packetBytes.result-recording-modes = +sum 23 | **.packets*.scalar-recording = true 24 | **.packetBytes*.scalar-recording = true 25 | 26 | **.numPacketIn*.scalar-recording = true 27 | 28 | **.bufferSize*.vector-recording = true 29 | **.queueSize*.vector-recording = true 30 | **.waitingTime*.vector-recording = true 31 | 32 | **.flowTable**.scalar-recording = true 33 | 34 | **.nodeInNumPaths**.scalar-recording = true 35 | **.avgPathLength.scalar-recording = true 36 | **.minPathLength.scalar-recording = true 37 | **.maxPathLength.scalar-recording = true 38 | **.numClients.scalar-recording = true 39 | **.numPaths.scalar-recording = true 40 | 41 | **.app[*].rtt*.vector-recording = true 42 | 43 | 44 | **.controllerApps[*].*.scalar-recording = true 45 | **.app[*].numLost*.scalar-recording = true 46 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 47 | 48 | **.vector-recording = false 49 | **.scalar-recording = false 50 | 51 | 52 | **.spanningTree.NodeType = "openflow.nodes.Open_Flow_Domain" 53 | **.spanningTree.startNode = 4 54 | **.highlightActivePorts = true 55 | 56 | # random ping application 57 | **.client[*].numApps = 1 58 | **.client[*].app[*].typename = "PingAppRandom" 59 | **.client[*].app[*].sendInterval = (${pingInterval= 0.25,0.5,1,1.5,2}s) 60 | **.client[*].app[*].startTime = uniform(100s,120s) 61 | 62 | 63 | 64 | #openflow params 65 | **.open_flow_switch.OF_Switch.connectAddress = "open_flow_controller1" 66 | **.open_flow_switch.OF_Switch.connectAt = uniform(0s,1s) 67 | **.open_flow_switch.etherMAC[*].mac.promiscuous = true 68 | 69 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 70 | **.OF_Switch.bufferCapacity = 3712 71 | 72 | 73 | **.OF_Switch.serviceTime = 0.000035s 74 | 75 | 76 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 77 | **.open_flow_controller*.serviceTime = 0.000005556s 78 | 79 | 80 | **.open_flow_controller*.numControllerApps = 3 81 | **.open_flow_controller*.controllerApps[0].typename = "LLDPForwarding" 82 | #refer to beacon leraning switch code 83 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 5 84 | **.open_flow_controller*.controllerApps[0].dropIfNoRouteFound = true 85 | **.open_flow_controller*.controllerApps[0].ignoreArpRequests = true 86 | 87 | **.open_flow_controller*.controllerApps[1].typename = "LLDPAgent" 88 | **.open_flow_controller*.controllerApps[1].flowModIdleTimeOut = 140 89 | 90 | **.open_flow_controller*.controllerApps[2].typename = "ARPResponder" 91 | 92 | 93 | 94 | # NIC configuration 95 | **.ppp[*].queue.packetCapacity = 10 # in routers 96 | **.open_flow_switch*.tcp.mss = 800 97 | 98 | 99 | #linux mint 15 std value 100 | **.arp.cacheTimeout = 60s 101 | 102 | 103 | # configure control and data plane interfaces separately 104 | *.configurator.config = xmldoc("ipv4config.xml") 105 | -------------------------------------------------------------------------------- /scenarios/usa/Scenario_USA_ARP_Ping_Drop_Load.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_USA 3 | debug-on-errors = true 4 | 5 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 6 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 7 | 8 | sim-time-limit = 1800s 9 | repeat = 4 10 | seed-set = ${repetition} 11 | 12 | 13 | **.numClients = 2 14 | 15 | 16 | **.rtt.result-recording-modes = +vector,-stats 17 | **.queueSize.result-recording-modes = +vector,+stats 18 | **.bufferSize.result-recording-modes = +vector,+stats 19 | **.waitingTime.result-recording-modes = +vector,+stats 20 | 21 | **.packets.result-recording-modes = +count 22 | **.packetBytes.result-recording-modes = +sum 23 | **.packets*.scalar-recording = true 24 | **.packetBytes*.scalar-recording = true 25 | 26 | **.numPacketIn*.scalar-recording = true 27 | 28 | **.bufferSize*.vector-recording = true 29 | **.queueSize*.vector-recording = true 30 | **.waitingTime*.vector-recording = true 31 | 32 | **.flowTable**.scalar-recording = true 33 | 34 | **.nodeInNumPaths**.scalar-recording = true 35 | **.avgPathLength.scalar-recording = true 36 | **.minPathLength.scalar-recording = true 37 | **.maxPathLength.scalar-recording = true 38 | **.numClients.scalar-recording = true 39 | **.numPaths.scalar-recording = true 40 | 41 | **.app[*].rtt*.vector-recording = true 42 | 43 | 44 | **.controllerApps[*].*.scalar-recording = true 45 | **.app[*].numLost*.scalar-recording = true 46 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 47 | 48 | **.vector-recording = false 49 | **.scalar-recording = false 50 | 51 | 52 | **.spanningTree.NodeType = "openflow.nodes.Open_Flow_Domain" 53 | **.spanningTree.startNode = 4 54 | **.highlightActivePorts = true 55 | 56 | # random ping application 57 | **.client[*].numApps = 1 58 | **.client[*].app[*].typename = "PingAppRandom" 59 | **.client[*].app[*].sendInterval = 1s 60 | **.client[*].app[*].startTime = uniform(100s,120s) 61 | 62 | 63 | 64 | #openflow params 65 | **.open_flow_switch.OF_Switch.connectAddress = "open_flow_controller1" 66 | **.open_flow_switch.OF_Switch.connectAt = uniform(0s,1s) 67 | **.open_flow_switch.etherMAC[*].mac.promiscuous = true 68 | 69 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 70 | **.OF_Switch.bufferCapacity = 3712 71 | 72 | 73 | **.OF_Switch.serviceTime = 0.000035s 74 | 75 | 76 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 77 | **.open_flow_controller*.serviceTime = 0.000005556s * (${cstFaktor= 920.72095397,1227.6279386267,1534.5349232834,1841.4419079401,2148.3488925967}) 78 | 79 | 80 | **.open_flow_controller*.numControllerApps = 3 81 | **.open_flow_controller*.controllerApps[0].typename = "LLDPForwarding" 82 | #refer to beacon leraning switch code 83 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 5 84 | **.open_flow_controller*.controllerApps[0].dropIfNoRouteFound = true 85 | **.open_flow_controller*.controllerApps[0].ignoreArpRequests = true 86 | 87 | **.open_flow_controller*.controllerApps[1].typename = "LLDPAgent" 88 | **.open_flow_controller*.controllerApps[1].flowModIdleTimeOut = 140 89 | 90 | **.open_flow_controller*.controllerApps[2].typename = "ARPResponder" 91 | 92 | 93 | 94 | # NIC configuration 95 | **.ppp[*].queue.packetCapacity = 10 # in routers 96 | **.open_flow_switch*.tcp.mss = 800 97 | 98 | 99 | #linux mint 15 std value 100 | **.arp.cacheTimeout = 60s 101 | 102 | 103 | # configure control and data plane interfaces separately 104 | *.configurator.config = xmldoc("ipv4config.xml") 105 | -------------------------------------------------------------------------------- /scenarios/usa/Scenario_USA_Ping_Drop.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_USA 3 | debug-on-errors = true 4 | 5 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 6 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 7 | 8 | sim-time-limit = 1800s 9 | repeat = 1 10 | seed-set = ${repetition} 11 | 12 | 13 | **.numClients = 1 14 | 15 | 16 | **.rtt.result-recording-modes = +vector,-stats 17 | **.queueSize.result-recording-modes = +vector,+stats 18 | **.bufferSize.result-recording-modes = +vector,+stats 19 | **.waitingTime.result-recording-modes = +vector,+stats 20 | 21 | **.nodeInNumPaths**.scalar-recording = true 22 | **.avgPathLength.scalar-recording = true 23 | **.minPathLength.scalar-recording = true 24 | **.maxPathLength.scalar-recording = true 25 | **.numClients.scalar-recording = true 26 | **.numPaths.scalar-recording = true 27 | 28 | **.flowTable**.scalar-recording = true 29 | 30 | **.packets.result-recording-modes = +count 31 | **.packetBytes.result-recording-modes = +sum 32 | **.packets*.scalar-recording = true 33 | **.packetBytes*.scalar-recording = true 34 | 35 | **.numPacketIn*.scalar-recording = true 36 | 37 | **.bufferSize*.vector-recording = true 38 | **.queueSize*.vector-recording = true 39 | **.waitingTime*.vector-recording = true 40 | 41 | **.app[*].rtt*.vector-recording = true 42 | 43 | 44 | **.controllerApps[*].*.scalar-recording = true 45 | **.app[*].numLost*.scalar-recording = true 46 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 47 | 48 | **.vector-recording = false 49 | **.scalar-recording = false 50 | 51 | 52 | **.spanningTree.NodeType = "openflow.nodes.Open_Flow_Domain" 53 | **.spanningTree.startNode = 4 54 | **.highlightActivePorts = true 55 | 56 | # random ping application 57 | **.client[*].numApps = 1 58 | **.client[*].app[*].typename = "PingAppRandom" 59 | **.client[*].app[*].sendInterval = 2s 60 | **.client[*].app[*].startTime = uniform(100s,120s) 61 | 62 | 63 | 64 | #openflow params 65 | **.open_flow_switch.OF_Switch.connectAddress = "open_flow_controller1" 66 | **.open_flow_switch.OF_Switch.connectAt = uniform(0s,1s) 67 | **.open_flow_switch.etherMAC[*].mac.promiscuous = true 68 | 69 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 70 | **.OF_Switch.bufferCapacity = 3712 71 | 72 | 73 | **.OF_Switch.serviceTime = 0.000035s * (${switchServiceTimeFactor= 25,50,75,100,125,150,175,200,225,250,275,300}) 74 | 75 | 76 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 77 | **.open_flow_controller*.serviceTime = 0.000005556s *(${controllerServiceTimeFactor= 25,50,75,100,125,150,175,200,225,250,275,300 !switchServiceTimeFactor}) 78 | 79 | 80 | 81 | **.open_flow_controller*.numControllerApps = 2 82 | **.open_flow_controller*.controllerApps[0].typename = "LLDPForwarding" 83 | **.open_flow_controller*.controllerApps[0].printMibGraph = true 84 | #refer to beacon leraning switch code 85 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 5 86 | **.open_flow_controller*.controllerApps[0].dropIfNoRouteFound = true 87 | 88 | **.open_flow_controller*.controllerApps[1].typename = "LLDPAgent" 89 | **.open_flow_controller*.controllerApps[1].flowModIdleTimeOut = 140 90 | 91 | 92 | 93 | 94 | 95 | # NIC configuration 96 | **.ppp[*].queue.packetCapacity = 10 # in routers 97 | **.open_flow_switch*.tcp.mss = 800 98 | 99 | 100 | #linux mint 15 std value 101 | **.arp.cacheTimeout = 60s 102 | 103 | 104 | # configure control and data plane interfaces separately 105 | *.configurator.config = xmldoc("ipv4config.xml") 106 | -------------------------------------------------------------------------------- /scenarios/usa/Scenario_USA_Ping_Drop_Clients_Packets.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_USA 3 | debug-on-errors = true 4 | 5 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 6 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 7 | 8 | sim-time-limit = 1800s 9 | repeat = 4 10 | seed-set = ${repetition} 11 | 12 | 13 | **.numClients = (${numOfClients= 1,2,3,4,5}) 14 | 15 | 16 | **.rtt.result-recording-modes = +vector,-stats 17 | **.queueSize.result-recording-modes = +vector,+stats 18 | **.bufferSize.result-recording-modes = +vector,+stats 19 | **.waitingTime.result-recording-modes = +vector,+stats 20 | 21 | **.packets.result-recording-modes = +count 22 | **.packetBytes.result-recording-modes = +sum 23 | **.packets*.scalar-recording = true 24 | **.packetBytes*.scalar-recording = true 25 | 26 | **.numPacketIn*.scalar-recording = true 27 | 28 | **.bufferSize*.vector-recording = true 29 | **.queueSize*.vector-recording = true 30 | **.waitingTime*.vector-recording = true 31 | 32 | **.flowTable**.scalar-recording = true 33 | 34 | **.nodeInNumPaths**.scalar-recording = true 35 | **.avgPathLength.scalar-recording = true 36 | **.minPathLength.scalar-recording = true 37 | **.maxPathLength.scalar-recording = true 38 | **.numClients.scalar-recording = true 39 | **.numPaths.scalar-recording = true 40 | 41 | **.app[*].rtt*.vector-recording = true 42 | 43 | 44 | **.controllerApps[*].*.scalar-recording = true 45 | **.app[*].numLost*.scalar-recording = true 46 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 47 | 48 | **.vector-recording = false 49 | **.scalar-recording = false 50 | 51 | 52 | **.spanningTree.NodeType = "openflow.nodes.Open_Flow_Domain" 53 | **.spanningTree.startNode = 4 54 | **.highlightActivePorts = true 55 | 56 | # random ping application 57 | **.client[*].numApps = 1 58 | **.client[*].app[*].typename = "PingAppRandom" 59 | **.client[*].app[*].sendInterval = (${pingInterval= 0.25,0.5,1,1.5,2}s) 60 | **.client[*].app[*].startTime = uniform(100s,120s) 61 | 62 | 63 | 64 | #openflow params 65 | **.open_flow_switch.OF_Switch.connectAddress = "open_flow_controller1" 66 | **.open_flow_switch.OF_Switch.connectAt = uniform(0s,1s) 67 | **.open_flow_switch.etherMAC[*].mac.promiscuous = true 68 | 69 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 70 | **.OF_Switch.bufferCapacity = 3712 71 | 72 | 73 | **.OF_Switch.serviceTime = 0.000035s 74 | 75 | 76 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 77 | **.open_flow_controller*.serviceTime = 0.000005556s 78 | 79 | 80 | **.open_flow_controller*.numControllerApps = 2 81 | **.open_flow_controller*.controllerApps[0].typename = "LLDPForwarding" 82 | #refer to beacon leraning switch code 83 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 5 84 | **.open_flow_controller*.controllerApps[0].dropIfNoRouteFound = true 85 | 86 | **.open_flow_controller*.controllerApps[1].typename = "LLDPAgent" 87 | **.open_flow_controller*.controllerApps[1].flowModIdleTimeOut = 140 88 | 89 | 90 | 91 | 92 | # NIC configuration 93 | **.ppp[*].queue.packetCapacity = 10 # in routers 94 | **.open_flow_switch*.tcp.mss = 800 95 | 96 | 97 | #linux mint 15 std value 98 | **.arp.cacheTimeout = 60s 99 | 100 | 101 | # configure control and data plane interfaces separately 102 | *.configurator.config = xmldoc("ipv4config.xml") 103 | -------------------------------------------------------------------------------- /scenarios/usa/Scenario_USA_Ping_Flood.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | network = openflow.scenarios.networks.Scenario_USA 3 | 4 | output-vector-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.vec 5 | output-scalar-file = ${resultdir}/${inifile}/${inifile}-${runnumber}.sca 6 | 7 | sim-time-limit = 1800s 8 | repeat = 1 9 | seed-set = ${repetition} 10 | 11 | 12 | **.numClients = 1 13 | 14 | 15 | **.rtt.result-recording-modes = +vector,-stats 16 | **.queueSize.result-recording-modes = +vector,+stats 17 | **.bufferSize.result-recording-modes = +vector,+stats 18 | **.waitingTime.result-recording-modes = +vector,+stats 19 | 20 | **.nodeInNumPaths**.scalar-recording = true 21 | **.avgPathLength.scalar-recording = true 22 | **.minPathLength.scalar-recording = true 23 | **.maxPathLength.scalar-recording = true 24 | **.numClients.scalar-recording = true 25 | **.numPaths.scalar-recording = true 26 | 27 | **.flowTable**.scalar-recording = true 28 | 29 | **.packets.result-recording-modes = +count 30 | **.packetBytes.result-recording-modes = +sum 31 | **.packets*.scalar-recording = true 32 | **.packetBytes*.scalar-recording = true 33 | 34 | **.numPacketIn*.scalar-recording = true 35 | 36 | **.bufferSize*.vector-recording = true 37 | **.queueSize*.vector-recording = true 38 | **.waitingTime*.vector-recording = true 39 | 40 | **.app[*].rtt*.vector-recording = true 41 | 42 | 43 | **.controllerApps[*].*.scalar-recording = true 44 | **.app[*].numLost*.scalar-recording = true 45 | **.app[*].numOutOfOrderArrivals*.scalar-recording = true 46 | 47 | **.vector-recording = false 48 | **.scalar-recording = false 49 | 50 | 51 | **.spanningTree.NodeType = "openflow.nodes.Open_Flow_Domain" 52 | **.spanningTree.startNode = 4 53 | **.highlightActivePorts = true 54 | 55 | # random ping application 56 | **.client[*].numApps = 1 57 | **.client[*].app[*].typename = "PingAppRandom" 58 | **.client[*].app[*].sendInterval = 2s 59 | **.client[*].app[*].startTime = uniform(100s,120s) 60 | 61 | 62 | 63 | #openflow params 64 | **.open_flow_switch.OF_Switch.connectAddress = "open_flow_controller1" 65 | **.open_flow_switch.OF_Switch.connectAt = uniform(0s,1s) 66 | **.open_flow_switch.etherMAC[*].mac.promiscuous = true 67 | 68 | # 404bytes see imix and buffer size of 1.5mb see hp switch 1500000/404 69 | **.OF_Switch.bufferCapacity = 3712 70 | 71 | 72 | **.OF_Switch.serviceTime = 0.000035s * (${switchServiceTimeFactor= 25,50,75,100,125,150,175,200,225,250,275,300}) 73 | 74 | 75 | #1800 00 requests per second on 8xcores 8xthreads and 32 switches (hotice2012-final) 76 | **.open_flow_controller*.serviceTime = 0.000005556s *(${controllerServiceTimeFactor= 25,50,75,100,125,150,175,200,225,250,275,300 !switchServiceTimeFactor}) 77 | 78 | 79 | 80 | **.open_flow_controller*.numControllerApps = 2 81 | **.open_flow_controller*.controllerApps[0].typename = "LLDPForwarding" 82 | #refer to beacon leraning switch code 83 | **.open_flow_controller*.controllerApps[0].flowModIdleTimeOut = 5 84 | **.open_flow_controller*.controllerApps[0].dropIfNoRouteFound = false 85 | 86 | **.open_flow_controller*.controllerApps[1].typename = "LLDPAgent" 87 | **.open_flow_controller*.controllerApps[1].flowModIdleTimeOut = 140 88 | 89 | 90 | 91 | 92 | 93 | # NIC configuration 94 | **.ppp[*].queue.packetCapacity = 10 # in routers 95 | **.open_flow_switch*.tcp.mss = 800 96 | 97 | 98 | #linux mint 15 std value 99 | **.arp.cacheTimeout = 60s 100 | 101 | 102 | # configure control and data plane interfaces separately 103 | *.configurator.config = xmldoc("ipv4config.xml") 104 | -------------------------------------------------------------------------------- /scenarios/usa/ipv4config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /setenv: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S sh -c "echo >&2 \"Error: You are running this script instead of sourcing it. Make sure to use it as 'source setenv' or '. setenv', otherwise its settings won't take effect.\"; exit 1" 2 | 3 | # first argument can be (e.g. 'source setenv -q'): 4 | # -q : do not show banner text on configuration success 5 | # -r : remove an already configured environment 6 | 7 | # Get the directory where this script reside using a trick (works differently on bash and zsh) 8 | # On bash, the current script's name is in 'BASH_SOURCE[0]' 9 | if [ "$BASH_VERSION" != "" ]; then # for BASH 10 | dir=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd) 11 | elif [ "$ZSH_VERSION" != "" ]; then # on zsh the script name is in '$0' 12 | dir=$(cd $(dirname $0) && pwd) 13 | else # on any other SH compatible shell we assume that the current working directory is the OMNeT++ root directory 14 | dir=$(pwd) 15 | fi 16 | 17 | # check if dir is really pointing to an omnet++ installation dir 18 | if [ ! -d $dir/src/openflow ]; then 19 | echo "Error: '$dir' does not look like an OpenFlow root directory" 20 | return 1 21 | fi 22 | 23 | # remove previous environment to prevent the accumulation of path elements 24 | if [ -n "$OPENFLOW_ROOT" ]; then 25 | if [ "$1" = "-r" ]; then 26 | echo "Removed previous environment for '$OPENFLOW_ROOT'." 27 | dir= 28 | else 29 | echo "Warning: overwriting previous environment for '$OPENFLOW_ROOT'." 30 | fi 31 | export PATH=${PATH#$OPENFLOW_ROOT/bin:} 32 | export OPENFLOW_ROOT= 33 | fi 34 | 35 | # do not continue if removal was requested 36 | if [ "$1" = "-r" ]; then 37 | return 0 38 | fi 39 | 40 | export OPENFLOW_ROOT=$dir 41 | dir= 42 | 43 | if [ "$1" != "-q" ]; then 44 | echo "Environment for Openflow in directory '$OPENFLOW_ROOT' is ready." 45 | 46 | if [ ! -f $OPENFLOW_ROOT/src/Makefile ]; then 47 | cat <<__END__ 48 | 49 | Type "make makefiles" and then "make" to build OpenFlow. 50 | __END__ 51 | fi 52 | fi 53 | 54 | # source user specific script if present 55 | if [ -f "$OPENFLOW_ROOT/setenv_local" ] ; then 56 | source $OPENFLOW_ROOT/setenv_local 57 | fi 58 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/ARPResponder.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ARPRESPONDER_H_ 3 | #define ARPRESPONDER_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/AbstractControllerApp.h" 7 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 8 | #include "openflow/openflow/controller/Switch_Info.h" 9 | #include "openflow/messages/OFP_Features_Reply_m.h" 10 | #include "openflow/messages/OFP_Packet_In_m.h" 11 | #include "inet/networklayer/arp/ipv4/ArpPacket_m.h" 12 | 13 | namespace openflow{ 14 | 15 | class ARPResponder:public AbstractControllerApp { 16 | 17 | 18 | public: 19 | ARPResponder(); 20 | ~ARPResponder(); 21 | virtual void finish() override; 22 | 23 | bool addEntry(std::string srcIp, MacAddress srcMac); 24 | 25 | protected: 26 | 27 | virtual void handleStartOperation(LifecycleOperation *operation) override {} 28 | 29 | virtual void handleStopOperation(LifecycleOperation *operation) override {} 30 | 31 | virtual void handleCrashOperation(LifecycleOperation *operation) override {} 32 | 33 | void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 34 | void initialize(int stage) override; 35 | virtual void handleMessageWhenUp(cMessage *msg) override; 36 | //virtual void handlePacketIn(OFP_Packet_In * packet_in_msg); 37 | virtual void handlePacketIn(Packet * pkt); 38 | 39 | virtual Packet * createArpReply(Ipv4Address srcIp, Ipv4Address dstIp, MacAddress srcMac,MacAddress dstMac); 40 | 41 | std::map macToIp; 42 | std::map ipToMac; 43 | 44 | long answeredArp; 45 | long floodedArp; 46 | }; 47 | 48 | } /*end namespace openflow*/ 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/ARPResponder.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | package openflow.controllerApps; 17 | 18 | simple ARPResponder like IControllerApp 19 | { 20 | parameters: 21 | @class(openflow::ARPResponder); 22 | @display("i=block/app"); 23 | int priority = default(1); 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/AbstractTCPControllerApp.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ABSTRACTTCPCONTROLLERAPP_H_ 3 | #define ABSTRACTTCPCONTROLLERAPP_H_ 4 | 5 | #include "openflow/controllerApps/AbstractControllerApp.h" 6 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 7 | 8 | namespace openflow{ 9 | 10 | #if (INET_VERSION > 0x405) 11 | class AbstractTCPControllerApp: public AbstractControllerApp, public TcpSocket::BufferingCallback 12 | #else 13 | class AbstractTCPControllerApp: public AbstractControllerApp, public TcpSocket::ReceiveQueueBasedCallback 14 | #endif 15 | { 16 | protected: 17 | enum ActionKind {ACTION_EVENT=3098, ACTION_DATA}; 18 | struct Action 19 | { 20 | int kind; 21 | cMessage *msg; 22 | Action() : kind(0), msg(nullptr) {} 23 | Action(int kind, cMessage* msg) : kind(kind), msg(msg) {} 24 | }; 25 | 26 | virtual void initialize(int stage) override; 27 | virtual void handleMessageWhenUp(cMessage *msg) override; 28 | virtual void processQueuedMsg(cMessage *data_msg) = 0; 29 | virtual void calcAvgQueueSize(int size); 30 | virtual void finish() override; 31 | 32 | /** @name TcpSocket::ICallback callback methods */ 33 | //@{ 34 | // virtual void socketDataArrived(TcpSocket *socket) override; // should be implement in derived class 35 | virtual void socketAvailable(TcpSocket *socket, TcpAvailableInfo *availableInfo) override; 36 | virtual void socketEstablished(TcpSocket *socket) override; 37 | virtual void socketPeerClosed(TcpSocket *socket) override; 38 | virtual void socketClosed(TcpSocket *socket) override; 39 | virtual void socketFailure(TcpSocket *socket, int code) override; 40 | virtual void socketStatusArrived(TcpSocket *socket, TcpStatusInfo *status) override {} 41 | virtual void socketDeleted(TcpSocket *socket) override {} // TODO 42 | //@} 43 | 44 | virtual void processSelfMessage(cMessage *msg); 45 | void startProcessingMsg(Action& action); 46 | virtual void processPacketFromTcp(Packet *pkt) = 0; 47 | 48 | //stats 49 | simsignal_t queueSize; 50 | simsignal_t waitingTime; 51 | 52 | std::map packetsPerSecond; 53 | 54 | int lastQueueSize; 55 | double lastChangeTime; 56 | std::map avgQueueSize; 57 | 58 | bool busy; 59 | std::list msgList; 60 | double serviceTime; 61 | 62 | TcpSocket socket; 63 | 64 | public: 65 | AbstractTCPControllerApp(); 66 | ~AbstractTCPControllerApp(); 67 | 68 | }; 69 | 70 | } /*end namespace openflow*/ 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/AbstractTCPControllerApp.ned: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2004 Andras Varga 3 | // 4 | // This program is free software; you can redistribute it and/or 5 | // modify it under the terms of the GNU Lesser General Public License 6 | // as published by the Free Software Foundation; either version 2 7 | // of the License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Lesser General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Lesser General Public License 15 | // along with this program; if not, see . 16 | // 17 | 18 | package openflow.controllerApps; 19 | 20 | import inet.applications.contract.IApp; 21 | 22 | // 23 | // [GENERATED DOCUMENTATION -- ACCURACY UNVERIFIED] 24 | // AbstractTCPControllerApp is a base class for OpenFlow controller applications that need 25 | // to communicate over TCP in addition to interacting with the OpenFlow controller. 26 | // 27 | simple AbstractTCPControllerApp like IControllerApp, IApp 28 | { 29 | parameters: 30 | @class(openflow::AbstractTCPControllerApp); 31 | @display("i=block/app"); 32 | @signal[queueSize](type="unsigned long"); 33 | @statistic[queueSize](title="QueueSize"; record=vector?,stats; interpolationmode=none); 34 | @signal[waitingTime](type="simtime_t"); 35 | @statistic[waitingTime](title="WaitingTime"; record=vector?,stats?; interpolationmode=none); 36 | 37 | // Processing time for each message (used to simulate processing delay). 38 | // Messages are processed sequentially with this delay between them. 39 | double serviceTime @unit("s") = default(0s); 40 | 41 | // Priority of flow entries installed by this application (higher values are matched first) 42 | int priority = default(1); 43 | 44 | gates: 45 | input socketIn @labels(TcpCommand/up); 46 | output socketOut @labels(TcpCommand/down); 47 | } 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/Hub.cc: -------------------------------------------------------------------------------- 1 | #include "openflow/controllerApps/Hub.h" 2 | 3 | namespace openflow{ 4 | 5 | Define_Module(Hub); 6 | 7 | Hub::Hub(){ 8 | 9 | } 10 | 11 | Hub::~Hub(){ 12 | 13 | } 14 | 15 | void Hub::initialize(int stage){ 16 | AbstractControllerApp::initialize(stage); 17 | } 18 | 19 | void Hub::receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) { 20 | AbstractControllerApp::receiveSignal(src,id,obj,details); 21 | Enter_Method("Hub::receiveSignal %s", cComponent::getSignalName(id)); 22 | if(id == PacketInSignalId){ 23 | EV << "Hub::PacketIn" << '\n'; 24 | auto pkt = dynamic_cast(obj); 25 | if (pkt != nullptr) { 26 | auto chunk = pkt->peekAtFront(); 27 | auto packet_in_msg = dynamicPtrCast(chunk); 28 | if (packet_in_msg != nullptr) 29 | floodPacket(pkt); 30 | } 31 | } 32 | // 33 | // if(id == PacketInSignalId){ 34 | // EV << "Hub::PacketIn" << '\n'; 35 | // if (dynamic_cast(obj) != NULL) { 36 | // OFP_Packet_In *packet_in = (OFP_Packet_In *) obj; 37 | // floodPacket(packet_in); 38 | // } 39 | // } 40 | } 41 | 42 | } /*end namespace openflow*/ 43 | 44 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/Hub.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HUB_H_ 3 | #define HUB_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/AbstractControllerApp.h" 7 | 8 | namespace openflow{ 9 | 10 | class Hub:public AbstractControllerApp { 11 | 12 | 13 | public: 14 | Hub(); 15 | ~Hub(); 16 | 17 | protected: 18 | void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 19 | void initialize(int stage) override; 20 | }; 21 | 22 | } /*end namespace openflow*/ 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/Hub.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | package openflow.controllerApps; 17 | 18 | simple Hub like IControllerApp 19 | { 20 | parameters: 21 | @class(openflow::Hub); 22 | @display("i=block/app"); 23 | int priority = default(1); 24 | } 25 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/IControllerApp.ned: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2004 Andras Varga 3 | // 4 | // This program is free software; you can redistribute it and/or 5 | // modify it under the terms of the GNU Lesser General Public License 6 | // as published by the Free Software Foundation; either version 2 7 | // of the License, or (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU Lesser General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU Lesser General Public License 15 | // along with this program; if not, see . 16 | // 17 | 18 | 19 | package openflow.controllerApps; 20 | 21 | // 22 | // Module interface for all OpenFlow controller applications. Controller 23 | // applications are modules that implement specific control logic for an 24 | // OpenFlow network. They run within an OpenFlow controller and make decisions 25 | // about how packets should be handled by OpenFlow switches. Examples include 26 | // learning switches, routing applications, load balancers, and security 27 | // applications. 28 | // 29 | // The controller application architecture follows a modular design where 30 | // multiple applications can be installed in a single controller, each handling 31 | // different aspects of network control. Applications receive events from the 32 | // controller (like packet-in messages from switches), process them according to 33 | // their logic, and respond with appropriate actions (like sending flow 34 | // modification messages to install flow entries in switches). 35 | // 36 | // Signal Definitions: 37 | // - PacketIn: Emitted when a packet-in message is received from a switch 38 | // - PacketOut: Emitted when a packet-out message is sent to a switch 39 | // - PacketFeatureRequest: Emitted when a feature request message is sent to a switch 40 | // - PacketFeatureReply: Emitted when a feature reply message is received from a switch 41 | // - PacketExperimenter: Emitted for experimenter (vendor) messages 42 | // - Booted: Emitted when the controller has completed initialization 43 | // 44 | moduleinterface IControllerApp 45 | { 46 | parameters: 47 | @class(openflow::IControllerApp); 48 | @signal[PacketIn]; 49 | @signal[PacketOut]; 50 | @signal[PacketFeatureRequest]; 51 | @signal[PacketFeatureReply]; 52 | @signal[PacketExperimenter]; 53 | @signal[Booted]; 54 | @display("i=block/app"); 55 | 56 | // Priority of flow entries installed by this application (higher values are matched first) 57 | // In OpenFlow, when multiple flow entries match a packet, the entry with the highest 58 | // priority is used. This parameter determines the priority value set in flow modification 59 | // messages sent by this controller application. 60 | int priority; 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LLDPAgent.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LLDPAGENT_H_ 3 | #define LLDPAGENT_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/AbstractControllerApp.h" 7 | #include "openflow/messages/LLDP_m.h" 8 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 9 | #include "openflow/openflow/controller/Switch_Info.h" 10 | #include "openflow/controllerApps/LLDPMibGraph.h" 11 | #include "openflow/messages/OFP_Features_Reply_m.h" 12 | #include "openflow/messages/OFP_Packet_In_m.h" 13 | 14 | namespace openflow{ 15 | 16 | class LLDPAgent:public AbstractControllerApp { 17 | 18 | 19 | public: 20 | LLDPAgent(); 21 | ~LLDPAgent(); 22 | LLDPMibGraph * getMibGraph(); 23 | 24 | protected: 25 | virtual void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 26 | virtual void initialize(int stage) override; 27 | virtual void handleMessageWhenUp(cMessage *msg) override; 28 | void triggerFlowMod(Switch_Info * swInfo); 29 | virtual void handlePacketIn(Packet * packet_in_msg); 30 | void sendLLDP(); 31 | double pollInterval; 32 | double timeOut; 33 | LLDPMibGraph mibGraph; 34 | bool printMibGraph; 35 | int idleTimeout; 36 | int hardTimeout; 37 | }; 38 | 39 | } /*end namespace openflow*/ 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LLDPAgent.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | package openflow.controllerApps; 17 | 18 | // 19 | // [GENERATED DOCUMENTATION -- ACCURACY UNVERIFIED] 20 | // The LLDPAgent is a controller application responsible for network topology discovery 21 | // using the Link Layer Discovery Protocol (LLDP). It is deployed exclusively on the 22 | // controller side, not on switches. 23 | // 24 | // The module periodically sends LLDP packets to all switches using OpenFlow packet-out 25 | // messages. Each switch forwards these LLDP packets on all its ports. When a switch 26 | // receives an LLDP packet on one of its ports, it forwards it to the controller via 27 | // a packet-in message. The LLDPAgent uses these packet-in messages to build a graph 28 | // of the network topology. 29 | // 30 | // The topology information is stored in an LLDPMibGraph, which represents the network 31 | // as a graph where switches and hosts are vertices and links are edges. This graph 32 | // is used by other controller applications like LLDPBalancedMinHop to compute paths 33 | // between hosts. 34 | // 35 | // The LLDPAgent installs flow entries in switches to forward LLDP packets to the 36 | // controller. It also handles the expiration of topology information based on the 37 | // configured timeout. 38 | // 39 | simple LLDPAgent like IControllerApp 40 | { 41 | parameters: 42 | @class(openflow::LLDPAgent); 43 | @display("i=block/app"); 44 | 45 | // How often to send LLDP packets for topology discovery (default value from Cisco) 46 | double pollInterval @unit("s") = default(30s); 47 | 48 | // How long topology information is valid before expiring (default value from Cisco) 49 | double timeOut @unit("s") = default(120s); 50 | 51 | // Hard timeout for flow entries (0 means no hard timeout) 52 | int flowModHardTimeOut = default(0); 53 | 54 | // Idle timeout for flow entries (how long a flow entry remains if not used) 55 | int flowModIdleTimeOut = default(60); 56 | 57 | // Whether to print the topology graph to the console 58 | bool printMibGraph = default(false); 59 | 60 | // Priority of flow entries installed by this application (higher values are matched first) 61 | int priority = default(1); 62 | } 63 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LLDPBalancedMinHop.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LLDPBALANCEDMINHOP_H_ 3 | #define LLDPBALANCEDMINHOP_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/AbstractControllerApp.h" 7 | #include "openflow/controllerApps/LLDPAgent.h" 8 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 9 | #include "openflow/openflow/controller/Switch_Info.h" 10 | #include "openflow/controllerApps/LLDPMib.h" 11 | #include "openflow/messages/OFP_Packet_In_m.h" 12 | #include "inet/networklayer/arp/ipv4/ArpPacket_m.h" 13 | 14 | namespace openflow{ 15 | 16 | struct LLDPPathSegment{ 17 | std::string chassisId; 18 | int outport; 19 | }; 20 | 21 | class LLDPBalancedMinHop:public AbstractControllerApp { 22 | 23 | 24 | public: 25 | LLDPBalancedMinHop(); 26 | ~LLDPBalancedMinHop(); 27 | 28 | protected: 29 | virtual void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 30 | virtual void initialize(int stage) override; 31 | virtual void handlePacketIn(Packet *); 32 | virtual std::list computeBalancedMinHopPath(std::string srcId, std::string dstId); 33 | 34 | LLDPAgent * lldpAgent; 35 | bool dropIfNoRouteFound; 36 | bool ignoreArpRequests; 37 | bool printMibGraph; 38 | 39 | long version; 40 | long versionHit; 41 | long versionMiss; 42 | long cacheHit; 43 | long cacheMiss; 44 | 45 | int idleTimeout; 46 | int hardTimeout; 47 | 48 | std::map, std::list > routeCache; 49 | }; 50 | 51 | } /*end namespace openflow*/ 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LLDPBalancedMinHop.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | package openflow.controllerApps; 17 | 18 | simple LLDPBalancedMinHop like IControllerApp 19 | { 20 | parameters: 21 | @class(openflow::LLDPBalancedMinHop); 22 | @display("i=block/app"); 23 | int flowModHardTimeOut = default(0); 24 | int flowModIdleTimeOut = default(1); 25 | bool printMibGraph = default(false); 26 | bool dropIfNoRouteFound = default(true); 27 | bool ignoreArpRequests = default(false); 28 | int priority = default(1); 29 | } 30 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LLDPForwarding.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LLDPAGENTFORWARDING_H_ 3 | #define LLDPAGENTFORWARDING_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/AbstractControllerApp.h" 7 | #include "openflow/controllerApps/LLDPAgent.h" 8 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 9 | #include "openflow/openflow/controller/Switch_Info.h" 10 | #include "openflow/controllerApps/LLDPMib.h" 11 | #include "openflow/messages/OFP_Packet_In_m.h" 12 | #include "inet/networklayer/arp/ipv4/ArpPacket_m.h" 13 | 14 | namespace openflow{ 15 | 16 | struct LLDPPathSegment{ 17 | std::string chassisId; 18 | int outport; 19 | }; 20 | 21 | class LLDPForwarding:public AbstractControllerApp { 22 | 23 | 24 | public: 25 | LLDPForwarding(); 26 | ~LLDPForwarding(); 27 | 28 | protected: 29 | virtual void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 30 | virtual void initialize(int stage) override; 31 | virtual void handlePacketIn(Packet * ); 32 | virtual void computePath(std::string srcId, std::string dstId, std::list &list); 33 | 34 | 35 | LLDPAgent * lldpAgent; 36 | long flooded; 37 | long forwarded; 38 | long dropped; 39 | bool dropIfNoRouteFound; 40 | bool ignoreArpRequests; 41 | bool printMibGraph; 42 | long version; 43 | long versionHit; 44 | long versionMiss; 45 | long cacheHit; 46 | long cacheMiss; 47 | 48 | int idleTimeout; 49 | int hardTimeout; 50 | 51 | std::map, std::list > routeCache; 52 | 53 | 54 | }; 55 | 56 | } /*end namespace openflow*/ 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LLDPForwarding.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | package openflow.controllerApps; 17 | 18 | simple LLDPForwarding like IControllerApp 19 | { 20 | parameters: 21 | @class(openflow::LLDPForwarding); 22 | @display("i=block/app"); 23 | int flowModHardTimeOut = default(0); 24 | int flowModIdleTimeOut = default(1); 25 | bool printMibGraph = default(false); 26 | bool dropIfNoRouteFound = default(true); 27 | bool ignoreArpRequests = default(false); 28 | int priority = default(1); 29 | } 30 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LLDPMib.cc: -------------------------------------------------------------------------------- 1 | #include "openflow/controllerApps/LLDPMib.h" 2 | 3 | using namespace std; 4 | 5 | namespace openflow{ 6 | 7 | LLDPMib::LLDPMib(){ 8 | 9 | } 10 | 11 | LLDPMib::LLDPMib(int sPort, int dPort,std::string sID,std::string dID,SimTime exp){ 12 | srcPort = sPort; 13 | dstPort = dPort; 14 | srcID = sID; 15 | dstID = dID; 16 | expiresAt = exp; 17 | } 18 | 19 | bool LLDPMib::operator == ( const LLDPMib &b) const{ 20 | return ((strcmp(b.getDstId().c_str(),dstID.c_str())==0 21 | && strcmp(b.getSrcId().c_str(),srcID.c_str())==0 22 | && b.getDstPort() == dstPort 23 | && b.getSrcPort() == srcPort) 24 | || (strcmp(b.getDstId().c_str(),srcID.c_str())==0 25 | && strcmp(b.getSrcId().c_str(),dstID.c_str())==0 26 | && b.getDstPort() == srcPort 27 | && b.getSrcPort() == dstPort)); 28 | } 29 | 30 | string LLDPMib::getDstId() const{ 31 | return dstID; 32 | } 33 | 34 | void LLDPMib::setDstId(string dstId){ 35 | this->dstID = dstId; 36 | } 37 | 38 | int LLDPMib::getDstPort() const{ 39 | return dstPort; 40 | } 41 | 42 | void LLDPMib::setDstPort(int dstPort){ 43 | this->dstPort = dstPort; 44 | } 45 | 46 | string LLDPMib::getSrcId() const{ 47 | return srcID; 48 | } 49 | 50 | void LLDPMib::setSrcId(string srcId){ 51 | this->srcID = srcId; 52 | } 53 | 54 | int LLDPMib::getSrcPort() const{ 55 | return srcPort; 56 | } 57 | 58 | void LLDPMib::setSrcPort(int srcPort){ 59 | this->srcPort = srcPort; 60 | } 61 | 62 | SimTime LLDPMib::getExpiresAt() const{ 63 | return expiresAt; 64 | } 65 | 66 | void LLDPMib::setExpiresAt(SimTime expiresAt){ 67 | this->expiresAt = expiresAt; 68 | } 69 | 70 | } /*end namespace openflow*/ 71 | 72 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LLDPMib.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef LLDPMIB_H_ 4 | #define LLDPMIB_H_ 5 | #include 6 | 7 | using namespace __gnu_cxx; 8 | using namespace omnetpp; 9 | 10 | namespace openflow{ 11 | 12 | class LLDPMib { 13 | public: 14 | LLDPMib(); 15 | LLDPMib(int sPort, int dPort,std::string sID,std::string dID,SimTime exp); 16 | 17 | std::string getDstId() const; 18 | void setDstId(std::string dstId); 19 | int getDstPort() const; 20 | void setDstPort(int dstPort); 21 | std::string getSrcId() const; 22 | void setSrcId(std::string srcId); 23 | int getSrcPort() const; 24 | void setSrcPort(int srcPort); 25 | SimTime getExpiresAt() const; 26 | void setExpiresAt(SimTime expiresAt); 27 | 28 | bool operator == (const LLDPMib &b) const; 29 | 30 | protected: 31 | int srcPort; 32 | int dstPort; 33 | std::string srcID; 34 | std::string dstID; 35 | SimTime expiresAt; 36 | }; 37 | 38 | } /*end namespace openflow*/ 39 | 40 | #endif /* FLOW_TABLE_H_ */ 41 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LLDPMibGraph.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef LLDPMIBGRAPH_H_ 4 | #define LLDPMIBGRAPH_H_ 5 | 6 | #include "openflow/controllerApps/LLDPMib.h" 7 | #include 8 | #include 9 | 10 | using namespace __gnu_cxx; 11 | 12 | namespace openflow{ 13 | 14 | class LLDPMibGraph { 15 | public: 16 | LLDPMibGraph(); 17 | 18 | bool addEntry(std::string src, int srcPort, std::string dst, int dstPort, SimTime timeOut); 19 | void removeExpiredEntries(); 20 | 21 | 22 | long getNumOfEdges() const; 23 | long getNumOfVerticies() const; 24 | 25 | const std::string getStringGraph(); 26 | const std::map >& getVerticies() const; 27 | long getVersion() const; 28 | 29 | protected: 30 | std::map< std::string, std::vector > verticies; 31 | long numOfVerticies; 32 | long numOfEdges; 33 | long version; 34 | }; 35 | 36 | } /*end namespace openflow*/ 37 | 38 | #endif /* FLOW_TABLE_H_ */ 39 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LearningSwitch.cc: -------------------------------------------------------------------------------- 1 | #include "openflow/controllerApps/LearningSwitch.h" 2 | #include "openflow/openflow/controller/Switch_Info.h" 3 | #include "openflow/openflow/protocol/OFMatchFactory.h" 4 | 5 | namespace openflow{ 6 | 7 | Define_Module(LearningSwitch); 8 | 9 | LearningSwitch::LearningSwitch(){ 10 | 11 | } 12 | 13 | LearningSwitch::~LearningSwitch(){ 14 | 15 | } 16 | 17 | void LearningSwitch::initialize(int stage){ 18 | AbstractControllerApp::initialize(stage); 19 | if (stage == INITSTAGE_LOCAL) { 20 | idleTimeout = par("flowModIdleTimeOut"); 21 | hardTimeout = par("flowModHardTimeOut"); 22 | } 23 | } 24 | 25 | void LearningSwitch::receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) { 26 | AbstractControllerApp::receiveSignal(src,id,obj,details); 27 | Enter_Method("LearningSwitch::receiveSignal %s", cComponent::getSignalName(id)); 28 | if(id == PacketInSignalId){ 29 | EV << "Hub::PacketIn" << '\n'; 30 | auto pkt = dynamic_cast(obj); 31 | if (pkt != nullptr) { 32 | auto chunk = pkt->peekAtFront(); 33 | auto packet_in_msg = dynamicPtrCast(chunk); 34 | if (packet_in_msg != nullptr) 35 | doSwitching(pkt); 36 | } 37 | } 38 | // if(id == PacketInSignalId){ 39 | // EV << "LearningSwitch::PacketIn" << endl; 40 | // if (dynamic_cast(obj) != NULL) { 41 | // OFP_Packet_In *packet_in = (OFP_Packet_In *) obj; 42 | // doSwitching(packet_in); 43 | // } 44 | // } 45 | } 46 | 47 | 48 | void LearningSwitch::doSwitching(Packet *packet_in_msg){ 49 | 50 | CommonHeaderFields headerFields = extractCommonHeaderFields(packet_in_msg); 51 | 52 | //search map for source mac address and enter 53 | if(lookupTable.count(headerFields.swInfo)<=0){ 54 | lookupTable[headerFields.swInfo]= std::map(); 55 | lookupTable[headerFields.swInfo][headerFields.src_mac] = headerFields.inport; 56 | } else { 57 | if(lookupTable[headerFields.swInfo].count(headerFields.src_mac)<=0){ 58 | lookupTable[headerFields.swInfo][headerFields.src_mac] = headerFields.inport; 59 | } 60 | } 61 | 62 | 63 | if(lookupTable.count(headerFields.swInfo)<=0){ 64 | floodPacket(packet_in_msg); 65 | } else { 66 | if(lookupTable[headerFields.swInfo].count(headerFields.dst_mac)<=0){ 67 | floodPacket(packet_in_msg); 68 | } else { 69 | uint32_t outport = lookupTable[headerFields.swInfo][headerFields.dst_mac]; 70 | 71 | auto builder = OFMatchFactory::getBuilder(); 72 | builder->setField(OFPXMT_OFB_ETH_DST, &headerFields.dst_mac); 73 | builder->setField(OFPXMT_OFB_ETH_TYPE, &headerFields.eth_type); 74 | builder->setField(OFPXMT_OFB_ETH_SRC, &headerFields.src_mac); 75 | builder->setField(OFPXMT_OFB_IN_PORT, &headerFields.inport); 76 | oxm_basic_match match = builder->build(); 77 | 78 | TcpSocket * socket = controller->findSocketFor(packet_in_msg); 79 | sendFlowModMessage(OFPFC_ADD, match, outport, socket,idleTimeout,hardTimeout); 80 | sendPacket(packet_in_msg, outport); 81 | } 82 | } 83 | } 84 | 85 | } /*end namespace openflow*/ 86 | 87 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LearningSwitch.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LEARNINGSWITCH_H_ 3 | #define LEARNINGSWITCH_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/AbstractControllerApp.h" 7 | #include "inet/linklayer/common/MacAddress.h" 8 | 9 | namespace openflow{ 10 | 11 | class LearningSwitch:public AbstractControllerApp { 12 | 13 | 14 | public: 15 | LearningSwitch(); 16 | ~LearningSwitch(); 17 | 18 | protected: 19 | virtual void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 20 | virtual void initialize(int stage) override; 21 | void doSwitching(Packet *packet_in_msg); 22 | 23 | virtual void handleMessageWhenUp(cMessage *msg) override { 24 | throw cRuntimeError("Received message, this module should not receive a message"); 25 | } 26 | 27 | 28 | std::map > lookupTable; 29 | 30 | int idleTimeout; 31 | int hardTimeout; 32 | 33 | 34 | }; 35 | 36 | } /*end namespace openflow*/ 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/openflow/controllerApps/LearningSwitch.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | package openflow.controllerApps; 17 | 18 | simple LearningSwitch like IControllerApp 19 | { 20 | parameters: 21 | @class(openflow::LearningSwitch); 22 | @display("i=block/app"); 23 | int flowModHardTimeOut = default(0); 24 | int flowModIdleTimeOut = default(10); 25 | int priority = default(1); 26 | } 27 | -------------------------------------------------------------------------------- /src/openflow/hostApps/LocalityPingAppRandom.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "inet/common/INETDefs.h" 4 | #include "inet/applications/pingapp/PingApp.h" 5 | #include "inet/networklayer/common/L3Address.h" 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace inet; 11 | 12 | namespace openflow{ 13 | 14 | /** 15 | * Generates ping requests and calculates the packet loss and round trip 16 | * parameters of the replies. Uses cTopology class to get all available destinations 17 | * and chooses random one 18 | * 19 | * See NED file for detailed description of operation. 20 | */ 21 | class LocalityPingAppRandom : public PingApp { 22 | protected: 23 | virtual void initialize(int stage) override; 24 | virtual void handleSelfMessage(omnetpp::cMessage *msg) override; 25 | virtual bool isEnabled() override; 26 | 27 | cTopology topo; 28 | std::string connectAddress; 29 | double localityRelation; 30 | std::string localId; 31 | std::map > groupToNodes; 32 | }; 33 | 34 | } /*end namespace openflow*/ 35 | -------------------------------------------------------------------------------- /src/openflow/hostApps/LocalityPingAppRandom.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.hostApps; 4 | 5 | //PingAppRandom: 6 | // choses random destination node. 7 | // 8 | // PingApp: 9 | // 10 | // Generates ping requests and calculates the packet loss and round trip 11 | // parameters of the replies. 12 | // 13 | // Start/stop time, interval etc can be specified via parameters. To disable, 14 | // specify empty destAddr or stopTime<=startTime. 15 | // 16 | // Every ping request is sent out with a sequence number, and replies are 17 | // expected to arrive in the same order. Whenever there's a jump in the 18 | // in the received ping responses' sequence number (e.g. 1, 2, 3, 5), then 19 | // the missing pings (number 4 in this example) is counted as lost. 20 | // Then if it still arrives later (that is, a reply with a sequence number 21 | // smaller than the largest one received so far) it will be counted as 22 | // out-of-sequence arrival. So the number of really lost pings will be 23 | // "lost" minus "out-of-order" (assuming there's no duplicate or bogus reply). 24 | // 25 | // Uses PingPayload as payload for the ICMP(v6) Echo Request/Reply packets. 26 | // 27 | // @see PingPayload, ICMP, ICMPv6Core 28 | // 29 | simple LocalityPingAppRandom extends inet.applications.pingapp.PingApp 30 | { 31 | parameters: 32 | @class(openflow::LocalityPingAppRandom); 33 | @display("i=block/app"); 34 | @class(LocalityPingAppRandom); 35 | double localityRelation = default(0.5); 36 | string destinationNedType = default("inet.node.inet.StandardHost"); 37 | string pathToGroupConfigFile = default(""); 38 | 39 | } 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/openflow/hostApps/PingAppRandom.cc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | #include "openflow/hostApps/PingAppRandom.h" 6 | 7 | #include "inet/networklayer/common/L3AddressResolver.h" 8 | #include "inet/networklayer/contract/ipv4/Ipv4Socket.h" 9 | #include "inet/networklayer/ipv4/Icmp.h" 10 | #include "inet/networklayer/ipv4/IcmpHeader.h" 11 | #include "inet/networklayer/ipv4/Ipv4InterfaceData.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using namespace inet; 18 | 19 | namespace openflow{ 20 | 21 | Define_Module(PingAppRandom); 22 | 23 | 24 | void PingAppRandom::initialize(int stage){ 25 | if (stage == INITSTAGE_LOCAL){ 26 | topo.extractByNedTypeName(cStringTokenizer(par("destinationNedType")).asVector()); 27 | EV << "Number of extracted nodes: " << topo.getNumNodes() << endl; 28 | } 29 | PingApp::initialize(stage); 30 | pingPacketHash = registerSignal("pingPacketHash"); 31 | 32 | } 33 | 34 | void PingAppRandom::handleSelfMessage(cMessage *msg){ 35 | 36 | if (msg == timer){ 37 | // connect to random destination node 38 | unsigned nodeNum = topo.getNumNodes(); 39 | if (nodeNum == 0) 40 | throw cRuntimeError("No potential destination nodes found"); 41 | int random_num = intrand(nodeNum); 42 | 43 | std::string connectAddressAux =topo.getNode(random_num)->getModule()->getFullPath(); 44 | 45 | if (connectAddressAux != connectAddress && currentSocket != nullptr) { 46 | currentSocket->close(); 47 | currentSocket = nullptr; 48 | } 49 | 50 | if (currentSocket == nullptr) { 51 | auto networkProtocol = &Protocol::ipv4; 52 | const Protocol *icmp = l3Echo.at(networkProtocol); 53 | currentSocket = new Ipv4Socket(gate("socketOut")); 54 | currentSocket->bind(icmp, L3Address()); 55 | currentSocket->setCallback(this); 56 | socketMap.addSocket(currentSocket); 57 | } 58 | 59 | connectAddress = connectAddressAux; 60 | while (topo.getNode(random_num)->getModule() == getParentModule()) { 61 | 62 | // avoid same source and destination 63 | random_num = intrand(topo.getNumNodes()); 64 | connectAddress =topo.getNode(random_num)->getModule()->getFullPath(); 65 | } 66 | 67 | destAddr = inet::L3AddressResolver().resolve(connectAddress.c_str()); 68 | ASSERT(!destAddr.isUnspecified()); 69 | srcAddr = inet::L3AddressResolver().resolve(par("srcAddr")); 70 | EV << "Starting up: dest=" << destAddr << " src=" << srcAddr << "\n"; 71 | 72 | sendPingRequest(); 73 | if (isEnabled()) 74 | scheduleNextPingRequest(simTime(), true); 75 | } 76 | } 77 | 78 | 79 | bool PingAppRandom::isEnabled(){ 80 | return (count == -1 || sentCount < count); 81 | } 82 | 83 | } /*end namespace openflow*/ 84 | -------------------------------------------------------------------------------- /src/openflow/hostApps/PingAppRandom.h: -------------------------------------------------------------------------------- 1 | 2 | #include "inet/common/INETDefs.h" 3 | #include "inet/applications/pingapp/PingApp.h" 4 | #include "inet/networklayer/common/L3Address.h" 5 | 6 | using namespace omnetpp; 7 | 8 | namespace openflow{ 9 | 10 | /** 11 | * Generates ping requests and calculates the packet loss and round trip 12 | * parameters of the replies. Uses cTopology class to get all available destinations 13 | * and chooses random one 14 | * 15 | * See NED file for detailed description of operation. 16 | */ 17 | class PingAppRandom : public inet::PingApp { 18 | protected: 19 | virtual bool isEnabled() override; 20 | virtual void initialize(int stage) override; 21 | virtual void handleSelfMessage(omnetpp::cMessage *msg) override; 22 | 23 | omnetpp::cTopology topo; 24 | std::string connectAddress; 25 | 26 | //stats 27 | inet::simsignal_t pingPacketHash; 28 | }; 29 | 30 | } /*end namespace openflow*/ 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/openflow/hostApps/PingAppRandom.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.hostApps; 4 | 5 | //PingAppRandom: 6 | // choses random destination node. 7 | // 8 | // PingApp: 9 | // 10 | // Generates ping requests and calculates the packet loss and round trip 11 | // parameters of the replies. 12 | // 13 | // Start/stop time, interval etc can be specified via parameters. To disable, 14 | // specify empty destAddr or stopTime<=startTime. 15 | // 16 | // Every ping request is sent out with a sequence number, and replies are 17 | // expected to arrive in the same order. Whenever there's a jump in the 18 | // in the received ping responses' sequence number (e.g. 1, 2, 3, 5), then 19 | // the missing pings (number 4 in this example) is counted as lost. 20 | // Then if it still arrives later (that is, a reply with a sequence number 21 | // smaller than the largest one received so far) it will be counted as 22 | // out-of-sequence arrival. So the number of really lost pings will be 23 | // "lost" minus "out-of-order" (assuming there's no duplicate or bogus reply). 24 | // 25 | // Uses PingPayload as payload for the ICMP(v6) Echo Request/Reply packets. 26 | // 27 | // @see PingPayload, ICMP, ICMPv6Core 28 | // 29 | simple PingAppRandom extends inet.applications.pingapp.PingApp 30 | { 31 | parameters: 32 | @class(openflow::PingAppRandom); 33 | @signal[pingPacketHash](type="unsigned long"); 34 | @statistic[pingPacketHash](title="PingPacketHash"; record=vector?,stats?; interpolationmode=none); 35 | string destinationNedType = default("inet.node.inet.StandardHost"); 36 | @display("i=block/app"); 37 | @class(PingAppRandom); 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/openflow/hostApps/TCPTrafficGeneratorApp.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef TCP_TRAFFIC_GENERATOR_APP_H_ 4 | #define TCP_TRAFFIC_GENERATOR_APP_H_ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "inet/applications/base/ApplicationBase.h" 12 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 13 | #include "inet/networklayer/common/L3Address.h" 14 | #include "inet/applications/tcpapp/TcpAppBase.h" 15 | 16 | using namespace std; 17 | using namespace inet; 18 | 19 | namespace openflow{ 20 | 21 | /** 22 | * Single-connection TCP application. 23 | */ 24 | 25 | struct Stats{ 26 | SimTime connectionStarted; 27 | SimTime connectionEstablished; 28 | SimTime connectionFinished; 29 | long transmittedBytes; 30 | }; 31 | 32 | class INET_API TCPTrafficGeneratorApp : public ApplicationBase, public TcpSocket::ICallback 33 | { 34 | 35 | protected: 36 | cTopology topo; 37 | int lineNumbers; 38 | std::set timerSet; 39 | virtual void initialize(int stage) override; 40 | virtual void handleMessageWhenUp(omnetpp::cMessage *msg) override; 41 | unsigned int FileRead( istream & is, vector & buff ); 42 | unsigned int CountLines( const vector & buff, int sz ); 43 | 44 | virtual void socketDataArrived(TcpSocket *socket, Packet *packet, bool urgent) override; 45 | virtual void socketAvailable(TcpSocket *socket, TcpAvailableInfo *availableInfo) override { socket->accept(availableInfo->getNewSocketId()); } 46 | virtual void socketEstablished(TcpSocket *socket) override; 47 | virtual void socketPeerClosed(TcpSocket *socket) override; 48 | virtual void socketClosed(TcpSocket *socket) override; 49 | virtual void socketFailure(TcpSocket *socket, int code) override; 50 | virtual void socketStatusArrived(TcpSocket *socket, TcpStatusInfo *status) override; 51 | virtual void socketDeleted(TcpSocket *socket) override {}; 52 | 53 | std::map statistics; 54 | 55 | 56 | //stats 57 | simsignal_t connectionFinished; 58 | simsignal_t connectionStarted; 59 | simsignal_t connectionEstablished; 60 | simsignal_t transmittedBytes; 61 | 62 | // Lifecycle methods 63 | virtual void handleStartOperation(LifecycleOperation *operation) override; 64 | virtual void handleStopOperation(LifecycleOperation *operation) override; 65 | virtual void handleCrashOperation(LifecycleOperation *operation) override; 66 | 67 | 68 | }; 69 | 70 | } /*end namespace openflow*/ 71 | 72 | #endif 73 | 74 | -------------------------------------------------------------------------------- /src/openflow/hostApps/TCPTrafficGeneratorApp.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.hostApps; 4 | 5 | 6 | import inet.applications.contract.IApp; 7 | 8 | 9 | simple TCPTrafficGeneratorApp like IApp 10 | { 11 | parameters: 12 | @class(openflow::TCPTrafficGeneratorApp); 13 | @signal[connectionFinished](type="simtime_t"); 14 | @statistic[connectionFinished](title="ConnectionFinished"; record=vector?,stats; interpolationmode=none); 15 | @signal[connectionStarted](type="simtime_t"); 16 | @statistic[connectionStarted](title="ConnectionStarted"; record=vector?,stats; interpolationmode=none); 17 | @signal[connectionEstablished](type="simtime_t"); 18 | @statistic[connectionEstablished](title="ConnectionEstablished"; record=vector?,stats; interpolationmode=none); 19 | @signal[transmittedBytes](type="double"); 20 | @statistic[transmittedBytes](title="BytesTransmitted"; record=vector?,stats; interpolationmode=none); 21 | @display("i=block/app"); 22 | double startSending @unit("s") = default(2s); 23 | int connectPort = default(1000); 24 | string destinationNedType = default("inet.node.inet.StandardHost"); 25 | string pathToFlowSizes = default(""); 26 | 27 | gates: 28 | input socketIn @labels(TcpCommand/up); 29 | output socketOut @labels(TcpCommand/down); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/openflow/hostApps/TCPTrafficSinkApp.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.hostApps; 4 | 5 | 6 | import inet.applications.contract.IApp; 7 | import inet.applications.tcpapp.TcpSinkApp; 8 | 9 | module TCPTrafficSinkApp extends TcpSinkApp like IApp 10 | { 11 | } 12 | -------------------------------------------------------------------------------- /src/openflow/hostApps/localityGroupConfigFatTree2ControllersK4.txt: -------------------------------------------------------------------------------- 1 | Scenario_DynamicFatTree_KN.fat_tree.client[0];0 2 | Scenario_DynamicFatTree_KN.fat_tree.client[1];0 3 | Scenario_DynamicFatTree_KN.fat_tree.client[2];0 4 | Scenario_DynamicFatTree_KN.fat_tree.client[3];0 5 | Scenario_DynamicFatTree_KN.fat_tree.client[4];0 6 | Scenario_DynamicFatTree_KN.fat_tree.client[5];0 7 | Scenario_DynamicFatTree_KN.fat_tree.client[6];0 8 | Scenario_DynamicFatTree_KN.fat_tree.client[7];0 9 | Scenario_DynamicFatTree_KN.fat_tree.client[8];1 10 | Scenario_DynamicFatTree_KN.fat_tree.client[9];1 11 | Scenario_DynamicFatTree_KN.fat_tree.client[10];1 12 | Scenario_DynamicFatTree_KN.fat_tree.client[11];1 13 | Scenario_DynamicFatTree_KN.fat_tree.client[12];1 14 | Scenario_DynamicFatTree_KN.fat_tree.client[13];1 15 | Scenario_DynamicFatTree_KN.fat_tree.client[14];1 16 | Scenario_DynamicFatTree_KN.fat_tree.client[15];1 -------------------------------------------------------------------------------- /src/openflow/hostApps/localityGroupConfigFatTree3ControllersK6.txt: -------------------------------------------------------------------------------- 1 | Scenario_DynamicFatTree_KN.fat_tree.client[0];0 2 | Scenario_DynamicFatTree_KN.fat_tree.client[1];0 3 | Scenario_DynamicFatTree_KN.fat_tree.client[2];0 4 | Scenario_DynamicFatTree_KN.fat_tree.client[3];0 5 | Scenario_DynamicFatTree_KN.fat_tree.client[4];0 6 | Scenario_DynamicFatTree_KN.fat_tree.client[5];0 7 | Scenario_DynamicFatTree_KN.fat_tree.client[6];0 8 | Scenario_DynamicFatTree_KN.fat_tree.client[7];0 9 | Scenario_DynamicFatTree_KN.fat_tree.client[8];0 10 | Scenario_DynamicFatTree_KN.fat_tree.client[9];0 11 | Scenario_DynamicFatTree_KN.fat_tree.client[10];0 12 | Scenario_DynamicFatTree_KN.fat_tree.client[11];0 13 | Scenario_DynamicFatTree_KN.fat_tree.client[12];0 14 | Scenario_DynamicFatTree_KN.fat_tree.client[13];0 15 | Scenario_DynamicFatTree_KN.fat_tree.client[14];0 16 | Scenario_DynamicFatTree_KN.fat_tree.client[15];0 17 | Scenario_DynamicFatTree_KN.fat_tree.client[16];0 18 | Scenario_DynamicFatTree_KN.fat_tree.client[17];0 19 | Scenario_DynamicFatTree_KN.fat_tree.client[18];1 20 | Scenario_DynamicFatTree_KN.fat_tree.client[19];1 21 | Scenario_DynamicFatTree_KN.fat_tree.client[20];1 22 | Scenario_DynamicFatTree_KN.fat_tree.client[21];1 23 | Scenario_DynamicFatTree_KN.fat_tree.client[22];1 24 | Scenario_DynamicFatTree_KN.fat_tree.client[23];1 25 | Scenario_DynamicFatTree_KN.fat_tree.client[24];1 26 | Scenario_DynamicFatTree_KN.fat_tree.client[25];1 27 | Scenario_DynamicFatTree_KN.fat_tree.client[26];1 28 | Scenario_DynamicFatTree_KN.fat_tree.client[27];1 29 | Scenario_DynamicFatTree_KN.fat_tree.client[28];1 30 | Scenario_DynamicFatTree_KN.fat_tree.client[29];1 31 | Scenario_DynamicFatTree_KN.fat_tree.client[30];1 32 | Scenario_DynamicFatTree_KN.fat_tree.client[31];1 33 | Scenario_DynamicFatTree_KN.fat_tree.client[32];1 34 | Scenario_DynamicFatTree_KN.fat_tree.client[33];1 35 | Scenario_DynamicFatTree_KN.fat_tree.client[34];1 36 | Scenario_DynamicFatTree_KN.fat_tree.client[35];1 37 | Scenario_DynamicFatTree_KN.fat_tree.client[36];2 38 | Scenario_DynamicFatTree_KN.fat_tree.client[37];2 39 | Scenario_DynamicFatTree_KN.fat_tree.client[38];2 40 | Scenario_DynamicFatTree_KN.fat_tree.client[39];2 41 | Scenario_DynamicFatTree_KN.fat_tree.client[40];2 42 | Scenario_DynamicFatTree_KN.fat_tree.client[41];2 43 | Scenario_DynamicFatTree_KN.fat_tree.client[42];2 44 | Scenario_DynamicFatTree_KN.fat_tree.client[43];2 45 | Scenario_DynamicFatTree_KN.fat_tree.client[44];2 46 | Scenario_DynamicFatTree_KN.fat_tree.client[45];2 47 | Scenario_DynamicFatTree_KN.fat_tree.client[46];2 48 | Scenario_DynamicFatTree_KN.fat_tree.client[47];2 49 | Scenario_DynamicFatTree_KN.fat_tree.client[48];2 50 | Scenario_DynamicFatTree_KN.fat_tree.client[49];2 51 | Scenario_DynamicFatTree_KN.fat_tree.client[50];2 52 | Scenario_DynamicFatTree_KN.fat_tree.client[51];2 53 | Scenario_DynamicFatTree_KN.fat_tree.client[52];2 54 | Scenario_DynamicFatTree_KN.fat_tree.client[53];2 -------------------------------------------------------------------------------- /src/openflow/hostApps/randomFlowSizesCleaned1.txt.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inet-framework/openflow/5624978a34bac600123bba2e7f19f5800697d6e3/src/openflow/hostApps/randomFlowSizesCleaned1.txt.tar.gz -------------------------------------------------------------------------------- /src/openflow/hyperflow/HF_ARPResponder.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HFARPRESPONDER_H_ 3 | #define HFARPRESPONDER_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/AbstractControllerApp.h" 7 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 8 | #include "openflow/openflow/controller/Switch_Info.h" 9 | #include "openflow/messages/OFP_Features_Reply_m.h" 10 | #include "openflow/messages/OFP_Packet_In_m.h" 11 | #include "inet/networklayer/arp/ipv4/ArpPacket_m.h" 12 | #include "openflow/controllerApps/ARPResponder.h" 13 | #include "openflow/hyperflow/HyperFlowAgent.h" 14 | #include "openflow/hyperflow/HF_ReFire_Wrapper.h" 15 | #include "openflow/utility/ARP_Wrapper.h" 16 | 17 | namespace openflow{ 18 | 19 | class HF_ARPResponder: public ARPResponder { 20 | 21 | 22 | public: 23 | HF_ARPResponder(); 24 | ~HF_ARPResponder(); 25 | 26 | 27 | protected: 28 | virtual bool searchHyperFlowAggent(); 29 | virtual void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 30 | virtual void initialize(int stage) override; 31 | virtual void handlePacketIn(Packet*) override; 32 | 33 | HyperFlowAgent * hfAgent = nullptr; 34 | static simsignal_t HyperFlowReFireSignalId; 35 | }; 36 | 37 | } /*end namespace openflow*/ 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/openflow/hyperflow/HF_ARPResponder.ned: -------------------------------------------------------------------------------- 1 | 2 | package openflow.hyperflow; 3 | import openflow.controllerApps.IControllerApp; 4 | 5 | // 6 | // [GENERATED DOCUMENTATION -- ACCURACY UNVERIFIED] 7 | // The HF_ARPResponder is a specialized controller application that extends the basic ARPResponder 8 | // functionality to work within the HyperFlow distributed controller architecture. (The HF prefix 9 | // stands for HyperFlow.) 10 | // 11 | // Basic ARPResponder Functionality: 12 | // - Maintains a mapping between IP addresses and MAC addresses 13 | // - Responds to ARP requests if it knows the MAC address for the requested IP 14 | // - Floods ARP requests to all switches if it doesn't know the requested MAC address 15 | // - Learns new IP-to-MAC mappings from ARP packets passing through the network 16 | // 17 | // HyperFlow is a distributed controller architecture that: 18 | // - Enables multiple OpenFlow controllers to work together as a logically centralized controller 19 | // - Provides fault tolerance and scalability through controller distribution 20 | // - Synchronizes state between controllers using a publish-subscribe mechanism 21 | // - Allows controllers to operate independently while maintaining a consistent network view 22 | // 23 | // HF_ARPResponder's Role: 24 | // 25 | // 1. State Synchronization: When it learns a new IP-to-MAC mapping, it not only stores it locally 26 | // but also publishes this information to other controllers through the HyperFlow synchronization channel. 27 | // 28 | // 2. Distributed Learning: It can receive IP-to-MAC mappings discovered by other controllers through 29 | // the HyperFlow "ReFire" mechanism, allowing all controllers to maintain a consistent ARP table. 30 | // 31 | // 3. Fault Tolerance: If one controller fails, others can continue to respond to ARP requests 32 | // because they share the same ARP table information. 33 | // 34 | // 4. Scalability: By distributing the ARP handling across multiple controllers, the system can 35 | // handle larger networks more efficiently. 36 | // 37 | // Note: HF_ARPResponder requires the HyperFlowAgent to be installed in the same controller. 38 | // The HyperFlowAgent provides the communication infrastructure that enables the 39 | // distributed functionality of HF_ARPResponder. 40 | // 41 | simple HF_ARPResponder like IControllerApp 42 | { 43 | parameters: 44 | @class(openflow::HF_ARPResponder); 45 | @signal[HyperFlowReFire]; 46 | @display("i=block/app"); 47 | int priority = default(1); 48 | } 49 | -------------------------------------------------------------------------------- /src/openflow/hyperflow/HF_LLDPAgent.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HFLLDPAGENT_H_ 3 | #define HFLLDPAGENT_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/LLDPAgent.h" 7 | #include "openflow/controllerApps/AbstractControllerApp.h" 8 | #include "openflow/messages/LLDP_m.h" 9 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 10 | #include "openflow/openflow/controller/Switch_Info.h" 11 | #include "openflow/controllerApps/LLDPMibGraph.h" 12 | #include "openflow/messages/OFP_Features_Reply_m.h" 13 | #include "openflow/messages/OFP_Packet_In_m.h" 14 | #include "openflow/hyperflow/HyperFlowAgent.h" 15 | #include "openflow/hyperflow/HF_ReFire_Wrapper.h" 16 | #include "openflow/utility/LLDP_Wrapper.h" 17 | 18 | namespace openflow{ 19 | 20 | class HF_LLDPAgent:public LLDPAgent { 21 | 22 | 23 | public: 24 | HF_LLDPAgent(); 25 | ~HF_LLDPAgent(); 26 | LLDPMibGraph * getMibGraph(); 27 | 28 | protected: 29 | virtual bool searchHyperFlowAggent(); 30 | virtual void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 31 | virtual void initialize(int stage) override; 32 | virtual void handlePacketIn(Packet *) override; 33 | HyperFlowAgent * hfAgent = nullptr; 34 | static simsignal_t HyperFlowReFireSignalId; 35 | }; 36 | 37 | } /*end namespace openflow*/ 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/openflow/hyperflow/HF_LLDPAgent.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.hyperflow; 4 | import openflow.controllerApps.IControllerApp; 5 | 6 | 7 | simple HF_LLDPAgent like IControllerApp 8 | { 9 | parameters: 10 | @class(openflow::HF_LLDPAgent); 11 | @signal[HyperFlowReFire]; 12 | @display("i=block/app"); 13 | 14 | //default value cisco 15 | double pollInterval @unit("s") = default(30s); 16 | 17 | //default value cisco 18 | double timeOut @unit("s") = default(120s); 19 | int flowModHardTimeOut = default(0); 20 | int flowModIdleTimeOut = default(60); 21 | bool printMibGraph = default(false); 22 | int priority = default(1); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/openflow/hyperflow/HF_ReFire_Wrapper.cc: -------------------------------------------------------------------------------- 1 | #include "openflow/hyperflow/HF_ReFire_Wrapper.h" 2 | 3 | using namespace std; 4 | 5 | namespace openflow{ 6 | 7 | HF_ReFire_Wrapper::HF_ReFire_Wrapper(){ 8 | 9 | } 10 | 11 | 12 | HF_ReFire_Wrapper::~HF_ReFire_Wrapper(){ 13 | 14 | } 15 | 16 | 17 | const DataChannelEntry& HF_ReFire_Wrapper::getDataChannelEntry() const{ 18 | return this->dataChannelEntry; 19 | } 20 | 21 | void HF_ReFire_Wrapper::setDataChannelEntry(const DataChannelEntry& dataEntry){ 22 | this->dataChannelEntry = dataEntry; 23 | } 24 | 25 | } /*end namespace openflow*/ 26 | -------------------------------------------------------------------------------- /src/openflow/hyperflow/HF_ReFire_Wrapper.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef HF_REFIRE_WRAPPER_H_ 4 | #define HF_REFIRE_WRAPPER_H_ 5 | 6 | #include 7 | #include "inet/linklayer/common/MacAddress.h" 8 | #include "openflow/hyperflow/HyperFlowStructs.h" 9 | 10 | using namespace std; 11 | 12 | namespace openflow{ 13 | 14 | class HF_ReFire_Wrapper: public cObject { 15 | 16 | public: 17 | HF_ReFire_Wrapper(); 18 | ~HF_ReFire_Wrapper(); 19 | 20 | 21 | const DataChannelEntry& getDataChannelEntry() const; 22 | void setDataChannelEntry(const DataChannelEntry& dataEntry); 23 | 24 | 25 | protected: 26 | DataChannelEntry dataChannelEntry; 27 | }; 28 | 29 | } /*end namespace openflow*/ 30 | 31 | 32 | #endif /* BUFFER_H_ */ 33 | -------------------------------------------------------------------------------- /src/openflow/hyperflow/HyperFlowAgent.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HYPER_FLOW_AGENT_H_ 3 | #define HYPER_FLOW_AGENT_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/AbstractTCPControllerApp.h" 7 | #include "openflow/messages/HF_SyncRequest_m.h" 8 | #include "openflow/messages/HF_ReportIn_m.h" 9 | #include "openflow/messages/HF_SyncReply_m.h" 10 | #include "openflow/hyperflow/HyperFlowStructs.h" 11 | #include "openflow/messages/HF_ChangeNotification_m.h" 12 | #include "openflow/hyperflow/HF_ReFire_Wrapper.h" 13 | 14 | namespace openflow{ 15 | 16 | class HyperFlowAgent:public AbstractTCPControllerApp { 17 | 18 | 19 | public: 20 | HyperFlowAgent(); 21 | ~HyperFlowAgent(); 22 | void synchronizeDataChannelEntry(DataChannelEntry entry); 23 | 24 | protected: 25 | 26 | virtual void initialize(int stage) override; 27 | virtual void processSelfMessage(cMessage *msg) override; 28 | virtual void processQueuedMsg(cMessage *data_msg) override; 29 | 30 | /** @name TcpSocket::ICallback callback methods */ 31 | //@{ 32 | virtual void socketDataArrived(TcpSocket *socket) override; // should be implement in derived class 33 | virtual void socketEstablished(TcpSocket *socket) override; 34 | //@} 35 | 36 | virtual void processPacketFromTcp(Packet *pkt) override; 37 | 38 | void sendReportIn(); 39 | void sendSyncRequest(); 40 | void handleSyncReply(const HF_SyncReply * msg); 41 | void handleCheckAlive(); 42 | void handleRecover(std::string controllerId); 43 | void handleFailure(std::string controllerId); 44 | 45 | 46 | bool waitingForSyncResponse; 47 | int lastSyncCounter; 48 | 49 | double checkSyncEvery; 50 | double checkAliveEvery; 51 | double checkReportInEvery; 52 | 53 | std::list controlChannel; 54 | std::list dataChannel; 55 | 56 | std::list knownControllers; 57 | std::list failedControllers; 58 | 59 | static simsignal_t HyperFlowReFireSignalId; 60 | 61 | virtual void handleStartOperation(LifecycleOperation *operation) override; 62 | 63 | 64 | }; 65 | 66 | 67 | } /*end namespace openflow*/ 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/openflow/hyperflow/HyperFlowStructs.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef HYPERFLOWSTRUCTS_H_ 3 | #define HYPERFLOWSTRUCTS_H_ 4 | 5 | #include "openflow/openflow/controller/Switch_Info.h" 6 | 7 | namespace openflow{ 8 | 9 | struct ControlChannelEntry{ 10 | std::list switches; 11 | std::string controllerId; 12 | SimTime time; 13 | }; 14 | 15 | struct DataChannelEntry{ 16 | std::string srcController; 17 | std::string trgSwitch; 18 | int eventId; 19 | omnetpp::cObject * payload; 20 | }; 21 | 22 | 23 | } /*end namespace openflow*/ 24 | 25 | 26 | #endif /* OF_CONTROLLER_H_ */ 27 | -------------------------------------------------------------------------------- /src/openflow/hyperflow/HyperFlowSynchronizer.ned: -------------------------------------------------------------------------------- 1 | 2 | package openflow.hyperflow; 3 | 4 | //Communication with OpenFlow switch; 5 | //Sending Packet-Out messages; 6 | //Sending Flow Modification messages; 7 | 8 | simple HyperFlowSynchronizer 9 | { 10 | parameters: 11 | @class(openflow::HyperFlowSynchronizer); 12 | @display("i=block/app"); 13 | @signal[queueSize](type="unsigned long"); 14 | @statistic[queueSize](title="QueueSize"; record=vector?,stats; interpolationmode=none); 15 | @signal[waitingTime](type="simtime_t"); 16 | @statistic[waitingTime](title="WaitingTime"; record=vector?,stats?; interpolationmode=none); 17 | 18 | 19 | string address = default(""); 20 | int port = default(1003); 21 | 22 | //should be the same as the checkaliveevery value of the agent module 23 | double aliveInterval @unit("s") = default(3s); 24 | 25 | double serviceTime @unit("s") = default(0s); 26 | 27 | gates: 28 | input socketIn @labels(TcpCommand/up); 29 | output socketOut @labels(TcpCommand/down); 30 | } 31 | -------------------------------------------------------------------------------- /src/openflow/kandoo/KN_ARPResponder.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNARPRESPONDER_H_ 3 | #define KNARPRESPONDER_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/AbstractControllerApp.h" 7 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 8 | #include "openflow/openflow/controller/Switch_Info.h" 9 | #include "openflow/messages/OFP_Features_Reply_m.h" 10 | #include "openflow/messages/OFP_Packet_In_m.h" 11 | #include "inet/networklayer/arp/ipv4/ArpPacket_m.h" 12 | #include "openflow/controllerApps/ARPResponder.h" 13 | #include "openflow/kandoo/KandooAgent.h" 14 | #include "openflow/utility/ARP_Wrapper.h" 15 | 16 | namespace openflow{ 17 | 18 | class KN_ARPResponder:public ARPResponder { 19 | 20 | 21 | public: 22 | KN_ARPResponder(); 23 | ~KN_ARPResponder(); 24 | 25 | 26 | protected: 27 | virtual void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 28 | virtual void initialize(int stage) override; 29 | virtual void handlePacketIn(Packet * packet_in_msg) override; 30 | 31 | KandooAgent * knAgent; 32 | simsignal_t kandooEventSignalId; 33 | std::string appName; 34 | }; 35 | 36 | } /*end namespace openflow*/ 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/openflow/kandoo/KN_ARPResponder.ned: -------------------------------------------------------------------------------- 1 | package openflow.kandoo; 2 | 3 | import openflow.controllerApps.IControllerApp; 4 | 5 | simple KN_ARPResponder like IControllerApp 6 | { 7 | parameters: 8 | @class(openflow::KN_ARPResponder); 9 | @signal[KandooEvent]; 10 | @display("i=block/app"); 11 | int priority = default(1); 12 | } 13 | -------------------------------------------------------------------------------- /src/openflow/kandoo/KN_LLDPAgent.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNLLDPAGENT_H_ 3 | #define KNLLDPAGENT_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/LLDPAgent.h" 7 | #include "openflow/controllerApps/AbstractControllerApp.h" 8 | #include "openflow/messages/LLDP_m.h" 9 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 10 | #include "openflow/openflow/controller/Switch_Info.h" 11 | #include "openflow/controllerApps/LLDPMibGraph.h" 12 | #include "openflow/messages/OFP_Features_Reply_m.h" 13 | #include "openflow/messages/OFP_Packet_In_m.h" 14 | #include "openflow/kandoo/KandooAgent.h" 15 | #include "openflow/utility/LLDP_Wrapper.h" 16 | 17 | namespace openflow{ 18 | 19 | class KN_LLDPAgent:public LLDPAgent { 20 | 21 | 22 | public: 23 | KN_LLDPAgent(); 24 | ~KN_LLDPAgent(); 25 | LLDPMibGraph * getMibGraph(); 26 | 27 | protected: 28 | virtual void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 29 | virtual void initialize(int stage) override; 30 | virtual void handlePacketIn(Packet *) override; 31 | KandooAgent * kandooAgent; 32 | simsignal_t kandooEventSignalId; 33 | std::string appName; 34 | }; 35 | 36 | } /*end namespace openflow*/ 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/openflow/kandoo/KN_LLDPAgent.ned: -------------------------------------------------------------------------------- 1 | package openflow.kandoo; 2 | 3 | import openflow.controllerApps.IControllerApp; 4 | 5 | simple KN_LLDPAgent like IControllerApp 6 | { 7 | parameters: 8 | @class(openflow::KN_LLDPAgent); 9 | @signal[KandooEvent]; 10 | @display("i=block/app"); 11 | 12 | //default value cisco 13 | double pollInterval @unit("s") = default(30s); 14 | 15 | //default value cisco 16 | double timeOut @unit("s") = default(120s); 17 | int flowModHardTimeOut = default(0); 18 | int flowModIdleTimeOut = default(60); 19 | bool printMibGraph = default(false); 20 | int priority = default(1); 21 | } 22 | -------------------------------------------------------------------------------- /src/openflow/kandoo/KN_LLDPBalancedMinHop.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNLLDPBALANCEDMINHOP_H_ 3 | #define KNLLDPBALANCEDMINHOP_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/LLDPBalancedMinHop.h" 7 | #include "openflow/kandoo/KandooAgent.h" 8 | 9 | 10 | namespace openflow{ 11 | 12 | class KN_LLDPBalancedMinHop:public LLDPBalancedMinHop { 13 | 14 | 15 | public: 16 | KN_LLDPBalancedMinHop(); 17 | ~KN_LLDPBalancedMinHop(); 18 | 19 | protected: 20 | virtual void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 21 | virtual void initialize(int stage) override; 22 | virtual void handlePacketIn(Packet *) override; 23 | 24 | KandooAgent * knAgent; 25 | simsignal_t kandooEventSignalId; 26 | std::string appName; 27 | 28 | 29 | }; 30 | 31 | } /*end namespace openflow*/ 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/openflow/kandoo/KN_LLDPBalancedMinHop.ned: -------------------------------------------------------------------------------- 1 | package openflow.kandoo; 2 | 3 | import openflow.controllerApps.IControllerApp; 4 | 5 | simple KN_LLDPBalancedMinHop like IControllerApp 6 | { 7 | parameters: 8 | @class(openflow::KN_LLDPBalancedMinHop); 9 | @signal[KandooEvent]; 10 | @display("i=block/app"); 11 | int flowModHardTimeOut = default(0); 12 | int flowModIdleTimeOut = default(1); 13 | bool printMibGraph = default(false); 14 | bool dropIfNoRouteFound = default(true); 15 | bool ignoreArpRequests = default(false); 16 | int priority = default(1); 17 | } 18 | -------------------------------------------------------------------------------- /src/openflow/kandoo/KN_LLDPForwarding.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNLLDPAGENTFORWARDING_H_ 3 | #define KNLLDPAGENTFORWARDING_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/LLDPForwarding.h" 7 | #include "openflow/kandoo/KandooAgent.h" 8 | 9 | 10 | namespace openflow{ 11 | 12 | class KN_LLDPForwarding:public LLDPForwarding { 13 | 14 | 15 | public: 16 | KN_LLDPForwarding(); 17 | ~KN_LLDPForwarding(); 18 | 19 | protected: 20 | void receiveSignal(cComponent *src, simsignal_t id, cObject *obj, cObject *details) override; 21 | void initialize(int stage) override; 22 | virtual void handlePacketIn(Packet * packet_in_msg) override; 23 | 24 | KandooAgent * knAgent; 25 | simsignal_t kandooEventSignalId; 26 | simsignal_t cpPingPacketHash; 27 | std::string appName; 28 | 29 | 30 | }; 31 | 32 | } /*end namespace openflow*/ 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/openflow/kandoo/KN_LLDPForwarding.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.kandoo; 4 | import openflow.controllerApps.IControllerApp; 5 | 6 | 7 | simple KN_LLDPForwarding like IControllerApp 8 | { 9 | parameters: 10 | @class(openflow::KN_LLDPForwarding); 11 | @signal[KandooEvent]; 12 | @signal[pingPacketHash](type="long"); 13 | @statistic[pingPacketHash](title="PingPacketHash"; record=vector?,stats?; interpolationmode=none); 14 | @display("i=block/app"); 15 | int flowModHardTimeOut = default(0); 16 | int flowModIdleTimeOut = default(1); 17 | bool printMibGraph = default(false); 18 | bool dropIfNoRouteFound = default(true); 19 | bool ignoreArpRequests = default(false); 20 | int priority = default(1); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/openflow/kandoo/KandooAgent.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KANDOO_AGENT_H_ 3 | #define KANDOO_AGENT_H_ 4 | 5 | #include 6 | #include "openflow/controllerApps/AbstractTCPControllerApp.h" 7 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 8 | #include "openflow/messages/KN_Packet_m.h" 9 | 10 | namespace openflow{ 11 | 12 | struct SwitchControllerMapping { 13 | std::string switchId; 14 | std::string controllerId; 15 | TcpSocket *socket; 16 | }; 17 | 18 | class KandooAgent:public AbstractTCPControllerApp { 19 | 20 | 21 | public: 22 | KandooAgent(); 23 | ~KandooAgent(); 24 | 25 | bool getIsRootController(); 26 | 27 | void sendRequest(KandooEntry entry); 28 | void sendReply(Packet * knpck,KandooEntry entry); 29 | 30 | virtual void processPacketFromTcp(Packet *pkt) override; 31 | void handleKandooPacket(Packet * knpck); 32 | 33 | void sendReplyToSwitchAuthoritive(std::string switchId, KandooEntry entry); 34 | 35 | protected: 36 | virtual void socketDataArrived(TcpSocket *socket) override; 37 | virtual void socketAvailable(TcpSocket *listenerSocket, TcpAvailableInfo *availableInfo) override; 38 | 39 | virtual void initialize(int stage) override; 40 | virtual void processSelfMessage(cMessage *msg) override; 41 | virtual void processQueuedMsg(cMessage *data_msg) override; 42 | 43 | virtual void handleStartOperation(LifecycleOperation *operation) override; 44 | 45 | bool isRootController; 46 | 47 | std::list switchControllerMapping; 48 | 49 | simsignal_t kandooEventSignalId; 50 | 51 | TcpSocket *findSocketFor(cMessage *msg); 52 | std::map< int,TcpSocket * > socketMap; 53 | }; 54 | 55 | } /*end namespace openflow*/ 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/openflow/kandoo/KandooAgent.ned: -------------------------------------------------------------------------------- 1 | package openflow.kandoo; 2 | 3 | simple KandooAgent extends openflow.controllerApps.AbstractTCPControllerApp 4 | { 5 | parameters: 6 | @class(openflow::KandooAgent); 7 | @display("i=block/app"); 8 | @class(KandooAgent); 9 | @signal[KandooEvent]; 10 | int flowModHardTimeOut = default(0); 11 | int flowModIdleTimeOut = default(1); 12 | int localPort = default(-1); 13 | string localAddress = default(""); 14 | 15 | string connectAddressRootController = default("root_controller"); 16 | int connectPortRootController = default(1003); 17 | 18 | double connectAt @unit("s") = default(1s); 19 | 20 | bool isRootController = default(false); 21 | } 22 | -------------------------------------------------------------------------------- /src/openflow/messages/HF_ChangeNotification.msg: -------------------------------------------------------------------------------- 1 | 2 | 3 | import openflow.messages.HF_Packet; 4 | 5 | cplusplus {{ 6 | #include "openflow/hyperflow/HyperFlowStructs.h" 7 | }}; 8 | 9 | namespace openflow; 10 | 11 | class DataChannelEntry 12 | { 13 | @existingClass; 14 | @opaque; 15 | // @toString(.str()); 16 | } 17 | 18 | // When packets are received by the data plane and sent to the connected controller, 19 | // the OFP_PACKET_IN messages are used. If the complete packet needs to be sent to the controller, because it can not be 20 | // stored in the bufer, it is encapsulated in the packet-in message. 21 | class HF_ChangeNotification extends HF_Packet 22 | { 23 | DataChannelEntry entry; 24 | } 25 | -------------------------------------------------------------------------------- /src/openflow/messages/HF_Packet.msg: -------------------------------------------------------------------------------- 1 | 2 | import inet.common.INETDefs; 3 | import inet.common.packet.chunk.Chunk; 4 | 5 | namespace openflow; 6 | 7 | // When packets are received by the data plane and sent to the connected controller, 8 | // the OFP_PACKET_IN messages are used. If the complete packet needs to be sent to the controller, because it can not be 9 | // stored in the bufer, it is encapsulated in the packet-in message. 10 | class HF_Packet extends inet::FieldsChunk 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/openflow/messages/HF_ReportIn.msg: -------------------------------------------------------------------------------- 1 | 2 | import openflow.messages.HF_Packet; 3 | 4 | cplusplus {{ 5 | #include "openflow/openflow/controller/Switch_Info.h" 6 | namespace openflow{ 7 | typedef std::list SwitchInfoList; 8 | } /*end namespace openflow*/ 9 | }}; 10 | 11 | namespace openflow; 12 | 13 | class SwitchInfoList 14 | { 15 | @existingClass; 16 | @opaque; 17 | // @toString(.str()); 18 | } 19 | 20 | // When packets are received by the data plane and sent to the connected controller, 21 | // the OFP_PACKET_IN messages are used. If the complete packet needs to be sent to the controller, because it can not be 22 | // stored in the bufer, it is encapsulated in the packet-in message. 23 | class HF_ReportIn extends HF_Packet 24 | { 25 | string controllerId; 26 | SwitchInfoList switchInfoList; 27 | } 28 | -------------------------------------------------------------------------------- /src/openflow/messages/HF_SyncReply.msg: -------------------------------------------------------------------------------- 1 | 2 | import openflow.messages.HF_Packet; 3 | 4 | cplusplus {{ 5 | #include "openflow/hyperflow/HyperFlowStructs.h" 6 | namespace openflow{ 7 | typedef std::list ControlChannel; 8 | typedef std::list DataChannel; 9 | } 10 | }}; 11 | 12 | namespace openflow; 13 | 14 | class ControlChannel 15 | { 16 | @existingClass; 17 | @opaque; 18 | // @toString(.str()); 19 | } 20 | 21 | class DataChannel 22 | { 23 | @existingClass; 24 | @opaque; 25 | // @toString(.str()); 26 | } 27 | 28 | // When packets are received by the data plane and sent to the connected controller, 29 | // the OFP_PACKET_IN messages are used. If the complete packet needs to be sent to the controller, because it can not be 30 | // stored in the bufer, it is encapsulated in the packet-in message. 31 | class HF_SyncReply extends HF_Packet 32 | { 33 | ControlChannel controlChannel; 34 | DataChannel dataChannel; 35 | } 36 | -------------------------------------------------------------------------------- /src/openflow/messages/HF_SyncRequest.msg: -------------------------------------------------------------------------------- 1 | 2 | import openflow.messages.HF_Packet; 3 | 4 | namespace openflow; 5 | 6 | // When packets are received by the data plane and sent to the connected controller, 7 | // the OFP_PACKET_IN messages are used. If the complete packet needs to be sent to the controller, because it can not be 8 | // stored in the bufer, it is encapsulated in the packet-in message. 9 | class HF_SyncRequest extends HF_Packet 10 | { 11 | int lastSyncCounter; 12 | } 13 | -------------------------------------------------------------------------------- /src/openflow/messages/KN_Packet.msg: -------------------------------------------------------------------------------- 1 | 2 | import inet.common.INETDefs; 3 | import inet.common.packet.chunk.Chunk; 4 | 5 | cplusplus {{ 6 | #include "openflow/utility/KandooStructs.h" 7 | }}; 8 | 9 | namespace openflow; 10 | 11 | class KandooEntry 12 | { 13 | @existingClass; 14 | @opaque; 15 | // @toString(.str()); 16 | } 17 | 18 | // When packets are received by the data plane and sent to the connected controller, 19 | // the OFP_PACKET_IN messages are used. If the complete packet needs to be sent to the controller, because it can not be 20 | // stored in the bufer, it is encapsulated in the packet-in message. 21 | class KN_Packet extends inet::FieldsChunk { 22 | KandooEntry knEntry; 23 | } 24 | -------------------------------------------------------------------------------- /src/openflow/messages/LLDP.msg: -------------------------------------------------------------------------------- 1 | 2 | 3 | import inet.common.INETDefs; 4 | import inet.common.packet.chunk.Chunk; 5 | 6 | namespace openflow; 7 | 8 | // When packets are received by the data plane and sent to the connected controller, 9 | // the OFP_PACKET_IN messages are used. If the complete packet needs to be sent to the controller, because it can not be 10 | // stored in the bufer, it is encapsulated in the packet-in message. 11 | class LLDP extends inet::FieldsChunk { 12 | chunkLength = inet::B(21); // 3 TLV: TLV 6B+ variable length, at least 3*7 13 | int portID; 14 | string chassisID; 15 | double ttl; 16 | } -------------------------------------------------------------------------------- /src/openflow/messages/OFP_Features_Reply.msg: -------------------------------------------------------------------------------- 1 | 2 | import inet.linklayer.common.MacAddress; 3 | //import openflow.openflow.protocol.OpenFlow; 4 | import openflow.messages.Open_Flow_Message; 5 | 6 | namespace openflow; 7 | 8 | // response to an OFP_Features_Request message 9 | class OFP_Features_Reply extends Open_Flow_Message 10 | { 11 | string datapath_id; // Datapath unique ID. The lower 48-bits are for a MAC address, 12 | // while the upper 16-bits are implementer-defined. 13 | // MacAddress address; 14 | uint32_t n_buffers; // Max packets buffered at once. 15 | 16 | uint8_t n_tables; // Number of tables supported by datapath. 17 | 18 | //Features 19 | uint32_t capabilities; // Bitmap of support "ofp_capabilities". 20 | uint32_t reserved; 21 | 22 | //Port info 23 | uint32_t ports[]; //Port definitions. The number of ports is inferred from the 24 | // length field in the header. 25 | } 26 | -------------------------------------------------------------------------------- /src/openflow/messages/OFP_Features_Request.msg: -------------------------------------------------------------------------------- 1 | 2 | //import openflow.openflow.protocol.OpenFlow; 3 | import openflow.messages.Open_Flow_Message; 4 | 5 | namespace openflow; 6 | 7 | 8 | //Upon session establishment, the controller sends an OFP Features Request message 9 | //to get information about the capabilities of a switch. This message does 10 | //not contain a body beyond the OpenFlow header. The switch responds with an 11 | //OFP Features Reply message. 12 | class OFP_Features_Request extends Open_Flow_Message 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /src/openflow/messages/OFP_Flow_Mod.msg: -------------------------------------------------------------------------------- 1 | 2 | import openflow.messages.Open_Flow_Message; 3 | 4 | namespace openflow; 5 | 6 | // Modifications to a flow table by the controller. 7 | class OFP_Flow_Mod extends Open_Flow_Message 8 | { 9 | 10 | 11 | 12 | uint64_t cookie; // Opaque controller-issued identifier. 13 | uint64_t cookie_mask; // Mask used to restrict the cookie bits 14 | //that must match when the command is 15 | //OFPFC_MODIFY* or OFPFC_DELETE*. A value 16 | //of 0 indicates no restriction. 17 | // Flow actions. 18 | uint8_t table_id; // ID of the table to put the flow in. 19 | //For OFPFC_DELETE_* commands, OFPTT_ALL 20 | //can also be used to delete matching 21 | //flows from all tables. 22 | uint8_t command; // One of OFPFC_*. 23 | uint16_t idle_timeout; // Idle time before discarding (seconds). 24 | uint16_t hard_timeout; // Max time before discarding (seconds). 25 | uint16_t priority; // Priority level of flow entry. 26 | uint32_t buffer_id; // Buffered packet to apply to, or 27 | //OFP_NO_BUFFER. 28 | //Not meaningful for OFPFC_DELETE*. 29 | uint32_t out_port; // For OFPFC_DELETE* commands, require 30 | //matching entries to include this as an 31 | //output port. A value of OFPP_ANY 32 | //indicates no restriction. */ 33 | uint32_t out_group; // For OFPFC_DELETE* commands, require 34 | //matching entries to include this as an 35 | //output group. A value of OFPG_ANY 36 | //indicates no restriction. 37 | uint16_t flags; // One of OFPFF_*. 38 | uint8_t pad[2]; 39 | oxm_basic_match match; // Fields to match. Variable size. 40 | ofp_action_output actions[]; 41 | //struct ofp_instruction instructions[0]; // Instruction set 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/openflow/messages/OFP_Hello.msg: -------------------------------------------------------------------------------- 1 | 2 | import openflow.messages.Open_Flow_Message; 3 | 4 | namespace openflow; 5 | 6 | class OFP_Hello extends Open_Flow_Message 7 | { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/openflow/messages/OFP_Initialize_Handshake.msg: -------------------------------------------------------------------------------- 1 | 2 | import openflow.messages.Open_Flow_Message; 3 | 4 | namespace openflow; 5 | 6 | 7 | //Upon session establishment, the controller sends an OFP Features Request message 8 | //to get information about the capabilities of a switch. This message does 9 | //not contain a body beyond the OpenFlow header. The switch responds with an 10 | //OFP Features Reply message. 11 | class OFP_Initialize_Handshake extends Open_Flow_Message 12 | { 13 | } 14 | -------------------------------------------------------------------------------- /src/openflow/messages/OFP_Packet_In.msg: -------------------------------------------------------------------------------- 1 | 2 | import openflow.messages.Open_Flow_Message; 3 | 4 | namespace openflow; 5 | 6 | // When packets are received by the data plane and sent to the connected controller, 7 | // the OFP_PACKET_IN messages are used. If the complete packet needs to be sent to the controller, because it can not be 8 | // stored in the bufer, it is encapsulated in the packet-in message. 9 | class OFP_Packet_In extends Open_Flow_Message 10 | { 11 | uint32_t buffer_id; // ID assigned by datapath. 12 | uint16_t total_len; // Full length of frame. 13 | uint8_t reason; // Reason packet is being sent (one of OFPR_*) 14 | // EthernetIIFrame frame; 15 | oxm_basic_match match; 16 | // oxm_tlv tlv[]; 17 | // uint8_t data[0]; // Ethernet frame, halfway through 32-bit word, 18 | // so the IP header is 32-bit aligned. The 19 | // amount of data is inferred from the length 20 | // field in the header. Because of padding, 21 | // offsetof(struct ofp_packet_in, data) == 22 | // sizeof(struct ofp_packet_in) - 2. 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/openflow/messages/OFP_Packet_Out.msg: -------------------------------------------------------------------------------- 1 | 2 | import openflow.messages.Open_Flow_Message; 3 | 4 | 5 | namespace openflow; 6 | 7 | //When the controller decides to send a packet out through the data plane, it uses the 8 | //OFP PACKET OUT message. 9 | class OFP_Packet_Out extends Open_Flow_Message 10 | { 11 | uint32_t buffer_id; // ID assigned by datapath (OFP_NO_BUFFER 12 | //if none). 13 | uint32_t in_port; // Packet���s input port or OFPP_CONTROLLER. 14 | 15 | ofp_action_output actions[]; // Action list. 16 | // EthernetIIFrame frame; 17 | uint8_t data[]; // Packet data. The length is inferred 18 | //from the length field in the header. 19 | //(Only meaningful if buffer_id == -1.) 20 | } 21 | -------------------------------------------------------------------------------- /src/openflow/messages/OFP_Port_Mod.msg: -------------------------------------------------------------------------------- 1 | 2 | import openflow.messages.Open_Flow_Message; 3 | 4 | namespace openflow; 5 | 6 | class OFP_Port_Mod extends Open_Flow_Message 7 | { 8 | uint32_t port_no; 9 | //uint8_t pad[4]; 10 | uint8_t hw_addr[6]; 11 | //uint8_t pad2[2]; //Pad to 64 bits. 12 | uint32_t config; //Bitmap of OFPPC_* flags. 13 | uint32_t mask; //Bitmap of OFPPC_* flags to be changed. 14 | uint32_t advertise; //Bitmap of OFPPF_*. Zero all bits to prevent any action taking place. 15 | //uint8_t pad3[4]; //Pad to 64 bits 16 | } 17 | -------------------------------------------------------------------------------- /src/openflow/messages/OpenFlowStructs.msg: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU Lesser General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU Lesser General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU Lesser General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | 16 | cplusplus {{ 17 | #include "openflow/openflow/protocol/OpenFlow.h" 18 | 19 | namespace openflow { 20 | inline std::ostream& operator<<(std::ostream& os, oxm_basic_match match) 21 | { 22 | os << "OFB_ETH_TYPE: " << std::hex << match.OFB_ETH_TYPE << ", OFB_ETH_SRC: " << match.OFB_ETH_SRC; 23 | os << ", OFB_ETH_DST: " << match.OFB_ETH_DST << ", OFB_IN_PORT: " << match.OFB_IN_PORT << endl; 24 | os << ", OFB_ARP_OP: " << match.OFB_ARP_OP << ", OFB_ARP_SHA: " << match.OFB_ARP_SHA; 25 | os << ", OFB_ARP_THA: " << match.OFB_ARP_THA << ", OFB_ARP_SPA: " << match.OFB_ARP_SPA; 26 | os << ", OFB_ARP_TPA: " << match.OFB_ARP_TPA << endl; 27 | return os; 28 | } 29 | inline std::ostream& operator<<(std::ostream& os, ofp_action_output action) 30 | { 31 | os << "Port (hex): " << std::hex << action.port << endl; 32 | return os; 33 | } 34 | 35 | } // namespace openflow; 36 | }}; 37 | 38 | namespace openflow; 39 | 40 | class ofp_action_output 41 | { 42 | @existingClass; 43 | @opaque; 44 | // @toString(.str()); 45 | } 46 | 47 | class oxm_basic_match 48 | { 49 | @existingClass; 50 | @opaque; 51 | // @toString(.str()); 52 | } 53 | 54 | class ofp_header 55 | { 56 | @existingClass; 57 | @opaque; 58 | // @toString(.str()); 59 | } 60 | -------------------------------------------------------------------------------- /src/openflow/messages/Open_Flow_Message.msg: -------------------------------------------------------------------------------- 1 | 2 | import inet.common.INETDefs; 3 | import inet.common.packet.chunk.Chunk; 4 | import openflow.messages.OpenFlowStructs; 5 | 6 | namespace openflow; 7 | 8 | // base class for all OpenFlow protocol messages; only contains the OpenFlow header 9 | class Open_Flow_Message extends inet::FieldsChunk 10 | { 11 | ofp_header header; 12 | } 13 | -------------------------------------------------------------------------------- /src/openflow/nodes/DistanceChannel.ned: -------------------------------------------------------------------------------- 1 | 2 | package openflow.nodes; 3 | import inet.common.misc.ThruputMeteringChannel; 4 | 5 | 6 | // uses the geographical distance between two nodes and calculates the delay. 7 | channel DistanceChannel extends ThruputMeteringChannel 8 | { 9 | double distance @unit(m) = default(0m); 10 | delay = this.distance / 200000km * 1s; 11 | datarate = 10Gbps; 12 | thruputDisplayFormat = "u"; 13 | } 14 | -------------------------------------------------------------------------------- /src/openflow/nodes/DynamicFatTree.ned: -------------------------------------------------------------------------------- 1 | 2 | package openflow.nodes; 3 | 4 | import inet.common.misc.ThruputMeteringChannel; 5 | import inet.node.ethernet.EthernetSwitch; 6 | import inet.node.inet.StandardHost; 7 | import openflow.openflow.switch.Open_Flow_Switch; 8 | import inet.node.ethernet.Eth100M; 9 | 10 | // 11 | // OpenFlow domain consisting of an OpenFlow switch and several hosts, but NO controller. 12 | // 13 | 14 | module DynamicFatTree 15 | { 16 | parameters: 17 | @display("bgb=2277,571;i=misc/cloud;is=vs;bgl=2"); 18 | int K = default(4); 19 | 20 | int podNum = K; // Pod number in FatTree 21 | int coreSwitchNum = int(pow((K/2),2)); // Core switches 22 | int aggrSwitchNum = int((K/2)*K); // Aggregation switches 23 | int edgeSwitchNum = int((K/2)*K); // Edge switches 24 | int hostNum = int(K*pow((K/2),2)); // Hosts in K-ary FatTree 25 | 26 | gates: 27 | inout gateCPlane[] @labels(ControlPlane-conn); 28 | 29 | types: 30 | channel ethernetline extends Eth100M 31 | { 32 | length = 200m; //delay = 1us; 33 | //datarate = 100Mbps; 34 | //thruputDisplayFormat = "u"; 35 | } 36 | 37 | submodules: 38 | 39 | coreLayerSwitches[coreSwitchNum]: Open_Flow_Switch { 40 | @display("p=306,55,row,90"); 41 | } 42 | 43 | aggLayerSwitches[aggrSwitchNum]: Open_Flow_Switch { 44 | @display("p=522,200,row,90"); 45 | } 46 | 47 | edgeLayerSwitches[edgeSwitchNum]: Open_Flow_Switch { 48 | @display("p=345,393,row,90"); 49 | } 50 | 51 | etherSwitch: EthernetSwitch { 52 | @display("p=79,250"); 53 | } 54 | 55 | client[hostNum]: StandardHost { 56 | @display("p=182,470,row,90"); 57 | } 58 | 59 | connections allowunconnected: 60 | 61 | for pod=0..podNum-1, for aggr=0..int((aggrSwitchNum/podNum))-1, for x=int(((K/2)*aggr))..int(((K/2)*(aggr+1))-1) { 62 | aggLayerSwitches[int(aggr+pod*(aggrSwitchNum/podNum))].gateDataPlane++ <--> ethernetline <--> coreLayerSwitches[x].gateDataPlane++; 63 | } 64 | 65 | for pod=0..podNum-1, for edge=0..int((edgeSwitchNum/podNum)-1), for x=int((edgeSwitchNum/podNum)*pod)..int(((edgeSwitchNum/podNum)*(pod+1))-1) { 66 | edgeLayerSwitches[int(edge+pod*(edgeSwitchNum/podNum))].gateDataPlane++ <--> ethernetline <--> aggLayerSwitches[x].gateDataPlane++; 67 | } 68 | 69 | for pod=0..podNum-1, for edge=0..int((edgeSwitchNum/podNum)-1), for x=0..int((hostNum/podNum/(edgeSwitchNum/podNum))-1) { 70 | edgeLayerSwitches[int(edge+pod*(edgeSwitchNum/podNum))].gateDataPlane++ <--> ethernetline <--> client[int(x+(edge+(pod*(edgeSwitchNum/podNum)))*(hostNum/podNum/(edgeSwitchNum/podNum)))].ethg++; 71 | } 72 | 73 | 74 | //cplane 75 | for i=0..(coreSwitchNum)-1 { 76 | coreLayerSwitches[i].gateControlPlane++ <--> ethernetline <--> etherSwitch.ethg++; 77 | } 78 | for i=0..(aggrSwitchNum)-1 { 79 | aggLayerSwitches[i].gateControlPlane++ <--> ethernetline <--> etherSwitch.ethg++; 80 | } 81 | for i=0..(edgeSwitchNum)-1 { 82 | edgeLayerSwitches[i].gateControlPlane++ <--> ethernetline <--> etherSwitch.ethg++; 83 | } 84 | 85 | for i=0..sizeof(gateCPlane)-1 { 86 | gateCPlane[i] <--> etherSwitch.ethg++; 87 | } 88 | 89 | } 90 | 91 | -------------------------------------------------------------------------------- /src/openflow/nodes/Fat_Tree.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.nodes; 4 | 5 | import inet.common.misc.ThruputMeteringChannel; 6 | import inet.node.ethernet.EthernetSwitch; 7 | import inet.node.inet.StandardHost; 8 | import openflow.openflow.switch.Open_Flow_Switch; 9 | 10 | 11 | // 12 | // OpenFlow domain consisting of an OpenFlow switch and several hosts, but NO controller. 13 | // 14 | module Fat_Tree 15 | { 16 | parameters: 17 | @display("bgb=2277,571;i=misc/cloud;is=vs;bgl=2"); 18 | int iNumber = default(4); 19 | 20 | gates: 21 | inout gateCPlane[] @labels(ControlPlane-conn); 22 | 23 | types: 24 | channel ethernetline extends ThruputMeteringChannel 25 | { 26 | delay = 1us; 27 | datarate = 100Mbps; 28 | thruputDisplayFormat = "u"; 29 | } 30 | submodules: 31 | 32 | coreLayerSwitches[iNumber]: Open_Flow_Switch { 33 | @display("p=306,55,row,90"); 34 | } 35 | 36 | aggLayerSwitches[iNumber*2]: Open_Flow_Switch { 37 | @display("p=306,200,row,90"); 38 | } 39 | 40 | edgeLayerSwitches[iNumber*2]: Open_Flow_Switch { 41 | @display("p=306,306,row,90"); 42 | } 43 | 44 | etherSwitch: EthernetSwitch { 45 | @display("p=79,200"); 46 | } 47 | 48 | client[iNumber*2*2]: StandardHost { 49 | @display("p=306,434,row,90"); 50 | } 51 | 52 | connections allowunconnected: 53 | 54 | //core to agg 55 | 56 | for i=0..(iNumber*2)-1 { 57 | coreLayerSwitches[0].gateDataPlane++ <--> ethernetline <--> aggLayerSwitches[i].gateDataPlane++ if i%2==0; 58 | coreLayerSwitches[1].gateDataPlane++ <--> ethernetline <--> aggLayerSwitches[i].gateDataPlane++ if i%2==0; 59 | } 60 | 61 | for i=0..(iNumber*2)-1 { 62 | coreLayerSwitches[2].gateDataPlane++ <--> ethernetline <--> aggLayerSwitches[i].gateDataPlane++ if i%2==1; 63 | coreLayerSwitches[3].gateDataPlane++ <--> ethernetline <--> aggLayerSwitches[i].gateDataPlane++ if i%2==1; 64 | } 65 | 66 | //agg to edge 67 | for i=0..(iNumber*2)-1 { 68 | aggLayerSwitches[i].gateDataPlane++ <--> ethernetline <--> edgeLayerSwitches[i].gateDataPlane++ if i%2==0; 69 | aggLayerSwitches[i].gateDataPlane++ <--> ethernetline <--> edgeLayerSwitches[i+1].gateDataPlane++ if i%2==0; 70 | aggLayerSwitches[i+1].gateDataPlane++ <--> ethernetline <--> edgeLayerSwitches[i].gateDataPlane++ if i%2==0; 71 | aggLayerSwitches[i+1].gateDataPlane++ <--> ethernetline <--> edgeLayerSwitches[i+1].gateDataPlane++ if i%2==0; 72 | } 73 | 74 | //edge to host 75 | for i=0..(iNumber*2)-1 { 76 | edgeLayerSwitches[i].gateDataPlane++ <--> ethernetline <--> client[i*2].ethg++; 77 | edgeLayerSwitches[i].gateDataPlane++ <--> ethernetline <--> client[(i*2)+1].ethg++; 78 | } 79 | 80 | //cplane 81 | for i=0..(iNumber)-1 { 82 | coreLayerSwitches[i].gateControlPlane++ <--> ethernetline <--> etherSwitch.ethg++; 83 | } 84 | for i=0..(iNumber*2)-1 { 85 | aggLayerSwitches[i].gateControlPlane++ <--> ethernetline <--> etherSwitch.ethg++; 86 | } 87 | for i=0..(iNumber*2)-1 { 88 | edgeLayerSwitches[i].gateControlPlane++ <--> ethernetline <--> etherSwitch.ethg++; 89 | } 90 | 91 | for i=0..sizeof(gateCPlane)-1 { 92 | gateCPlane[i] <--> etherSwitch.ethg++; 93 | } 94 | 95 | } 96 | 97 | -------------------------------------------------------------------------------- /src/openflow/nodes/Open_Flow_Domain.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.nodes; 4 | 5 | import inet.common.misc.ThruputMeteringChannel; 6 | import inet.node.ethernet.EthernetSwitch; 7 | import inet.node.inet.StandardHost; 8 | import openflow.openflow.switch.Open_Flow_Switch; 9 | 10 | 11 | // 12 | // OpenFlow domain consisting of an OpenFlow switch and several hosts, but NO controller. 13 | // 14 | module Open_Flow_Domain 15 | { 16 | parameters: 17 | @display("bgb=347,267;i=misc/cloud;is=vs;bgl=2"); 18 | int numClients = default(0); 19 | int domainID = default(-1); 20 | 21 | gates: 22 | inout gateDPlane[] @labels(DataPlane-conn); 23 | inout gateCPlane[] @labels(ControlPlane-conn); 24 | types: 25 | channel ethernetline extends ThruputMeteringChannel 26 | { 27 | delay = 1us; 28 | datarate = 100Mbps; 29 | thruputDisplayFormat = "u"; 30 | } 31 | submodules: 32 | open_flow_switch: Open_Flow_Switch { 33 | @display("p=120,186"); 34 | } 35 | 36 | etherSwitch: EthernetSwitch { 37 | @display("p=240,186"); 38 | } 39 | 40 | client[this.numClients]: StandardHost { 41 | @display("p=120,50,row,90"); 42 | } 43 | connections allowunconnected: 44 | for i=0..sizeof(gateDPlane)-1 { 45 | gateDPlane[i] <--> open_flow_switch.gateDataPlane++; 46 | } 47 | 48 | for i=0..numClients-1 { 49 | client[i].ethg++ <--> ethernetline <--> open_flow_switch.gateDataPlane++; 50 | } 51 | 52 | for i=0..sizeof(gateCPlane)-1 { 53 | etherSwitch.ethg++ <--> gateCPlane[i]; 54 | } 55 | 56 | etherSwitch.ethg++ <--> ethernetline <--> open_flow_switch.gateControlPlane++; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/openflow/openflow/controller/IOpenFlowController.ned: -------------------------------------------------------------------------------- 1 | 2 | package openflow.openflow.controller; 3 | 4 | // 5 | // Interface for OpenFlow controller implementations. 6 | // 7 | // The OpenFlow controller is responsible for: 8 | // 9 | // 1. Establishing and maintaining connections with OpenFlow switches 10 | // 2. Processing OpenFlow protocol messages (HELLO, FEATURES_REQUEST, PACKET_IN, etc.) 11 | // 3. Managing the network by installing flow entries in switches 12 | // 4. Providing an interface for controller applications to implement network control logic 13 | // 14 | moduleinterface IOpenFlowController 15 | { 16 | parameters: 17 | // IP address the controller listens on 18 | string address; 19 | 20 | // TCP port the controller listens on (standard OpenFlow port is 6633) 21 | int port; 22 | 23 | // Processing time for each message (used to simulate controller processing delay) 24 | double serviceTime @unit("s"); 25 | 26 | // Time before the controller is fully operational (boot delay) 27 | double bootTime @unit("s"); 28 | 29 | gates: 30 | input socketIn @labels(TcpCommand/up); 31 | output socketOut @labels(TcpCommand/down); 32 | } 33 | -------------------------------------------------------------------------------- /src/openflow/openflow/controller/OF_Controller.ned: -------------------------------------------------------------------------------- 1 | 2 | package openflow.openflow.controller; 3 | 4 | // 5 | // [GENERATED DOCUMENTATION -- ACCURACY UNVERIFIED] 6 | // The OF_Controller is the core module that implements the OpenFlow controller functionality 7 | // in the openflow simulation model. It handles the communication with OpenFlow switches, 8 | // processes OpenFlow protocol messages, and provides an interface for controller applications. 9 | // 10 | // The OF_Controller is responsible for: 11 | // 12 | // 1. Connection Management: Establishing and maintaining TCP connections with OpenFlow switches. 13 | // It handles the OpenFlow handshake process (HELLO, FEATURES_REQUEST, FEATURES_REPLY) and 14 | // maintains information about connected switches. 15 | // 16 | // 2. Message Processing: Processing OpenFlow protocol messages received from switches, such as 17 | // PACKET_IN, FEATURES_REPLY, and EXPERIMENTER messages. It also sends messages to switches, 18 | // such as PACKET_OUT and FLOW_MOD messages. 19 | // 20 | // 3. Controller Application Interface: Providing an interface for controller applications to 21 | // register themselves and receive notifications about OpenFlow events. It emits signals for 22 | // various events (PacketIn, PacketOut, etc.) that controller applications can subscribe to. 23 | // 24 | // 4. Switch Information Management: Maintaining a list of connected switches and their capabilities, 25 | // which can be accessed by controller applications. 26 | // 27 | // The OF_Controller is typically used as a submodule within the Open_Flow_Controller compound module, 28 | // which combines it with standard networking components (TCP/IP stack, Ethernet interfaces) and 29 | // controller applications to form a complete OpenFlow controller. 30 | // 31 | simple OF_Controller like IOpenFlowController 32 | { 33 | parameters: 34 | @class(openflow::OF_Controller); 35 | @signal[PacketIn](type="cPacket"); 36 | @signal[PacketOut](type="cPacket"); 37 | @signal[PacketHello](type="cPacket"); 38 | @signal[PacketFeatureRequest](type="cPacket"); 39 | @signal[PacketFeatureReply](type="cPacket"); 40 | @signal[PacketExperimenter](type="cPacket"); 41 | @signal[Booted](type="openflow::OF_Controller"); 42 | @signal[queueSize](type="unsigned long"); 43 | @statistic[queueSize](title="QueueSize"; record=vector?,stats?; interpolationmode=none); 44 | @signal[waitingTime](type="simtime_t"); 45 | @statistic[waitingTime](title="WaitingTime"; record=vector?,stats?; interpolationmode=none); 46 | @display("i=block/app"); 47 | 48 | // IP address the controller listens on (empty string means all available interfaces) 49 | string address = default(""); 50 | 51 | // TCP port the controller listens on (standard OpenFlow port is 6633) 52 | int port = default(6633); 53 | 54 | // Processing time for each message (used to simulate controller processing delay) 55 | double serviceTime @unit("s") = default(0s); 56 | 57 | // Time before the controller is fully operational (boot delay) 58 | double bootTime @unit("s") = default(0s); 59 | 60 | // Whether to process messages in parallel (true) or sequentially (false) 61 | // When false, messages are processed one at a time with serviceTime delay between them 62 | // When true, multiple messages can be processed simultaneously 63 | bool parallelProcessing = default(false); 64 | 65 | gates: 66 | input socketIn @labels(TcpCommand/up); 67 | output socketOut @labels(TcpCommand/down); 68 | } 69 | -------------------------------------------------------------------------------- /src/openflow/openflow/controller/Switch_Info.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "openflow/openflow/controller/Switch_Info.h" 3 | 4 | using namespace std; 5 | 6 | namespace openflow{ 7 | 8 | Switch_Info::Switch_Info(){ 9 | 10 | } 11 | 12 | 13 | int Switch_Info::getConnId() const { 14 | return connID; 15 | } 16 | 17 | void Switch_Info::setConnId(int connId) { 18 | connID = connId; 19 | } 20 | 21 | int Switch_Info::getVersion() const { 22 | return connID; 23 | } 24 | 25 | void Switch_Info::setVersion(int version) { 26 | this->version = version; 27 | } 28 | 29 | 30 | string Switch_Info::getMacAddress() const { 31 | return macAddress; 32 | } 33 | 34 | void Switch_Info::setMacAddress(string macAddress) { 35 | this->macAddress = macAddress; 36 | } 37 | 38 | int Switch_Info::getNumOfPorts() const { 39 | return numOfPorts; 40 | } 41 | 42 | void Switch_Info::setNumOfPorts(int numOfPorts) { 43 | this->numOfPorts = numOfPorts; 44 | if (numOfPorts > 0) { 45 | this->idPort.resize(numOfPorts); 46 | std::fill(this->idPort.begin(), this->idPort.end(), -1); 47 | } 48 | else 49 | this->idPort.clear(); 50 | } 51 | 52 | void Switch_Info::setSwitchPortsIndexId(const int &index, const int &id) { 53 | if (index >= (int) this->idPort.size() || index < 0) 54 | throw cRuntimeError("Index port doesn't exist"); 55 | this->idPort[index] = id; 56 | } 57 | 58 | 59 | int Switch_Info::getIndexPort(const int &index) { 60 | if (index >= (int) this->idPort.size() || index < 0) 61 | throw cRuntimeError("Index port doesn't exist"); 62 | return this->idPort[index]; 63 | } 64 | 65 | int Switch_Info::getIdPort(const int &id) { 66 | auto it = std::find(this->idPort.begin(), this->idPort.end(), id); 67 | if (it == this->idPort.end()) 68 | return -1; 69 | return (*it); 70 | } 71 | 72 | 73 | TcpSocket* Switch_Info::getSocket() const { 74 | return socket; 75 | } 76 | 77 | void Switch_Info::setSocket(TcpSocket* socket) { 78 | this->socket = socket; 79 | } 80 | 81 | } /*end namespace openflow*/ 82 | -------------------------------------------------------------------------------- /src/openflow/openflow/controller/Switch_Info.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SWITCH_INFO_H_ 3 | #define SWITCH_INFO_H_ 4 | 5 | #include "openflow/openflow/protocol/OpenFlow.h" 6 | #include "inet/transportlayer/contract/tcp/TcpSocket.h" 7 | 8 | using namespace __gnu_cxx; 9 | using namespace inet; 10 | 11 | namespace openflow{ 12 | 13 | class Switch_Info { 14 | public: 15 | Switch_Info(); 16 | 17 | int getConnId() const; 18 | void setConnId(int connId); 19 | int getVersion() const; 20 | void setVersion(int version); 21 | std::string getMacAddress() const; 22 | void setMacAddress(std::string macAddress); 23 | int getNumOfPorts() const; 24 | void setNumOfPorts(int numOfPorts); 25 | TcpSocket* getSocket() const; 26 | void setSocket(TcpSocket* socket); 27 | 28 | void setSwitchPortsIndexId(const int &, const int &); 29 | 30 | 31 | int getIndexPort(const int&); 32 | int getIdPort(const int&); 33 | 34 | 35 | protected: 36 | std::vector idPort; 37 | 38 | int connID; 39 | int numOfPorts; 40 | std::string macAddress; 41 | TcpSocket *socket; 42 | int version; 43 | 44 | }; 45 | 46 | } /*end namespace openflow*/ 47 | 48 | #endif /* FLOW_TABLE_H_ */ 49 | -------------------------------------------------------------------------------- /src/openflow/openflow/protocol/OF100MatchBuilder.h: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | // c Timo Haeckel, for HAW Hamburg 16 | // 17 | 18 | #ifndef OPENFLOW_OPENFLOW_PROTOCOL_OF100MATCHBUILDER_H_ 19 | #define OPENFLOW_OPENFLOW_PROTOCOL_OF100MATCHBUILDER_H_ 20 | 21 | #include 22 | 23 | namespace openflow { 24 | 25 | class OF100MatchBuilder : public OFMatchBuilder{ 26 | public: 27 | OF100MatchBuilder() : OFMatchBuilder(){} 28 | virtual ~OF100MatchBuilder(){} 29 | 30 | virtual OFMatchBuilder* setField(oxm_ofb_match_fields field, void* value); 31 | 32 | }; 33 | 34 | } /* namespace openflow */ 35 | 36 | #endif /* OPENFLOW_OPENFLOW_PROTOCOL_OF100MATCHBUILDER_H_ */ 37 | -------------------------------------------------------------------------------- /src/openflow/openflow/protocol/OF100MessageFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | // c Timo Haeckel, for HAW Hamburg 16 | // 17 | 18 | 19 | #ifndef OPENFLOW_OPENFLOW_UTIL_OF100MESSAGEFACTORY_H_ 20 | #define OPENFLOW_OPENFLOW_UTIL_OF100MESSAGEFACTORY_H_ 21 | 22 | #include "openflow/openflow/protocol/OFMessageFactory.h" 23 | 24 | namespace openflow { 25 | 26 | /** 27 | * Implementing the openflow message factory interface for OpenFlow Version 1.0.0 28 | * 29 | * @author Timo Haeckel, for HAW Hamburg 30 | */ 31 | class OF100MessageFactory: public OFMessageFactory { 32 | friend OFMessageFactory; 33 | protected: 34 | OF100MessageFactory(); 35 | virtual ~OF100MessageFactory(); 36 | 37 | public: 38 | virtual Packet* createFeaturesReply(std::string dpid, uint32_t n_buffers, uint8_t n_tables, uint32_t capabilities, uint32_t n_ports = 0) override; 39 | virtual Packet* createFeatureRequest() override; 40 | virtual Packet* createFlowModMessage(ofp_flow_mod_command mod_com,const oxm_basic_match& match, int pritority, uint32_t* outports, int n_outports, uint32_t idleTimeOut=1 , uint32_t hardTimeOut=0) override; 41 | virtual Packet* createHello() override; 42 | virtual Packet* createPacketIn(ofp_packet_in_reason reason, inet::Packet *ethPk, uint32_t buffer_id, bool sendFullFrame) override; 43 | virtual Packet* createPacketOut(uint32_t* outports, int n_outports, int in_port, uint32_t buffer_id = OFP_NO_BUFFER, inet::Packet *ethPk = nullptr) override; 44 | }; 45 | 46 | } /* namespace openflow */ 47 | 48 | #endif /* OPENFLOW_OPENFLOW_UTIL_OF100MESSAGEFACTORY_H_ */ 49 | -------------------------------------------------------------------------------- /src/openflow/openflow/protocol/OFMatchFactory.cc: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | // c Timo Haeckel, for HAW Hamburg 16 | // 17 | 18 | #include "openflow/openflow/protocol/OFMatchFactory.h" 19 | #include "openflow/openflow/protocol/OF100MatchBuilder.h" 20 | #include 21 | 22 | using namespace std; 23 | 24 | namespace openflow { 25 | 26 | std::unique_ptr OFMatchFactory::getBuilder(){ 27 | #if OFP_VERSION_IN_USE == OFP_100 28 | return std::unique_ptr(new OF100MatchBuilder()); 29 | #endif 30 | } 31 | 32 | } /* namespace openflow */ 33 | -------------------------------------------------------------------------------- /src/openflow/openflow/protocol/OFMatchFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | // c Timo Haeckel, for HAW Hamburg 16 | // 17 | 18 | 19 | #ifndef OPENFLOW_OPENFLOW_UTIL_OFMATCHFACTORY_H_ 20 | #define OPENFLOW_OPENFLOW_UTIL_OFMATCHFACTORY_H_ 21 | 22 | #include "openflow/openflow/protocol/OpenFlow.h" 23 | #include 24 | 25 | namespace openflow { 26 | class OFMatchBuilder; 27 | } 28 | 29 | namespace openflow { 30 | 31 | /** 32 | * Class for static OFMatchFactory creation. 33 | * Provides access to a match factory for the openflow version currently in use. 34 | * 35 | * @author Timo Haeckel, for HAW Hamburg 36 | */ 37 | class OFMatchFactory { 38 | public: 39 | /** 40 | * Creates a match builder for the current openflow version. Make sure to delete it! 41 | */ 42 | static std::unique_ptr getBuilder(); 43 | }; 44 | 45 | class OFMatchBuilder { 46 | public: 47 | OFMatchBuilder(){ 48 | match.wildcards = OFPFW_ALL; 49 | } 50 | virtual ~OFMatchBuilder(){} 51 | 52 | /** 53 | * Set one field defined in the openflow protocol with the value. 54 | * @param oxm_ofb_match_fields the field to set 55 | * @param value the value to set for the field 56 | * 57 | * @return this match builder 58 | */ 59 | virtual OFMatchBuilder* setField(oxm_ofb_match_fields field, void* value) = 0; 60 | 61 | oxm_basic_match build(){ 62 | return match; 63 | } 64 | protected: 65 | oxm_basic_match match; 66 | }; 67 | 68 | } /* namespace openflow */ 69 | 70 | #endif /* OPENFLOW_OPENFLOW_UTIL_OFMATCHFACTORY_H_ */ 71 | -------------------------------------------------------------------------------- /src/openflow/openflow/protocol/OFMessageFactory.cc: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | // c Timo Haeckel, for HAW Hamburg 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | namespace openflow { 23 | 24 | OFMessageFactory* OFMessageFactory::instance() { 25 | static OFMessageFactory* _messageFactoryInstance = nullptr; 26 | if (!_messageFactoryInstance) { 27 | #if OFP_VERSION_IN_USE == OFP_100 28 | _messageFactoryInstance = new OF100MessageFactory(); 29 | #endif 30 | } 31 | return _messageFactoryInstance; 32 | } 33 | ; 34 | 35 | } /* namespace openflow */ 36 | -------------------------------------------------------------------------------- /src/openflow/openflow/protocol/OpenFlow.h: -------------------------------------------------------------------------------- 1 | #ifndef __OPENFLOW_OPENFLOW_H 2 | #define __OPENFLOW_OPENFLOW_H 3 | 4 | 5 | #include 6 | 7 | #define OFP_100 0x01 8 | #define OFP_135 0x04 //currently not supported. 9 | #define OFP_141 0x05 //currently not supported. 10 | #define OFP_151 0x06 //currently not supported. 11 | 12 | #if INET_VERSION < 0x0404 || INET_VERSION == 0x0404 && INET_PATCH_LEVEL < 0x02 13 | #error OpenFlow: Incompatible INET version. At least INET version v4.4.2 required. 14 | #endif 15 | 16 | #ifndef OFP_VERSION_IN_USE 17 | #define OFP_VERSION_IN_USE OFP_100 18 | #endif 19 | 20 | //#if OFP_VERSION_IN_USE == OFP_100 21 | #include 22 | //#elif OFP_VERSION_IN_USE == OFP_135 23 | ////TODO add implementation for ofp135 24 | // #include 25 | // 26 | //#elif OFP_VERSION_IN_USE == OFP_141 27 | ////TODO add implementation for ofp141 28 | // #include 29 | // 30 | //#elif OFP_VERSION_IN_USE == OFP_151 31 | ////TODO add implementation for ofp151 32 | // #include 33 | // 34 | //#endif 35 | // 36 | 37 | #endif // __OPENFLOW_OPENFLOW_H 38 | -------------------------------------------------------------------------------- /src/openflow/openflow/switch/Buffer.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "openflow/openflow/switch/Buffer.h" 3 | #include "openflow/openflow/protocol/OpenFlow.h" 4 | #include "inet/linklayer/ethernet/common/EthernetMacHeader_m.h" 5 | 6 | using namespace std; 7 | using namespace inet; 8 | 9 | namespace openflow{ 10 | 11 | Buffer::Buffer(){ 12 | 13 | } 14 | 15 | Buffer::Buffer(int cap){ 16 | capacity = cap; 17 | next_buffer_id = 1; 18 | } 19 | 20 | Buffer::~Buffer(){ 21 | for(auto&& pair : pending_msgs) { 22 | delete pair.second; 23 | } 24 | pending_msgs.clear(); 25 | } 26 | 27 | int Buffer::size(){ 28 | return pending_msgs.size(); 29 | } 30 | 31 | bool Buffer::isfull(){ 32 | return pending_msgs.size() >= capacity; 33 | } 34 | 35 | 36 | 37 | 38 | // store message in buffer and return buffer_id. 39 | uint32_t Buffer::storeMessage(Packet *msg){ 40 | auto header = msg->peekAtFront(); 41 | pending_msgs.insert(pair (next_buffer_id, msg)); 42 | 43 | // OFP_NO_BUFFER = 0xffffffff; 44 | if (next_buffer_id != OFP_NO_BUFFER){ 45 | uint32_t result = next_buffer_id; 46 | next_buffer_id++; 47 | return result; 48 | }else{ 49 | next_buffer_id = 0; 50 | return next_buffer_id; 51 | } 52 | } 53 | bool Buffer::deleteMessage(Packet *msg){ 54 | for (auto it = pending_msgs.begin(); it != pending_msgs.end(); ++it) { 55 | if (it->second == msg) { 56 | it = pending_msgs.erase(it); 57 | return true; 58 | } 59 | } 60 | 61 | return false; 62 | } 63 | 64 | 65 | uint32_t Buffer::getCapacity(){ 66 | return capacity; 67 | } 68 | 69 | // return message that is stored at the specified buffer_id 70 | Packet *Buffer::returnMessage(uint32_t buffer_id){ 71 | auto it = pending_msgs.find(buffer_id); 72 | Packet *frame = nullptr; 73 | if (it != pending_msgs.end()) { 74 | frame = it->second; 75 | pending_msgs.erase(it); 76 | } 77 | return frame; 78 | } 79 | 80 | } /*end namespace openflow*/ 81 | -------------------------------------------------------------------------------- /src/openflow/openflow/switch/Buffer.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef BUFFER_H_ 4 | #define BUFFER_H_ 5 | 6 | #include 7 | #include 8 | #include "inet/common/packet/Packet.h" 9 | 10 | 11 | using namespace std; 12 | using namespace inet; 13 | 14 | namespace openflow{ 15 | 16 | class Buffer { 17 | 18 | public: 19 | Buffer(); 20 | Buffer(int cap); 21 | ~Buffer(); 22 | bool isfull(); 23 | uint32_t storeMessage(Packet *msg); 24 | bool deleteMessage(Packet *msg); 25 | Packet *returnMessage(uint32_t buffer_id); 26 | uint32_t getCapacity(); 27 | int size(); 28 | 29 | 30 | protected: 31 | std::map pending_msgs; 32 | uint32_t capacity; 33 | uint32_t next_buffer_id; 34 | }; 35 | 36 | 37 | } /*end namespace openflow*/ 38 | 39 | #endif /* BUFFER_H_ */ 40 | -------------------------------------------------------------------------------- /src/openflow/openflow/switch/Flow_Table.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "inet/linklayer/ethernet/common/EthernetMacHeader_m.h" 3 | #include "inet/linklayer/common/MacAddress.h" 4 | #include "inet/networklayer/arp/ipv4/ArpPacket_m.h" 5 | #include "openflow/openflow/switch/Flow_Table.h" 6 | 7 | using namespace std; 8 | 9 | namespace openflow{ 10 | 11 | Flow_Table::Flow_Table() { 12 | 13 | } 14 | 15 | Flow_Table::~Flow_Table() { 16 | clear(); 17 | } 18 | 19 | 20 | static inline int flow_fields_match(const oxm_basic_match &m1, const oxm_basic_match &m2, const uint32_t w){ 21 | return (((w & OFPFW_IN_PORT) || m1.OFB_IN_PORT == m2.OFB_IN_PORT) 22 | && ((w & OFPFW_DL_TYPE) || m1.OFB_ETH_TYPE == m2.OFB_ETH_TYPE ) 23 | && ((w & OFPFW_DL_SRC) || !m1.OFB_ETH_SRC.compareTo(m2.OFB_ETH_SRC)) 24 | && ((w & OFPFW_DL_DST) || !m1.OFB_ETH_DST.compareTo(m2.OFB_ETH_DST))); 25 | } 26 | 27 | void Flow_Table::addEntry(Flow_Table_Entry entry) { 28 | entryList.push_front(entry); 29 | } 30 | 31 | 32 | 33 | Flow_Table_Entry* Flow_Table::lookup(oxm_basic_match &match) { 34 | EV << "Looking through " << entryList.size() << " Flow Entries!" << '\n'; 35 | 36 | for(auto iter = entryList.begin(); iter != entryList.end();){ 37 | //check if flow has expired 38 | if ((*iter).getExpiresAt() < simTime()){ 39 | iter = entryList.erase(iter); 40 | continue; 41 | } 42 | if (flow_fields_match(match, (*iter).getMatch(), (*iter).getMatch().wildcards)){ 43 | //adapt idle timer filed if neccessary 44 | if ((*iter).getIdleTimeout() != 0){ 45 | (*iter).setExpiresAt((*iter).getIdleTimeout()+simTime()); 46 | } 47 | return &(*iter); 48 | } 49 | ++iter; 50 | } 51 | return NULL; 52 | } 53 | 54 | void Flow_Table::clear() { 55 | entryList.clear(); 56 | } 57 | 58 | } /*end namespace openflow*/ 59 | -------------------------------------------------------------------------------- /src/openflow/openflow/switch/Flow_Table.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLOW_TABLE_H_ 3 | #define FLOW_TABLE_H_ 4 | 5 | #include 6 | #include "openflow/openflow/protocol/OpenFlow.h" 7 | #include "openflow/openflow/switch/Flow_Table_Entry.h" 8 | 9 | using namespace __gnu_cxx; 10 | 11 | 12 | namespace openflow{ 13 | 14 | class Flow_Table { 15 | public: 16 | Flow_Table(); 17 | virtual ~Flow_Table(); 18 | void addEntry(Flow_Table_Entry entry); 19 | Flow_Table_Entry * lookup(oxm_basic_match &match); 20 | void removeExpiredEntries(); 21 | /** 22 | * @brief For lifecycle: clears all entries from the table. 23 | */ 24 | virtual void clear(); 25 | 26 | 27 | private: 28 | std::list entryList; 29 | }; 30 | 31 | 32 | 33 | } /*end namespace openflow*/ 34 | 35 | #endif /* FLOW_TABLE_H_ */ 36 | -------------------------------------------------------------------------------- /src/openflow/openflow/switch/Flow_Table_Entry.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "inet/linklayer/ethernet/common/EthernetMacHeader_m.h" 3 | #include "inet/linklayer/common/MacAddress.h" 4 | #include "inet/networklayer/arp/ipv4/ArpPacket_m.h" 5 | #include "openflow/openflow/switch/Flow_Table_Entry.h" 6 | 7 | using namespace std; 8 | 9 | namespace openflow{ 10 | 11 | Flow_Table_Entry::Flow_Table_Entry(){ 12 | idleTimeout = 0.; 13 | hardTimeout = 0.; 14 | } 15 | 16 | Flow_Table_Entry::Flow_Table_Entry(const OFP_Flow_Mod *flowModMsg){ 17 | match = flowModMsg->getMatch(); 18 | 19 | instructions[0] = flowModMsg->getActions(0); 20 | 21 | priority = flowModMsg->getPriority(); 22 | hardTimeout = flowModMsg->getHard_timeout(); 23 | idleTimeout = flowModMsg->getIdle_timeout(); 24 | 25 | if(idleTimeout != 0){ 26 | expiresAt = idleTimeout+simTime(); 27 | } else { 28 | expiresAt = hardTimeout+simTime(); 29 | } 30 | } 31 | 32 | flow_table_cookie Flow_Table_Entry::getCookie() const{ 33 | return cookie; 34 | } 35 | 36 | flow_table_counters Flow_Table_Entry::getCounters() const{ 37 | return counters; 38 | } 39 | 40 | flow_table_flags Flow_Table_Entry::getFlags() const{ 41 | return flags; 42 | } 43 | 44 | double Flow_Table_Entry::getHardTimeout() const{ 45 | return hardTimeout; 46 | } 47 | 48 | double Flow_Table_Entry::getIdleTimeout() const{ 49 | return idleTimeout; 50 | } 51 | 52 | SimTime Flow_Table_Entry::getExpiresAt() const{ 53 | return expiresAt; 54 | } 55 | 56 | ofp_action_output Flow_Table_Entry::getInstructions() const{ 57 | return instructions[0]; 58 | } 59 | 60 | oxm_basic_match Flow_Table_Entry::getMatch() const{ 61 | return match; 62 | } 63 | 64 | int Flow_Table_Entry::getPriority() const{ 65 | return priority; 66 | } 67 | 68 | void Flow_Table_Entry::setCookie(flow_table_cookie cookie){ 69 | this->cookie = cookie; 70 | } 71 | 72 | void Flow_Table_Entry::setCounters(flow_table_counters counters){ 73 | this->counters = counters; 74 | } 75 | 76 | void Flow_Table_Entry::setFlags(flow_table_flags flags){ 77 | this->flags = flags; 78 | } 79 | 80 | void Flow_Table_Entry::setHardTimeout(double hardTimeout){ 81 | this->hardTimeout = hardTimeout; 82 | } 83 | 84 | void Flow_Table_Entry::setIdleTimeout(double idleTimeout){ 85 | this->idleTimeout = idleTimeout; 86 | } 87 | 88 | void Flow_Table_Entry::setExpiresAt(SimTime expiresAt){ 89 | this->expiresAt = expiresAt; 90 | } 91 | 92 | void Flow_Table_Entry::setInstructions(ofp_action_output instructions[1]){ 93 | this->instructions[0] = instructions[0]; 94 | } 95 | 96 | void Flow_Table_Entry::setMatch(oxm_basic_match match){ 97 | this->match = match; 98 | } 99 | 100 | void Flow_Table_Entry::setPriority(int priority){ 101 | this->priority = priority; 102 | } 103 | 104 | } /*end namespace openflow*/ 105 | -------------------------------------------------------------------------------- /src/openflow/openflow/switch/Flow_Table_Entry.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef FLOW_TABLE_ENTRY_H_ 4 | #define FLOW_TABLE_ENTRY_H_ 5 | 6 | #include "openflow/openflow/protocol/OpenFlow.h" 7 | #include "openflow/messages/OFP_Flow_Mod_m.h" 8 | 9 | using namespace __gnu_cxx; 10 | 11 | namespace openflow{ 12 | 13 | struct flow_table_counters { 14 | 15 | }; 16 | 17 | struct flow_table_flags { 18 | 19 | }; 20 | 21 | struct flow_table_cookie { 22 | 23 | }; 24 | 25 | 26 | struct ltmatch{ 27 | bool operator() (const oxm_basic_match m1, const oxm_basic_match m2) const{ 28 | if(m1.OFB_IN_PORT == m2.OFB_IN_PORT){ 29 | return false; 30 | }else if(m1.OFB_ETH_TYPE == m2.OFB_ETH_TYPE){ 31 | return false; 32 | }else if(m1.OFB_ETH_SRC == m2.OFB_ETH_SRC){ 33 | return false; 34 | }else if(m1.OFB_ETH_DST == m2.OFB_ETH_DST){ 35 | return false; 36 | }else if (m1.wildcards != m2.wildcards){ 37 | return false; 38 | }else{ 39 | return true; 40 | } 41 | } 42 | }; 43 | 44 | 45 | class Flow_Table_Entry { 46 | public: 47 | Flow_Table_Entry(); 48 | Flow_Table_Entry(const OFP_Flow_Mod *flowModMsg); 49 | 50 | flow_table_cookie getCookie() const; 51 | flow_table_counters getCounters() const; 52 | flow_table_flags getFlags() const; 53 | double getHardTimeout() const; 54 | double getIdleTimeout() const; 55 | SimTime getExpiresAt() const; 56 | ofp_action_output getInstructions() const; 57 | oxm_basic_match getMatch() const; 58 | int getPriority() const; 59 | 60 | void setCookie(flow_table_cookie cookie); 61 | void setCounters(flow_table_counters counters); 62 | void setFlags(flow_table_flags flags); 63 | void setHardTimeout(double hardTimeout); 64 | void setIdleTimeout(double idleTimeout); 65 | void setExpiresAt(SimTime expiresAt); 66 | void setInstructions(ofp_action_output instructions[1]); 67 | void setMatch(oxm_basic_match match); 68 | void setPriority(int priority); 69 | 70 | protected: 71 | oxm_basic_match match; 72 | flow_table_counters counters; 73 | ofp_action_output instructions[1]; 74 | flow_table_cookie cookie; 75 | flow_table_flags flags; 76 | int priority; 77 | double idleTimeout; 78 | double hardTimeout; 79 | SimTime expiresAt; 80 | }; 81 | 82 | } /*end namespace openflow*/ 83 | 84 | #endif /* FLOW_TABLE_H_ */ 85 | -------------------------------------------------------------------------------- /src/openflow/openflow/switch/IOpenFlowRelayUnit.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | // c Timo Haeckel, for HAW Hamburg 16 | // 17 | 18 | package openflow.openflow.switch; 19 | 20 | // 21 | // Interface module for OpenFlowRealyUnits implementing the flow based forwarding. 22 | // 23 | 24 | // 25 | // Prototype for modules providing OpenFlow rule based Ethernet switch functionality. 26 | // These modules forward frames (@see ~EtherFrame) to appropriate ports. 27 | // 28 | // Functions: 29 | // - relays frames based on OpenFlow matching to OpenFlow Table entries (@see ~OF_FlowTable) 30 | // - models finite buffer size (drops) and finite processing power (latency, queueing) 31 | // 32 | // 33 | // This module is not a concrete implementation, it just defines gates and 34 | // parameters a ~IOpenFlowRelayUnit should have. Concrete inplementations add 35 | // capacity and performance aspects to the model (number of frames processed 36 | // per second, amount of memory available in the switch, etc.) 37 | // 38 | // Known implementations are ~OF_Switch 39 | // 40 | // @author Timo Haeckel, for HAW Hamburg 41 | // 42 | moduleinterface IOpenFlowRelayUnit 43 | { 44 | parameters: 45 | @display("i=block/switch"); 46 | 47 | // paths to other modules 48 | string interfaceTableModule; // The path to the InterfaceTable module 49 | 50 | // Modelling a realistic environment 51 | double serviceTime @unit("s"); // The relay units service time, models finite processing power 52 | int bufferCapacity; // Max. number of frames in Buffer, infinity if <= 0 53 | 54 | // Local TCP connection 55 | string localAddress; 56 | int localPort; 57 | 58 | // OpenFlow controller connection 59 | double connectAt @unit("s"); // Simtime at which the switch connects to the controller. 60 | string connectAddress; // controller address 61 | int connectPort; // controller port 62 | 63 | gates: 64 | // control plane port connection 65 | input controlPlaneIn @labels(TcpCommand/up); 66 | output controlPlaneOut @labels(TcpCommand/down); 67 | 68 | // data plane port connections 69 | input dataPlaneIn; 70 | output dataPlaneOut; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /src/openflow/openflow/switch/OF_Switch.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.openflow.switch; 4 | 5 | ////The Switch Application module is a TCP application and therefore directly connected 6 | //to the TCP module. It belongs to the control plane and is responsible for 7 | //the communication with the controller. 8 | simple OF_Switch like IOpenFlowRelayUnit 9 | { 10 | parameters: 11 | @class(openflow::OF_Switch); 12 | @signal[cpPingPacketHash](type="unsigned long"); 13 | @statistic[cpPingPacketHash](title="CpPingPacketHash"; record=vector?,stats; interpolationmode=none); 14 | @signal[dpPingPacketHash](type="unsigned long"); 15 | @statistic[dpPingPacketHash](title="DpPingPacketHash"; record=vector?,stats; interpolationmode=none); 16 | @signal[queueSize](type="unsigned long"); 17 | @statistic[queueSize](title="QueueSize"; record=vector?,stats; interpolationmode=none); 18 | @signal[bufferSize](type="long"); 19 | @statistic[bufferSize](title="BufferSize"; record=vector?,stats; interpolationmode=none); 20 | @signal[waitingTime](type="simtime_t"); 21 | @statistic[waitingTime](title="WaitingTime"; record=vector?,stats?; interpolationmode=none); 22 | @display("i=block/app"); 23 | 24 | string interfaceTableModule; // The path to the InterfaceTable module 25 | 26 | string localAddress = default(""); 27 | int localPort = default(-1); 28 | string connectAddress = default(""); 29 | int connectPort = default(6633); 30 | 31 | double flowTimeoutPollInterval @unit("s") = default(1s); 32 | double connectAt @unit("s") = default(1s); 33 | double serviceTime @unit("s") = default(0s); 34 | int bufferCapacity = default(0); 35 | 36 | bool sendCompletePacket = default(false); 37 | bool highlightActivePorts = default(false); 38 | 39 | gates: 40 | input controlPlaneIn @labels(TcpCommand/up); 41 | output controlPlaneOut @labels(TcpCommand/down); 42 | 43 | input dataPlaneIn; 44 | output dataPlaneOut; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/openflow/openflow/switch/flowtable/IOpenFlowFlowTable.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | // (c) Timo Haeckel, for HAW Hamburg 16 | // 17 | 18 | 19 | package openflow.openflow.switch.flowtable; 20 | 21 | // 22 | // Interface for OpenFlow flow tables, which are a core component of the OpenFlow 23 | // switch architecture. Flow tables store the forwarding rules (flow entries) that 24 | // determine how packets are processed by the switch. 25 | // 26 | // The default implementation is ~OF_FlowTable. 27 | // 28 | // @author Timo Haeckel, for HAW Hamburg 29 | // 30 | moduleinterface IOpenFlowFlowTable 31 | { 32 | parameters: 33 | @display("i=block/table2,#008002"); 34 | 35 | // The maximum numbers of entries this table can hold, 36 | // if <= 0 the table size will be infinite 37 | int maxFlowEntries; 38 | 39 | // The interval to check if there are no entries. Auto check if == 0. 40 | double agingInterval @unit("s"); 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/openflow/openflow/switch/flowtable/OF_FlowTable.ned: -------------------------------------------------------------------------------- 1 | // 2 | // This program is free software: you can redistribute it and/or modify 3 | // it under the terms of the GNU General Public License as published by 4 | // the Free Software Foundation, either version 3 of the License, or 5 | // (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU General Public License 13 | // along with this program. If not, see http://www.gnu.org/licenses/. 14 | // 15 | // c Timo Haeckel, for HAW Hamburg 16 | // 17 | 18 | 19 | package openflow.openflow.switch.flowtable; 20 | 21 | import openflow.openflow.switch.flowtable.IOpenFlowFlowTable; 22 | 23 | // 24 | // [GENERATED DOCUMENTATION -- ACCURACY UNVERIFIED] 25 | // The OF_FlowTable module implements the core packet forwarding logic of an OpenFlow switch. 26 | // It stores flow entries that determine how packets are processed and forwarded through the switch. 27 | // 28 | // Each flow entry contains: 29 | // - Match fields: Criteria for matching packets (MAC addresses, IP addresses, ports, etc.) 30 | // - Actions: Instructions for handling matching packets (forward to port, drop, modify headers) 31 | // - Timeouts: Idle and hard timeouts for automatic entry removal 32 | // - Priority: Determines matching precedence when multiple entries could match 33 | // 34 | // Key functions: 35 | // - Packet matching: Finding the appropriate flow entry for incoming packets 36 | // - Flow entry management: Adding, modifying, and removing entries based on controller commands 37 | // - Timeout handling: Automatically removing expired entries 38 | // 39 | // In the OpenFlow architecture: 40 | // - The controller installs flow entries in the switch's flow table 41 | // - When a packet arrives, it's matched against the flow table 42 | // - If a match is found, the corresponding actions are executed 43 | // - If no match is found, the packet is typically sent to the controller (table miss) 44 | // 45 | // @author Timo Haeckel, for HAW Hamburg 46 | // 47 | simple OF_FlowTable like IOpenFlowFlowTable 48 | { 49 | parameters: 50 | @class(openflow::OF_FlowTable); 51 | @display("i=block/table2,#008002"); 52 | 53 | // The maximum numbers of entries this table can hold, 54 | // if <= 0 the table size will be infinite 55 | int maxFlowEntries = default(0); 56 | // the interval to check if there are aged entries. Auto check if == 0 57 | double agingInterval @unit("s") = default(0s); 58 | } 59 | -------------------------------------------------------------------------------- /src/openflow/package.ned: -------------------------------------------------------------------------------- 1 | package openflow; 2 | 3 | @license(LGPL); 4 | -------------------------------------------------------------------------------- /src/openflow/utility/ARP_Wrapper.cc: -------------------------------------------------------------------------------- 1 | #include "openflow/utility/ARP_Wrapper.h" 2 | 3 | using namespace std; 4 | 5 | namespace openflow{ 6 | 7 | ARP_Wrapper::ARP_Wrapper(){ 8 | 9 | } 10 | 11 | 12 | ARP_Wrapper::~ARP_Wrapper(){ 13 | 14 | } 15 | 16 | const string& ARP_Wrapper::getSrcIp() const { 17 | return this->srcIp; 18 | } 19 | 20 | void ARP_Wrapper::setSrcIp(const string& srcIp){ 21 | this->srcIp = srcIp; 22 | } 23 | 24 | const MacAddress& ARP_Wrapper::getSrcMacAddress() const{ 25 | return this->srcMac; 26 | } 27 | 28 | void ARP_Wrapper::setSrcMacAddress(const MacAddress& macAddress){ 29 | this->srcMac = macAddress; 30 | } 31 | 32 | } /*end namespace openflow*/ 33 | -------------------------------------------------------------------------------- /src/openflow/utility/ARP_Wrapper.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef ARP_WRAPPER_H_ 4 | #define ARP_WRAPPER_H_ 5 | 6 | #include 7 | #include "inet/linklayer/common/MacAddress.h" 8 | 9 | using namespace std; 10 | using namespace inet; 11 | 12 | namespace openflow{ 13 | 14 | class ARP_Wrapper: public cObject { 15 | 16 | public: 17 | ARP_Wrapper(); 18 | ~ARP_Wrapper(); 19 | 20 | const string& getSrcIp() const; 21 | void setSrcIp(const string& srcIp); 22 | 23 | const MacAddress& getSrcMacAddress() const; 24 | void setSrcMacAddress(const MacAddress& macAddress); 25 | 26 | 27 | 28 | protected: 29 | string srcIp; 30 | MacAddress srcMac; 31 | }; 32 | 33 | 34 | } /*end namespace openflow*/ 35 | 36 | #endif /* BUFFER_H_ */ 37 | -------------------------------------------------------------------------------- /src/openflow/utility/ControllerInvolvementFilter.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef CONTROLLERINVOLVEMENTFILTER_H_ 4 | #define CONTROLLERINVOLVEMENTFILTER_H_ 5 | 6 | #include "inet/common/lifecycle/OperationalBase.h" 7 | #include "inet/common/lifecycle/ModuleOperations.h" 8 | using namespace inet; 9 | 10 | namespace openflow{ 11 | 12 | class ControllerInvolvementFilter : public OperationalBase, public cListener 13 | { 14 | protected: 15 | 16 | //stats 17 | simsignal_t cpPingPacketHash; 18 | 19 | virtual void initialize(int stage) override; 20 | virtual void finish() override; 21 | virtual void finish(cComponent *component, simsignal_t signalID) override {cListener::finish(component, signalID);} 22 | virtual void handleMessageWhenUp(cMessage *msg) override; 23 | 24 | virtual void receiveSignal(cComponent *source, simsignal_t signalID, unsigned long l, cObject *details) override; 25 | 26 | std::map controllerInvolvements; 27 | 28 | // Lifecycle methods 29 | virtual void handleStartOperation(LifecycleOperation *operation) override {}; 30 | virtual void handleStopOperation(LifecycleOperation *operation) override {}; 31 | virtual void handleCrashOperation(LifecycleOperation *operation) override {}; 32 | 33 | #if INET_VERSION >= 0x0404 34 | virtual bool isInitializeStage(int stage) const override { return stage == INITSTAGE_APPLICATION_LAYER; } 35 | virtual bool isModuleStartStage(int stage) const override { return stage == ModuleStartOperation::STAGE_APPLICATION_LAYER; } 36 | virtual bool isModuleStopStage(int stage) const override { return stage == ModuleStopOperation::STAGE_APPLICATION_LAYER; } 37 | #else 38 | virtual bool isInitializeStage(int stage) override { return stage == INITSTAGE_APPLICATION_LAYER; } 39 | virtual bool isModuleStartStage(int stage) override { return stage == ModuleStartOperation::STAGE_APPLICATION_LAYER; } 40 | virtual bool isModuleStopStage(int stage) override { return stage == ModuleStopOperation::STAGE_APPLICATION_LAYER; } 41 | #endif 42 | }; 43 | 44 | } /*end namespace openflow*/ 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/openflow/utility/ControllerInvolvementFilter.ned: -------------------------------------------------------------------------------- 1 | package openflow.utility; 2 | 3 | // Calculates a Spanning Tree in the OpenFlow network. 4 | // The purpose is to prevent packet loops in the network. 5 | simple ControllerInvolvementFilter 6 | { 7 | parameters: 8 | @class(openflow::ControllerInvolvementFilter); 9 | @signal[pingPacketHash](type="long"); 10 | @statistic[pingPacketHash](title="PingPacketHash"; record=vector?,stats?; interpolationmode=none); 11 | @display("i=openflow/spanning-tree"); 12 | } 13 | -------------------------------------------------------------------------------- /src/openflow/utility/ControllerInvolvmentFilter.cc: -------------------------------------------------------------------------------- 1 | #include "openflow/utility/ControllerInvolvementFilter.h" 2 | 3 | namespace openflow{ 4 | 5 | Define_Module(ControllerInvolvementFilter); 6 | 7 | 8 | void ControllerInvolvementFilter::initialize(int stage) { 9 | OperationalBase::initialize(stage); 10 | if (stage == INITSTAGE_LOCAL) { 11 | cpPingPacketHash = registerSignal("cpPingPacketHash"); 12 | getParentModule()->subscribe("cpPingPacketHash",this); 13 | } 14 | } 15 | 16 | void ControllerInvolvementFilter::receiveSignal(cComponent *source, simsignal_t signalID, unsigned long l, cObject *details) { 17 | Enter_Method("ControllerInvolvementFilter::receiveSignal %s", cComponent::getSignalName(signalID)); 18 | if(signalID==cpPingPacketHash){ 19 | if(controllerInvolvements.count(l) <=0){ 20 | controllerInvolvements.insert(std::pair(l,1)); 21 | } else { 22 | controllerInvolvements[l]++; 23 | } 24 | } 25 | } 26 | 27 | void ControllerInvolvementFilter::handleMessageWhenUp(cMessage *msg) { 28 | throw cRuntimeError("this module doesn't handle messages, it runs only in initialize()"); 29 | } 30 | 31 | void ControllerInvolvementFilter::finish(){ 32 | /* std::map::iterator iterMap; 33 | for(iterMap = controllerInvolvements.begin(); iterMap != controllerInvolvements.end(); iterMap++){ 34 | std::stringstream name; 35 | name << "controllerInvolvementsFor-" << iterMap->first; 36 | recordScalar(name.str().c_str(),iterMap->second); 37 | } 38 | */ 39 | 40 | for(const auto & elem : controllerInvolvements){ 41 | std::stringstream name; 42 | name << "controllerInvolvementsFor-" << elem.first; 43 | recordScalar(name.str().c_str(), elem.second); 44 | } 45 | } 46 | 47 | } /*end namespace openflow*/ 48 | -------------------------------------------------------------------------------- /src/openflow/utility/KandooStructs.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KANDOOSTRUCTS_H_ 3 | #define KANDOOSTRUCTS_H_ 4 | 5 | #include "omnetpp.h" 6 | using namespace omnetpp; 7 | 8 | namespace openflow{ 9 | 10 | struct KandooEntry{ 11 | std::string srcController; 12 | std::string trgController; 13 | std::string trgApp; 14 | std::string srcApp; 15 | std::string trgSwitch; 16 | std::string srcSwitch; 17 | omnetpp::cObject * payload = nullptr; 18 | int type = -1; //0 inform, 1 request, 2 reply 19 | }; 20 | 21 | } /*end namespace openflow*/ 22 | 23 | #endif /* OF_CONTROLLER_H_ */ 24 | -------------------------------------------------------------------------------- /src/openflow/utility/LLDP_Wrapper.cc: -------------------------------------------------------------------------------- 1 | #include "openflow/utility/LLDP_Wrapper.h" 2 | 3 | using namespace std; 4 | 5 | namespace openflow{ 6 | 7 | LLDP_Wrapper::LLDP_Wrapper(){ 8 | 9 | } 10 | 11 | 12 | LLDP_Wrapper::~LLDP_Wrapper(){ 13 | 14 | } 15 | 16 | 17 | const string& LLDP_Wrapper::getDstId() const{ 18 | return this->dstId; 19 | } 20 | 21 | void LLDP_Wrapper::setDstId(const string& dstId){ 22 | this->dstId = dstId; 23 | } 24 | 25 | int LLDP_Wrapper::getDstPort() const{ 26 | return this->dstPort; 27 | } 28 | 29 | void LLDP_Wrapper::setDstPort(int dstPort){ 30 | this->dstPort = dstPort; 31 | } 32 | 33 | const string& LLDP_Wrapper::getSrcId() const{ 34 | return this->srcId; 35 | } 36 | 37 | void LLDP_Wrapper::setSrcId(const string& srcId){ 38 | this->srcId = srcId; 39 | } 40 | int LLDP_Wrapper::getSrcPort() const{ 41 | return this->srcPort; 42 | } 43 | 44 | void LLDP_Wrapper::setSrcPort(int srcPort){ 45 | this->srcPort = srcPort; 46 | } 47 | 48 | } /*end namespace openflow*/ 49 | -------------------------------------------------------------------------------- /src/openflow/utility/LLDP_Wrapper.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef LLDP_WRAPPER_H_ 4 | #define LLDP_WRAPPER_H_ 5 | 6 | #include 7 | 8 | using namespace std; 9 | using namespace omnetpp; 10 | 11 | namespace openflow{ 12 | 13 | class LLDP_Wrapper: public cObject { 14 | 15 | public: 16 | LLDP_Wrapper(); 17 | ~LLDP_Wrapper(); 18 | 19 | const string& getDstId() const; 20 | void setDstId(const string& dstId); 21 | int getDstPort() const; 22 | void setDstPort(int dstPort); 23 | const string& getSrcId() const; 24 | void setSrcId(const string& srcId); 25 | int getSrcPort() const; 26 | void setSrcPort(int srcPort); 27 | 28 | 29 | protected: 30 | string dstId; 31 | string srcId; 32 | int dstPort; 33 | int srcPort; 34 | 35 | }; 36 | 37 | 38 | } /*end namespace openflow*/ 39 | 40 | #endif /* BUFFER_H_ */ 41 | -------------------------------------------------------------------------------- /src/openflow/utility/OpenFlowGraphAnalyzer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef OPENFLOWGRAPHANALYZER_H_ 3 | #define OPENFLOWGRAPHANALYZER_H_ 4 | 5 | #include "inet/common/lifecycle/OperationalBase.h" 6 | #include "inet/common/lifecycle/ModuleOperations.h" 7 | #include "openflow/openflow/switch/OF_Switch.h" 8 | 9 | class Node; 10 | 11 | namespace openflow{ 12 | 13 | class OpenFlowGraphAnalyzer : public OperationalBase 14 | { 15 | 16 | public: 17 | virtual void finish() override; 18 | 19 | 20 | protected: 21 | cTopology topo; 22 | 23 | std::list > computedPaths; 24 | std::list getShortestPath(cTopology::Node * src, cTopology::Node * trg); 25 | 26 | int maxPathLength; 27 | int minPathLength; 28 | double avgPathLength; 29 | int numClientNodes; 30 | int numSwitchNodes; 31 | double avgNumSwitchLinks; 32 | bool considerOnlyEndToEnd; 33 | 34 | std::map swMap; 35 | std::map clMap; 36 | 37 | 38 | virtual void initialize(int stage) override; 39 | virtual void handleMessageWhenUp(cMessage *msg) override; 40 | 41 | // Lifecycle methods 42 | virtual void handleStartOperation(LifecycleOperation *operation) override {}; 43 | virtual void handleStopOperation(LifecycleOperation *operation) override {}; 44 | virtual void handleCrashOperation(LifecycleOperation *operation) override {}; 45 | 46 | #if INET_VERSION >= 0x0404 47 | virtual bool isInitializeStage(int stage) const override { return stage == INITSTAGE_APPLICATION_LAYER; } 48 | virtual bool isModuleStartStage(int stage) const override { return stage == ModuleStartOperation::STAGE_APPLICATION_LAYER; } 49 | virtual bool isModuleStopStage(int stage) const override { return stage == ModuleStopOperation::STAGE_APPLICATION_LAYER; } 50 | #else 51 | virtual bool isInitializeStage(int stage) override { return stage == INITSTAGE_APPLICATION_LAYER; } 52 | virtual bool isModuleStartStage(int stage) override { return stage == ModuleStartOperation::STAGE_APPLICATION_LAYER; } 53 | virtual bool isModuleStopStage(int stage) override { return stage == ModuleStopOperation::STAGE_APPLICATION_LAYER; } 54 | #endif 55 | }; 56 | 57 | } /*end namespace openflow*/ 58 | 59 | #endif /* SPANNINGTREE_H_ */ 60 | -------------------------------------------------------------------------------- /src/openflow/utility/OpenFlowGraphAnalyzer.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.utility; 4 | 5 | // Calculates a Spanning Tree in the OpenFlow network. 6 | // The purpose is to prevent packet loops in the network. 7 | simple OpenFlowGraphAnalyzer 8 | { 9 | parameters: 10 | @class(openflow::OpenFlowGraphAnalyzer); 11 | @display("i=spanning-tree"); 12 | string NodeType = default("openflow.openflow.switch.Open_Flow_Switch inet.node.inet.StandardHost"); 13 | bool considerOnlyEndToEnd = default(true); 14 | } 15 | -------------------------------------------------------------------------------- /src/openflow/utility/StaticSpanningTree.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef STATICSPANNINGTREE_H_ 4 | #define STATICSPANNINGTREE_H_ 5 | 6 | #include "inet/common/lifecycle/OperationalBase.h" 7 | #include "inet/common/lifecycle/ModuleOperations.h" 8 | #include "openflow/openflow/switch/OF_Switch.h" 9 | 10 | namespace openflow{ 11 | 12 | class StaticSpanningTree : public OperationalBase 13 | { 14 | protected: 15 | struct NodeInfo { 16 | NodeInfo() {isInTree=false;isProcessed=false;} 17 | bool isInTree; 18 | bool isProcessed; 19 | int moduleID; 20 | std::vector ports; 21 | std::vector treeNeighbors; 22 | }; 23 | 24 | typedef std::vector NodeInfoVector; 25 | cTopology topo_spanntree; 26 | NodeInfoVector nodeInfo; 27 | 28 | virtual void initialize(int stage) override; 29 | virtual void handleMessageWhenUp(cMessage *msg) override; 30 | 31 | // Lifecycle methods 32 | virtual void handleStartOperation(LifecycleOperation *operation) override {}; 33 | virtual void handleStopOperation(LifecycleOperation *operation) override {}; 34 | virtual void handleCrashOperation(LifecycleOperation *operation) override {}; 35 | 36 | #if INET_VERSION >= 0x0404 37 | virtual bool isInitializeStage(int stage) const override { return stage == INITSTAGE_APPLICATION_LAYER; } 38 | virtual bool isModuleStartStage(int stage) const override { return stage == ModuleStartOperation::STAGE_APPLICATION_LAYER; } 39 | virtual bool isModuleStopStage(int stage) const override { return stage == ModuleStopOperation::STAGE_APPLICATION_LAYER; } 40 | #else 41 | virtual bool isInitializeStage(int stage) override { return stage == INITSTAGE_APPLICATION_LAYER; } 42 | virtual bool isModuleStartStage(int stage) override { return stage == ModuleStartOperation::STAGE_APPLICATION_LAYER; } 43 | virtual bool isModuleStopStage(int stage) override { return stage == ModuleStopOperation::STAGE_APPLICATION_LAYER; } 44 | #endif 45 | }; 46 | 47 | } /*end namespace openflow*/ 48 | 49 | #endif /* SPANNINGTREE_H_ */ 50 | -------------------------------------------------------------------------------- /src/openflow/utility/StaticSpanningTree.ned: -------------------------------------------------------------------------------- 1 | 2 | 3 | package openflow.utility; 4 | 5 | // Calculates a Spanning Tree in the OpenFlow network. 6 | // The purpose is to prevent packet loops in the network. 7 | simple StaticSpanningTree 8 | { 9 | parameters: 10 | @class(openflow::StaticSpanningTree); 11 | @display("i=openflow/spanning-tree"); 12 | string NodeType = default("openflow.openflow.switch.Open_Flow_Switch"); 13 | int startNode = default(0); 14 | } 15 | -------------------------------------------------------------------------------- /src/run_openflow: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | DIR=`dirname $0` 3 | 4 | if [ -x $DIR/openflow_exe -o -x $DIR/openflow_exe.exe ]; then 5 | $DIR/openflow_exe -n $DIR/../../inet/src:$DIR/../scenarios:$DIR $* 6 | else 7 | opp_run_dbg -l $DIR/openflow -n $DIR/../../inet/src:$DIR/../scenarios:$DIR $* 8 | fi 9 | -------------------------------------------------------------------------------- /test/fingerprint/README: -------------------------------------------------------------------------------- 1 | This folder contains fingerprint-based tests for various models. 2 | 3 | When a fingerprint test passes, that indicates that with very high 4 | probability, the simulation has followed the same trajectory as when 5 | the fingerprint was recorded, i.e. the times and modules of the events 6 | were the same. That is, a passing fingerprint tests means that the 7 | simulation model logic works the same as before. 8 | 9 | However, a passing test does not guarantee that e.g. result recording 10 | has not changed. 11 | 12 | Fingerprints are fragile to NED changes and parameter value changes. 13 | 14 | When a fingerprint test fails, the simulation's correctness has to be 15 | verified by some other means, and the fingerprints in the tests 16 | updated. 17 | 18 | When the fingerprint fails only on your computer, try to build omnet with: 19 | CFLAGS_RELEASE+=" -mfpmath=sse -msse2" CFLAGS_DEBUG+=" -mfpmath=sse -msse2" ./configure 20 | CFLAGS_RELEASE+=" -mfpmath=sse -msse2" CFLAGS_DEBUG+=" -mfpmath=sse -msse2" make -------------------------------------------------------------------------------- /test/fingerprint/fingerprinttest: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Hint: You may want to use the '-F tyf' option to exclude graphical (tyf) fingerprints, as they are not regularly kept up to date" 3 | 4 | FP_EXTRA_OPTIONS="-l $OPENFLOW_ROOT/src/openflow6 -n $INET_ROOT/src:$OPENFLOW_ROOT/scenarios:$OPENFLOW_ROOT/src --image-path=$INET_ROOT/images" 5 | echo FP_EXTRA_OPTIONS=$FP_EXTRA_OPTIONS 6 | 7 | #$INET_ROOT/bin/inet_fingerprinttest --executable opp_run --directory $OPENFLOW_ROOT "$@" -a $FP_EXTRA_OPTIONS 8 | $OPENFLOW_ROOT/test/fingerprint/inet4_fingerprinttest --executable opp_run --directory $OPENFLOW_ROOT "$@" -a $FP_EXTRA_OPTIONS 9 | -------------------------------------------------------------------------------- /test/smoke/README: -------------------------------------------------------------------------------- 1 | This folder contains smoke tests for the OpenFlow framework. The 2 | 3 | $ ./smoketest scenarios.csv 4 | 5 | command runs all example simulations for a while, and they must not crash 6 | or stop with an error. 7 | 8 | This test can provide a very modest level of confidence regarding the 9 | quality of the models. 10 | --------------------------------------------------------------------------------