├── AUTHORS ├── BUGS ├── COPYING ├── Documentation ├── IO Overview.graffle │ ├── QuickLook │ │ ├── Preview.pdf │ │ └── Thumbnail.tiff │ ├── data.plist │ ├── image1.pdf │ ├── image2.pdf │ └── image3.eps └── Packet In.graffle ├── INSTALL ├── Makefile ├── README ├── README.dev ├── README.md ├── README.syslog ├── RELEASE-NOTES ├── UPGRADING ├── build.xml ├── doc ├── flowvisor.8 ├── fvconfig.1 └── fvctl.1 ├── lib ├── asm-3.0.jar ├── cglib-2.2.jar ├── commons-codec-1.4.jar ├── commons-collections-3.2.1.jar ├── commons-dbcp-1.4.jar ├── commons-logging-1.1.jar ├── commons-pool-1.5.6.jar ├── derby.jar ├── derbytools.jar ├── emma │ ├── emma.jar │ └── emma_ant.jar ├── gson-2.0.jar ├── jetty-continuation-7.0.2.v20100331.jar ├── jetty-http-7.0.2.v20100331.jar ├── jetty-io-7.0.2.v20100331.jar ├── jetty-security-7.0.2.v20100331.jar ├── jetty-server-7.0.2.v20100331.jar ├── jetty-util-7.0.2.v20100331.jar ├── jna.jar ├── jsonrpc2-base-1.30.jar ├── jsonrpc2-server-1.8.jar ├── jsse.jar ├── junit-4.8.1.jar ├── log4j-1.2.16.jar ├── openflow.jar ├── servlet-api-2.5.jar ├── syslog4j-0.9.46-bin.jar ├── ws-commons-util-1.0.2.jar ├── xmlrpc-client-3.1.3.jar ├── xmlrpc-common-3.1.3.jar └── xmlrpc-server-3.1.3.jar ├── scripts ├── DEB │ ├── Makefile │ └── README ├── FlowVisorDB.sql ├── derby-interact.sh ├── derby.properties ├── envs.sh ├── fix_trailing_whitespace.pl ├── flowvisor-emma.sh ├── flowvisor-javac.sh ├── flowvisor.sh ├── fv-startup.sh ├── fvconfig.sh ├── fvctl-json.py ├── fvctl-xml.sh ├── fvlog.config ├── install-package.sh ├── install-script.sh ├── logrotate ├── make-deb-repo.sh ├── make-deb.sh ├── make-release-repo.sh ├── make-release.sh ├── make-repo.sh ├── make-rpm-repo.sh ├── run-tests.sh └── xmlrpc_client.py ├── src.tests └── org │ └── flowvisor │ ├── config │ └── BracketParseTest.java │ └── flows │ ├── FederatedFlowMapTest.java │ ├── FlowEntryTest.java │ ├── FlowSpaceUtilsTest.java │ ├── FlowTestOpTest.java │ └── LinearFlowMapTest.java ├── src └── org │ └── flowvisor │ ├── FlowVisor.java │ ├── ShutdownHook.java │ ├── api │ ├── APIAuth.java │ ├── APIServer.java │ ├── APIUserCred.java │ ├── DeviceAdvertisement.java │ ├── FVCtl.java │ ├── FVRpcErrorLogger.java │ ├── FVUserAPI.java │ ├── FVUserAPIImpl.java │ ├── FVUserAPIJSON.java │ ├── FVUserAPIJSONImpl.java │ ├── FVUserAPIXML.java │ ├── FVUserAPIXMLRPCImpl.java │ ├── FlowChange.java │ ├── FlowSpaceChangeRequest.java │ ├── FlowTableCallback.java │ ├── FlowVisorLoginService.java │ ├── JSONRPCService.java │ ├── JettyServer.java │ ├── LinkAdvertisement.java │ ├── SSLWebServer.java │ ├── TopologyCallback.java │ └── handlers │ │ ├── ApiHandler.java │ │ ├── ConfigurationHandler.java │ │ ├── HandlerUtils.java │ │ ├── MonitoringHandler.java │ │ ├── configuration │ │ ├── AddFlowSpace.java │ │ ├── AddSlice.java │ │ ├── GetConfig.java │ │ ├── ListFSInsertionStatus.java │ │ ├── ListFlowSpace.java │ │ ├── ListSlices.java │ │ ├── ListVersion.java │ │ ├── RemoveFlowSpace.java │ │ ├── RemoveSlice.java │ │ ├── SaveConfig.java │ │ ├── SetConfig.java │ │ ├── UpdateAdminPassword.java │ │ ├── UpdateFlowSpace.java │ │ ├── UpdateSlice.java │ │ └── UpdateSlicePassword.java │ │ └── monitoring │ │ ├── ListDatapathFlowDB.java │ │ ├── ListDatapathFlowRewriteDB.java │ │ ├── ListDatapathInfo.java │ │ ├── ListDatapathStats.java │ │ ├── ListDatapaths.java │ │ ├── ListFVHealth.java │ │ ├── ListLinks.java │ │ ├── ListSliceHealth.java │ │ ├── ListSliceInfo.java │ │ ├── ListSliceStats.java │ │ ├── RegisterEventCallback.java │ │ └── UnRegisterEventCallback.java │ ├── classifier │ ├── CookiePair.java │ ├── CookieTranslator.java │ ├── FVClassifier.java │ ├── FVSendMsg.java │ ├── XidPair.java │ ├── XidPairWithMessage.java │ ├── XidTranslator.java │ └── XidTranslatorWithMessage.java │ ├── config │ ├── BracketParse.java │ ├── Bracketable.java │ ├── ChangedListener.java │ ├── ConfDBHandler.java │ ├── ConfDBSettings.java │ ├── ConfigError.java │ ├── ConfigurationEvent.java │ ├── FVAppConfig.java │ ├── FVConfig.java │ ├── FVConfigProxy.java │ ├── FVConfigurationController.java │ ├── FlowMapChangedListener.java │ ├── FlowSpace.java │ ├── FlowSpaceHandler.java │ ├── FlowSpaceImpl.java │ ├── Flowvisor.java │ ├── FlowvisorChangedListener.java │ ├── FlowvisorImpl.java │ ├── InvalidDropPolicy.java │ ├── InvalidSliceName.java │ ├── LoadConfig.java │ ├── Slice.java │ ├── SliceChangedListener.java │ ├── SliceImpl.java │ ├── Switch.java │ ├── SwitchChangedListener.java │ ├── SwitchImpl.java │ └── convertor │ │ ├── ConfBoolEntry.java │ │ ├── ConfDirEntry.java │ │ ├── ConfFlowMapEntry.java │ │ ├── ConfIntEntry.java │ │ ├── ConfRealEntry.java │ │ ├── ConfStrEntry.java │ │ ├── ConfigCantCreateError.java │ │ ├── ConfigClassLoader.java │ │ ├── ConfigDumper.java │ │ ├── ConfigEntry.java │ │ ├── ConfigError.java │ │ ├── ConfigIterator.java │ │ ├── ConfigJson.java │ │ ├── ConfigNotFoundError.java │ │ ├── ConfigPrinter.java │ │ ├── ConfigType.java │ │ ├── ConfigWrongTypeError.java │ │ └── Convertor.java │ ├── events │ ├── ConfigUpdateEvent.java │ ├── ExampleHandler.java │ ├── FVEvent.java │ ├── FVEventHandler.java │ ├── FVEventLoop.java │ ├── FVEventUtils.java │ ├── FVIOEvent.java │ ├── FVRequestTimeoutEvent.java │ ├── FVStatsTimer.java │ ├── FVTimerEvent.java │ ├── OFKeepAlive.java │ └── TearDownEvent.java │ ├── exceptions │ ├── ActionDisallowedException.java │ ├── BufferFull.java │ ├── DPIDNotFound.java │ ├── DuplicateControllerException.java │ ├── FVException.java │ ├── FlowEntryNotFound.java │ ├── InvalidUserInfoKey.java │ ├── MalformedControllerURL.java │ ├── MalformedFlowChange.java │ ├── MalformedOFMessage.java │ ├── MapUnparsable.java │ ├── MissingRequiredField.java │ ├── NoMatch.java │ ├── NoParamException.java │ ├── PermissionDeniedException.java │ ├── RPCException.java │ ├── SliceNameDisallowedException.java │ ├── SliceNotFound.java │ ├── StatDisallowedException.java │ ├── UnhandledEvent.java │ ├── UnknownFieldType.java │ └── UnknownMatchField.java │ ├── flows │ ├── FederatedFlowMap.java │ ├── FlowDB.java │ ├── FlowDBEntry.java │ ├── FlowEntry.java │ ├── FlowIntersect.java │ ├── FlowMap.java │ ├── FlowRewriteDB.java │ ├── FlowSpaceRuleStore.java │ ├── FlowSpaceUtil.java │ ├── FlowTestOp.java │ ├── LinearFlowDB.java │ ├── LinearFlowMap.java │ ├── LinearFlowRewriteDB.java │ ├── MatchType.java │ ├── NoopFlowDB.java │ ├── NoopFlowRewriteDB.java │ └── SliceAction.java │ ├── fvtimer │ └── FVTimer.java │ ├── io │ └── FVMessageAsyncStream.java │ ├── log │ ├── AnyLogger.java │ ├── DevNullLogger.java │ ├── FVLog.java │ ├── FVLogInterface.java │ ├── FVStats.java │ ├── FVStatsGroup.java │ ├── JettyLog.java │ ├── LogLevel.java │ ├── SendRecvDropStats.java │ ├── StderrLogger.java │ └── ThreadLogger.java │ ├── message │ ├── Classifiable.java │ ├── FVBarrierReply.java │ ├── FVBarrierRequest.java │ ├── FVEchoReply.java │ ├── FVEchoRequest.java │ ├── FVError.java │ ├── FVFeaturesReply.java │ ├── FVFeaturesRequest.java │ ├── FVFlowMod.java │ ├── FVFlowRemoved.java │ ├── FVGetConfigReply.java │ ├── FVGetConfigRequest.java │ ├── FVHello.java │ ├── FVMessageFactory.java │ ├── FVMessageUtil.java │ ├── FVPacketIn.java │ ├── FVPacketOut.java │ ├── FVPortMod.java │ ├── FVPortStatus.java │ ├── FVQueueConfigReply.java │ ├── FVQueueConfigRequest.java │ ├── FVSetConfig.java │ ├── FVStatisticsReply.java │ ├── FVStatisticsRequest.java │ ├── FVUnknownMessage.java │ ├── FVVendor.java │ ├── SanityCheckable.java │ ├── Slicable.java │ ├── TopologyControllable.java │ ├── actions │ │ ├── FVActionDataLayerDestination.java │ │ ├── FVActionDataLayerSource.java │ │ ├── FVActionEnqueue.java │ │ ├── FVActionNetworkLayerDestination.java │ │ ├── FVActionNetworkLayerSource.java │ │ ├── FVActionNetworkTypeOfService.java │ │ ├── FVActionOutput.java │ │ ├── FVActionStripVirtualLan.java │ │ ├── FVActionTransportLayerDestination.java │ │ ├── FVActionTransportLayerSource.java │ │ ├── FVActionVendor.java │ │ ├── FVActionVirtualLanIdentifier.java │ │ ├── FVActionVirtualLanPriorityCodePoint.java │ │ └── SlicableAction.java │ ├── lldp │ │ ├── LLDPTrailer.java │ │ └── LLDPUtil.java │ └── statistics │ │ ├── ClassifiableStatistic.java │ │ ├── FVAggregateStatisticsReply.java │ │ ├── FVAggregateStatisticsRequest.java │ │ ├── FVDescriptionStatistics.java │ │ ├── FVFlowStatisticsReply.java │ │ ├── FVFlowStatisticsRequest.java │ │ ├── FVPortStatisticsReply.java │ │ ├── FVPortStatisticsRequest.java │ │ ├── FVQueueStatisticsReply.java │ │ ├── FVQueueStatisticsRequest.java │ │ ├── FVTableStatistics.java │ │ ├── FVVendorStatistics.java │ │ └── SlicableStatistic.java │ ├── ofswitch │ ├── DPIDandPort.java │ ├── OFSwitchAcceptor.java │ ├── TopologyConnection.java │ └── TopologyController.java │ ├── openflow │ └── protocol │ │ └── FVMatch.java │ ├── resources │ ├── SlicerLimits.java │ └── ratelimit │ │ ├── FixedIntervalRefillStrategy.java │ │ ├── NoLimitRefillStrategy.java │ │ ├── RefillStrategy.java │ │ └── TokenBucket.java │ └── slicer │ ├── FVSlicer.java │ └── ReconnectEvent.java └── utilities ├── README ├── find-syslog-jumps.pl ├── fvcli ├── init.d └── flowvisor-citrix-startup.sh ├── jsonrpc ├── __init__.py ├── cgiwrapper.py ├── modpywrapper.py ├── proxy.py └── serviceHandler.py ├── mrtg ├── fvSliceStats2mrtg.sh └── fvSwitchStats2mrtg.sh └── nload ├── Makefile ├── README └── nload.c /AUTHORS: -------------------------------------------------------------------------------- 1 | Current designer/coder: 2 | Sumanth M Sathyanarayana - sumanth@onlab.us 3 | Flowvisor creator: 4 | Rob Sherwood - rob.sherwood@stanford.edu / r.sherwood@telekom.com 5 | 6 | Currently maintained by: 7 | Sumanth M Sathyanarayana - sumanth@onlab.us 8 | 9 | FlowVisor Project headed by: 10 | Ali Al-Shabibi 11 | 12 | Additional help from: 13 | 14 | FlowVisor 0.4: 15 | Glen Gibb 16 | Srini Seetharaman 17 | FlowVisor 0.6: 18 | Aaron Helsinger 19 | Josh Smift 20 | Nick Bastin 21 | FlowVisor 0.7: 22 | Christopher Tengi 23 | Anne Struble 24 | Jose F. Mingorance-Puga 25 | FlowVisor 0.8: 26 | Ali Al-Shabibi 27 | FlowVisor 0.10: 28 | Andrew Ragusa 29 | FlowVisor 1.0: 30 | Ali Al-Shabibi 31 | FlowVisor 1.2: 32 | Sumanth M. Sathyanarayana 33 | FlowVisor 1.4: 34 | Sumanth M. Sathyanarayana 35 | 36 | -------------------------------------------------------------------------------- /BUGS: -------------------------------------------------------------------------------- 1 | 2 | Please post bugs to: 3 | 4 | https://github.com/OPENNETWORKINGLAB/flowvisor/issues 5 | 6 | Any bug report is appreciated but the best bug reports include: 7 | 8 | 1) if and how the bug can be replicated 9 | 2) a stack trace (if available) 10 | 3) tcpdump's of both the switch<-->FV and FV<-->controllers 11 | openflow control channels 12 | - make sure to set the capture length to 0 meaning 13 | capture the full packets. Traces with partial packet captures 14 | as not useful :-( 15 | 16 | Thanks in advance! 17 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008 The Board of Trustees of The Leland Stanford 2 | Junior University 3 | 4 | We are making the FlowVisor specification, code, and associated 5 | documentation (Software) available for public use and benefit with the 6 | expectation that others will use, modify and enhance the Software and 7 | contribute those enhancements back to the community. However, since we 8 | would like to make the Software available for broadest use, with as few 9 | restrictions as possible permission is hereby granted, free of charge, 10 | to any person obtaining a copy of this Software to deal in the Software 11 | under the copyrights without restriction, including without limitation 12 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 | and/or sell copies of the Software, and to permit persons to whom the 14 | Software is furnished to do so, subject to the following conditions: 15 | The above copyright notice and this permission notice shall be included 16 | in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 22 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 23 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | 27 | The name and trademarks of copyright holder(s) may NOT be used in 28 | advertising or publicity pertaining to the Software or any 29 | derivatives without specific, written prior permission. 30 | 31 | -------------------------------------------------------------------------------- /Documentation/IO Overview.graffle/QuickLook/Preview.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/Documentation/IO Overview.graffle/QuickLook/Preview.pdf -------------------------------------------------------------------------------- /Documentation/IO Overview.graffle/QuickLook/Thumbnail.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/Documentation/IO Overview.graffle/QuickLook/Thumbnail.tiff -------------------------------------------------------------------------------- /Documentation/IO Overview.graffle/image1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/Documentation/IO Overview.graffle/image1.pdf -------------------------------------------------------------------------------- /Documentation/IO Overview.graffle/image2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/Documentation/IO Overview.graffle/image2.pdf -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | REQUIREMENTS: 2 | - ant (no version requirements?) 3 | - java 1.6 (currently works with both Sun's JDK; 4 | and OpenJDK) 5 | 6 | BUILD: 7 | - run `make` (or `ant` : Makefile is just a wrapper) 8 | 9 | INSTALL: 10 | - make install 11 | 12 | This puts scripts and jars into a specified $prefix 13 | 14 | CONFIG: 15 | Build a default configuration with: 16 | fvconfig generate config.json 17 | 18 | Load the contents of the config.json in to database: 19 | fvconfig load config.json 20 | 21 | Dump the running config to a file: 22 | fvctl dumpConfig 23 | 24 | The config file is editable manually. Once editted, you may 25 | load the file using the above command (recommended) or start 26 | flowvisor with the config file as a parameter. 27 | 28 | You can still configure flowvisor during runtime using fvctl. 29 | `man 1 fvctl` or `man ./doc/fvctl.1` for details 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Because I am old and crotchety and my fingers can't stop from running 2 | # `make` commands 3 | 4 | .PHONY: docs doc all test tests count install clean 5 | 6 | all: 7 | ant 8 | 9 | docs: 10 | ant javadoc 11 | 12 | doc: 13 | ant javadoc 14 | 15 | test: tests 16 | 17 | tests: all setup-db unit-tests rmdb 18 | 19 | setup-db: 20 | ./scripts/derby-interact.sh ./scripts/FlowVisorDB.sql > /dev/null 21 | 22 | rmdb: 23 | rm -rf FlowVisorDB 24 | 25 | unit-tests: 26 | ant tests 27 | 28 | emma: 29 | ant emma-report 30 | 31 | emma-report: setup-db emma rmdb 32 | 33 | regress: 34 | ./scripts/run-tests.sh $(REV) 35 | 36 | regression: setup-db regress rmdb regressclean 37 | 38 | count: 39 | @find src -name \*.java | xargs wc -l | sort -n 40 | 41 | install: all 42 | ./scripts/install-script.sh 43 | 44 | pkg-install: all 45 | ./scripts/install-package.sh 46 | 47 | 48 | whitespace: 49 | ./scripts/fix_trailing_whitespace.pl -fix `find src -name \*.java` 50 | 51 | regressclean: 52 | rm -rf flowvisor-test 53 | 54 | clean: 55 | ant clean 56 | rm -rf pkgbuild 57 | 58 | emmaclean: 59 | rm -rf inst 60 | rm -rf coverage 61 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | FlowVisor: 2 | An OpenFlow controller that acts as a hypervisor/proxy 3 | between a switch and multiple controllers. Can slice 4 | multiple switches in parallel, effectively slicing a network. 5 | 6 | Documentation: 7 | 8 | Start with the INSTALL file and then refer to: 9 | https://github.com/OPENNETWORKINGLAB/flowvisor/wiki 10 | for more information on the installation process refer to: 11 | https://github.com/OPENNETWORKINGLAB/flowvisor/wiki/Installation-from-Source, or 12 | https://github.com/OPENNETWORKINGLAB/flowvisor/wiki/Installation-from-Binary 13 | for configuration and deployment instructions. Also, 14 | the manpages are in the ./doc directory and can be viewed 15 | without installing them using `man ./doc/fvctl.1` 16 | 17 | For developers, check out README.dev and the architecture diagrams: 18 | https://github.com/OPENNETWORKINGLAB/flowvisor/wiki under the developement section 19 | Also, `make docs` produces the source code documentation and 20 | there are manpages under ./doc 21 | 22 | Questions: 23 | openflow-discuss@openflowswitch.org 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FlowVisor 2 | ========= 3 | An OpenFlow controller that acts as a hypervisor/proxy 4 | between a switch and multiple controllers. Can slice 5 | multiple switches in parallel, effectively slicing a network. 6 | 7 | Documentation 8 | ============= 9 | 10 | Start with the INSTALL file and then refer to: 11 | https://www.flowvisor.org 12 | Also, the manpages are in the ./doc directory and can be viewed 13 | without installing them using `man ./doc/fvctl.1` 14 | 15 | For developers, check out README.dev and the architecture diagrams: 16 | https://github.com/OPENNETWORKINGLAB/flowvisor/wiki under the developement section 17 | Also, `make docs` produces the source code documentation and 18 | there are manpages under ./doc 19 | 20 | Questions 21 | ========= 22 | 23 | openflow-discuss@openflowswitch.org 24 | 25 | 26 | -------------------------------------------------------------------------------- /README.syslog: -------------------------------------------------------------------------------- 1 | Introduction 2 | ------------ 3 | 4 | Flowvisor now incorporates Log4j and Syslog4j which removes the need 5 | for the JNI interface to the system syslog. Logging is controlled 6 | from the fvlog.config configuration file. This file is essentially 7 | a log4j configuration file. Therefore a detailed description 8 | can be found at http://logging.apache.org/log4j/1.2/manual.html. 9 | 10 | Features 11 | -------- 12 | 13 | This logging systems is capable of logging to one or more destinations. 14 | So you can specify multiple logging destination will be written to 15 | simultaneously. Moreover, you can modify the configuration at runtime 16 | to enable logging another location. Logging configuration changes will 17 | be updated every minute. 18 | 19 | 20 | Possible Destinations 21 | --------------------- 22 | 23 | Console 24 | [Externally] [Daily] [Rolling] File 25 | JDBC 26 | JMS 27 | NT Event Log 28 | Null 29 | SMTP 30 | Telnet 31 | 32 | -------------------------------------------------------------------------------- /UPGRADING: -------------------------------------------------------------------------------- 1 | REQUIREMENTS: 2 | 3 | Running flowvisor at 0.8.x version. 4 | 5 | CONVERSION: 6 | 7 | To convert the xml file to the json format, run: 8 | 9 | fvconfig convert config.xml 10 | 11 | This will return a config.json file in the same 12 | directory. 13 | 14 | LOADING: 15 | 16 | Two options available: 17 | 18 | 1. Start flowvisor with config file parameter 19 | 20 | flowvisor config.json 21 | 22 | NOTE: This will overwrite contents of the database 23 | with the configuration file. Make sure the database 24 | and config file are in sync by dumping the config 25 | from a runnning flowvisor by: 26 | 27 | fvctl dumpConfig config.json 28 | 29 | Otherwise any undumped config will be lost. 30 | 31 | 32 | 2. (RECOMMENDED) Loading the config into flowvisor 33 | before starting. 34 | 35 | fvconfig load config.json 36 | 37 | -------------------------------------------------------------------------------- /lib/asm-3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/asm-3.0.jar -------------------------------------------------------------------------------- /lib/cglib-2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/cglib-2.2.jar -------------------------------------------------------------------------------- /lib/commons-codec-1.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/commons-codec-1.4.jar -------------------------------------------------------------------------------- /lib/commons-collections-3.2.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/commons-collections-3.2.1.jar -------------------------------------------------------------------------------- /lib/commons-dbcp-1.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/commons-dbcp-1.4.jar -------------------------------------------------------------------------------- /lib/commons-logging-1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/commons-logging-1.1.jar -------------------------------------------------------------------------------- /lib/commons-pool-1.5.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/commons-pool-1.5.6.jar -------------------------------------------------------------------------------- /lib/derby.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/derby.jar -------------------------------------------------------------------------------- /lib/derbytools.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/derbytools.jar -------------------------------------------------------------------------------- /lib/emma/emma.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/emma/emma.jar -------------------------------------------------------------------------------- /lib/emma/emma_ant.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/emma/emma_ant.jar -------------------------------------------------------------------------------- /lib/gson-2.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/gson-2.0.jar -------------------------------------------------------------------------------- /lib/jetty-continuation-7.0.2.v20100331.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/jetty-continuation-7.0.2.v20100331.jar -------------------------------------------------------------------------------- /lib/jetty-http-7.0.2.v20100331.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/jetty-http-7.0.2.v20100331.jar -------------------------------------------------------------------------------- /lib/jetty-io-7.0.2.v20100331.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/jetty-io-7.0.2.v20100331.jar -------------------------------------------------------------------------------- /lib/jetty-security-7.0.2.v20100331.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/jetty-security-7.0.2.v20100331.jar -------------------------------------------------------------------------------- /lib/jetty-server-7.0.2.v20100331.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/jetty-server-7.0.2.v20100331.jar -------------------------------------------------------------------------------- /lib/jetty-util-7.0.2.v20100331.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/jetty-util-7.0.2.v20100331.jar -------------------------------------------------------------------------------- /lib/jna.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/jna.jar -------------------------------------------------------------------------------- /lib/jsonrpc2-base-1.30.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/jsonrpc2-base-1.30.jar -------------------------------------------------------------------------------- /lib/jsonrpc2-server-1.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/jsonrpc2-server-1.8.jar -------------------------------------------------------------------------------- /lib/jsse.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/jsse.jar -------------------------------------------------------------------------------- /lib/junit-4.8.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/junit-4.8.1.jar -------------------------------------------------------------------------------- /lib/log4j-1.2.16.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/log4j-1.2.16.jar -------------------------------------------------------------------------------- /lib/openflow.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/openflow.jar -------------------------------------------------------------------------------- /lib/servlet-api-2.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/servlet-api-2.5.jar -------------------------------------------------------------------------------- /lib/syslog4j-0.9.46-bin.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/syslog4j-0.9.46-bin.jar -------------------------------------------------------------------------------- /lib/ws-commons-util-1.0.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/ws-commons-util-1.0.2.jar -------------------------------------------------------------------------------- /lib/xmlrpc-client-3.1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/xmlrpc-client-3.1.3.jar -------------------------------------------------------------------------------- /lib/xmlrpc-common-3.1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/xmlrpc-common-3.1.3.jar -------------------------------------------------------------------------------- /lib/xmlrpc-server-3.1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opennetworkinglab/flowvisor/b45b58f1afc674d8cd79126e0652aef2563838b2/lib/xmlrpc-server-3.1.3.jar -------------------------------------------------------------------------------- /scripts/DEB/Makefile: -------------------------------------------------------------------------------- 1 | dir=$(type)/binary-all 2 | all: 3 | dpkg-scanpackages $(dir)/ | gzip -9c > $(dir)/Packages.gz 4 | @echo Now copy tree to yuba: 5 | @echo "tar cpf - . | ssh yuba 'cd /hpn/home/httpd/htdocs/openflow/downloads/GENI/DEB && tar xvf -'" 6 | -------------------------------------------------------------------------------- /scripts/DEB/README: -------------------------------------------------------------------------------- 1 | GENI APT REPOSITORY: 2 | 3 | add 4 | 5 | deb http://updates/flowvisor.org/openflow/downloads/GENI/DEB unstable/binary-$(ARCH)/ 6 | 7 | to your /etc/sources.list 8 | 9 | And then run `sudo apt-get install flowvisor` 10 | 11 | 12 | 13 | --- NOTE TO SELF --- 14 | BUILT on openflow5 (or any machine with dpkg) and 15 | copied to yuba, because yuba is centos 16 | -------------------------------------------------------------------------------- /scripts/derby-interact.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | #base=PREFIX 4 | 5 | if [ -z $base ] ; then 6 | envs=`dirname $0`/../scripts/envs.sh 7 | else 8 | envs=/etc/flowvisor/envs.sh 9 | fi 10 | 11 | if [ -f $envs ] ; then 12 | . $envs 13 | else 14 | echo "Could not find $envs: dying..." >&2 15 | exit 1 16 | fi 17 | 18 | exec java $fv_defines -cp $classpath org.apache.derby.tools.ij $@ 19 | #exec java -cp $classpath org.apache.derby.tools.ij $@ 20 | -------------------------------------------------------------------------------- /scripts/derby.properties: -------------------------------------------------------------------------------- 1 | derby.stream.error.file=/var/log/flowvisor/flowvisor-db.log 2 | derby.stream.error.logBootTrace=true 3 | -------------------------------------------------------------------------------- /scripts/envs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SSL_KEYPASSWD=CHANGEME_PASSWD 4 | 5 | #configbase=PREFIX 6 | 7 | #install_root is for installing to a new directory, e.g., for chroot() 8 | 9 | if [ -z $configbase ] ; then 10 | configbase=`dirname $0`/.. 11 | #configbase=`pwd`/`dirname $0`/.. 12 | install_dir=$configbase/dist 13 | jars=$configbase/lib 14 | config_dir=$configbase 15 | SSL_KEYSTORE=$configbase/mySSLKeyStore 16 | dbhome=$configbase 17 | logfile=$config_dir/scripts 18 | else 19 | install_dir=$install_root$configbase/libexec/flowvisor 20 | jars=$install_dir 21 | config_dir=$install_root/etc/flowvisor 22 | SSL_KEYSTORE=$config_dir/mySSLKeyStore 23 | dbhome=$install_root$configbase/share/db/flowvisor 24 | logfile=$config_dir 25 | fi 26 | 27 | 28 | fv_defines="-Dorg.flowvisor.config_dir=$config_dir -Dorg.flowvisor.install_dir=$install_dir -Dderby.system.home=$dbhome -Dfvlog.configuration=$logfile/fvlog.config" 29 | 30 | 31 | # Setup some environmental variables 32 | classpath=$jars/openflow.jar:\ 33 | $jars/xmlrpc-client-3.1.3.jar:\ 34 | $jars/xmlrpc-common-3.1.3.jar:\ 35 | $jars/xmlrpc-server-3.1.3.jar:\ 36 | $jars/commons-logging-1.1.jar:\ 37 | $jars/ws-commons-util-1.0.2.jar:\ 38 | $jars/jsse.jar:\ 39 | $jars/asm-3.0.jar:\ 40 | $jars/cglib-2.2.jar:\ 41 | $jars/commons-codec-1.4.jar:\ 42 | $jars/commons-collections-3.2.1.jar:\ 43 | $jars/commons-dbcp-1.4.jar:\ 44 | $jars/commons-pool-1.5.6.jar:\ 45 | $jars/gson-2.0.jar:\ 46 | $jars/jetty-continuation-7.0.2.v20100331.jar:\ 47 | $jars/jetty-http-7.0.2.v20100331.jar:\ 48 | $jars/jetty-io-7.0.2.v20100331.jar:\ 49 | $jars/jetty-security-7.0.2.v20100331.jar:\ 50 | $jars/jetty-server-7.0.2.v20100331.jar:\ 51 | $jars/jetty-util-7.0.2.v20100331.jar:\ 52 | $jars/servlet-api-2.5.jar:\ 53 | $jars/derby.jar:\ 54 | $jars/derbytools.jar:\ 55 | $jars/jna.jar:\ 56 | $jars/syslog4j-0.9.46-bin.jar:\ 57 | $jars/log4j-1.2.16.jar:\ 58 | $jars/jsonrpc2-base-1.30.jar:\ 59 | $jars/jsonrpc2-server-1.8.jar:\ 60 | $install_dir/flowvisor.jar 61 | 62 | emmajar=$jars/emma/emma.jar 63 | 64 | # ssl options for the jvm 65 | 66 | sslopts="-Djavax.net.ssl.keyStore=$SSL_KEYSTORE -Djavax.net.ssl.keyStorePassword=$SSL_KEYPASSWD" 67 | 68 | # for ssl debugging options 69 | #sslopts="$sslopts -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.debug=ssl" 70 | 71 | test -f /etc/default/flowvisor && . /etc/default/flowvisor 72 | test -f /etc/sysconfig/flowvisor && . /etc/sysconfig/flowvisor 73 | -------------------------------------------------------------------------------- /scripts/fix_trailing_whitespace.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | $FIX='-fix'; 4 | $SHOW='-show'; 5 | 6 | 7 | $cmd = shift @ARGV or usage("need to specify -show or -fix"); 8 | 9 | usage("invalid command $cmd") unless ($cmd eq $FIX or $cmd eq $SHOW); 10 | 11 | $linecount=0; 12 | foreach $file (@ARGV) 13 | { 14 | open F, "$file" or die "open (readonly) : $!"; 15 | if($cmd eq $FIX) 16 | { 17 | open OUT, ">$file.tmp" or die "open (writing): $!"; 18 | } 19 | while() 20 | { 21 | $linecount++; 22 | if($cmd eq $FIX) 23 | { 24 | s/(\s+)(\s)$/$2/; 25 | print OUT; 26 | } 27 | else 28 | { 29 | print "$file:$linecount : $_" if(/\s+\s$/); 30 | } 31 | } 32 | if($cmd eq $FIX) 33 | { 34 | close OUT; 35 | if( -s "$file.tmp") 36 | { 37 | rename("$file.tmp","$file"); 38 | } 39 | else 40 | { 41 | die "$file.tmp zero length... not moving into place!: $!"; 42 | } 43 | } 44 | } 45 | 46 | 47 | sub usage 48 | { 49 | my $msg = join(" ",@_); 50 | print STDERR << "EOF"; 51 | fix_trailing_whitespace.pl <-show|-fix> file1 [file2 [...]] 52 | -show will list lines with trailing whitespace 53 | -fix will remove the trailing white space 54 | EOF 55 | print STDERR "\n\n$msg\n"; 56 | exit(1); 57 | } 58 | -------------------------------------------------------------------------------- /scripts/flowvisor-emma.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #base=PREFIX 4 | 5 | if [ -z $base ] ; then 6 | envs=`dirname $0`/../scripts/envs.sh 7 | DEBUG=yes 8 | else 9 | envs=/etc/flowvisor/envs.sh 10 | fi 11 | 12 | if [ -f $envs ] ; then 13 | . $envs 14 | else 15 | echo "Could not find $envs: dying..." >&2 16 | exit 1 17 | fi 18 | 19 | default_jvm_args="-server -Xms100M -Xmx2000M -XX:OnError=flowvisor-crash-logger -XX:+UseConcMarkSweepGC $fv_defines" 20 | emma_jvm_args="-Demma.coverage.out.file=$configbase/coverage/coverage.emma -Demma.coverage.out.merge=true" 21 | 22 | if [ -z $FV_JVM_ARGS ]; then 23 | export FV_JVM_ARGS="$default_jvm_args" 24 | fi 25 | 26 | if [ ! -z $FV_DEBUG_PORT ] ; then 27 | # Checkout http://java.dzone.com/articles/how-debug-remote-java-applicat for 28 | # remote debugging details in java 29 | FV_JVM_ARGS="$FV_JVM_ARGS -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,address=$FV_DEBUG_PORT,server=y" 30 | fi 31 | 32 | echo Starting FlowVisor >&2 33 | #echo Running with FV_JVM_ARGS=$FV_JVM_ARGS >&2 34 | exec java $FV_JVM_ARGS $emma_jvm_args $fv_defines $sslopts -cp $configbase/inst:$emmajar:$classpath org.flowvisor.FlowVisor "$@" 35 | -------------------------------------------------------------------------------- /scripts/flowvisor-javac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #base=PREFIX 4 | 5 | 6 | if [ -z $base ] ; then 7 | envs=`dirname $0`/../scripts/envs.sh 8 | else 9 | envs=$base/etc/flowvisor/envs.sh 10 | fi 11 | 12 | if [ -f $envs ] ; then 13 | . $envs 14 | else 15 | echo "Could not find $envs: dying..." >&2 16 | exit 1 17 | fi 18 | 19 | # just in case we have to invoke things by hand 20 | javac -cp $classpath "$@" 21 | -------------------------------------------------------------------------------- /scripts/flowvisor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #base=PREFIX 4 | 5 | if [ -z "$FV_RUN_AS_ROOT" -o "x$FV_RUN_AS_ROOT" != "xyes" ]; then 6 | if [ `id -u` -eq 0 ]; then 7 | echo "FlowVisor should not be run as root" 8 | exit 1 9 | fi 10 | fi 11 | 12 | 13 | if [ -z $base ] ; then 14 | envs=`dirname $0`/../scripts/envs.sh 15 | DEBUG=yes 16 | else 17 | envs=/etc/flowvisor/envs.sh 18 | fi 19 | 20 | if [ -f $envs ] ; then 21 | . $envs 22 | else 23 | echo "Could not find $envs: dying..." >&2 24 | exit 1 25 | fi 26 | 27 | default_jvm_args="-server -Xms100M -Xmx2000M -XX:OnError=flowvisor-crash-logger -XX:+UseConcMarkSweepGC $fv_defines" 28 | 29 | 30 | if [ -z $FV_JVM_ARGS ]; then 31 | export FV_JVM_ARGS="$default_jvm_args" 32 | fi 33 | 34 | if [ ! -z $FV_DEBUG_PORT ] ; then 35 | # Checkout http://java.dzone.com/articles/how-debug-remote-java-applicat for 36 | # remote debugging details in java 37 | FV_JVM_ARGS="$FV_JVM_ARGS -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,address=$FV_DEBUG_PORT,server=y" 38 | fi 39 | 40 | echo Starting FlowVisor >&2 41 | #echo Running with FV_JVM_ARGS=$FV_JVM_ARGS >&2 42 | exec java $FV_JVM_ARGS $fv_defines $sslopts -cp $classpath org.flowvisor.FlowVisor "$@" 43 | -------------------------------------------------------------------------------- /scripts/fvconfig.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #base=PREFIX 4 | 5 | usage() { 6 | cat << "EOF" 7 | USAGE: fvconfig cmd config.json [options] 8 | match config.json 9 | load config.json 10 | chpasswd config.json 11 | query config.json [slicename] 12 | convert config.json 13 | generate newconfig.json [hostname] [admin_passwd] [of_port] [api_port] 14 | generateCert hostname 15 | EOF 16 | exit 1 17 | } 18 | 19 | if [ -z $base ] ; then 20 | envs=`dirname $0`/../scripts/envs.sh 21 | else 22 | envs=$install_root/etc/flowvisor/envs.sh 23 | fi 24 | 25 | if [ -f $envs ] ; then 26 | . $envs 27 | else 28 | echo "Could not find $envs: dying..." >&2 29 | exit 1 30 | fi 31 | 32 | if [ "x$1" = "x" ] ; then 33 | usage 34 | exit 1 35 | fi 36 | 37 | makeSSL() { 38 | echo "Trying to generate SSL Server Key with passwd from scripts/envs.sh" >&2 39 | if [ "X$1" != "X" ] ; then 40 | cn=$1 41 | else 42 | cn=`hostname` 43 | fi 44 | echo Generating cert with common name == $cn 45 | dname="-dname cn=$cn" 46 | keytool -genkey -keystore $SSL_KEYSTORE -storepass $SSL_KEYPASSWD -keypass $SSL_KEYPASSWD -keyalg DSA $dname 47 | } 48 | 49 | cmd=$1 50 | shift 51 | case "X$cmd" in 52 | Xmatch) 53 | exec java -cp $classpath $fv_defines org.flowvisor.message.FVPacketIn "$@" 54 | ;; 55 | Xload) 56 | exec java -cp $classpath $fv_defines org.flowvisor.config.LoadConfig "$@" 57 | ;; 58 | Xchpasswd) 59 | exec java -cp $classpath $fv_defines org.flowvisor.api.APIAuth "$@" 60 | ;; 61 | Xquery) 62 | exec java -cp $classpath $fv_defines org.flowvisor.flows.FlowSpaceUtil "$@" 63 | ;; 64 | Xconvert) 65 | exec java -cp $classpath $fv_defines org.flowvisor.config.convertor.Convertor "$@" 66 | ;; 67 | XgenerateCert) 68 | makeSSL $1 69 | ;; 70 | Xgenerate) 71 | java $fv_defines -cp $classpath org.apache.derby.tools.ij $logfile/FlowVisorDB.sql > /dev/null 72 | makeSSL $2 73 | exec java -cp $classpath $fv_defines org.flowvisor.config.FVConfig $1 $3 $4 $5 74 | ;; 75 | 76 | X) 77 | usage 78 | ;; 79 | *) 80 | echo "Unknown command '$cmd' : $@" >&2 81 | usage 82 | ;; 83 | esac 84 | 85 | 86 | -------------------------------------------------------------------------------- /scripts/fvctl-xml.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #base=PREFIX 4 | 5 | echo "Warning: The XMLRPC interface is deprecated, and will be removed in future versions" 6 | 7 | if [ -z $base ] ; then 8 | envs=`dirname $0`/../scripts/envs.sh 9 | else 10 | envs=/etc/flowvisor/envs.sh 11 | fi 12 | 13 | if [ -f $envs ] ; then 14 | . $envs 15 | else 16 | echo "Could not find $envs: dying..." >&2 17 | exit 1 18 | fi 19 | 20 | exec java -cp $classpath $fv_defines org.flowvisor.api.FVCtl "$@" 21 | -------------------------------------------------------------------------------- /scripts/fvlog.config: -------------------------------------------------------------------------------- 1 | ##### 2 | ## See README.syslog for more information 3 | ##### 4 | 5 | log4j.rootCategory=WARN, system 6 | 7 | # Console logger 8 | #log4j.appender.A1=org.apache.log4j.ConsoleAppender 9 | #log4j.appender.A1.layout=org.apache.log4j.PatternLayout 10 | #log4j.appender.A1.layout.ConversionPattern=%m%n 11 | 12 | # Rolling file logger 13 | #log4j.appender.F=org.apache.log4j.RollingFileAppender 14 | #log4j.appender.F.File=test.log 15 | 16 | #log4j.appender.F.layout=org.apache.log4j.PatternLayout 17 | #log4j.appender.F.layout.ConversionPattern=%p %l %m %n 18 | 19 | 20 | # Flowvisor syslog logger. Logs to the system logger. 21 | # Currently outputs the priority followed by the message. 22 | log4j.appender.system=org.flowvisor.log.AnyLogger 23 | log4j.appender.system.Protocol=unix_socket 24 | log4j.appender.system.layout=org.apache.log4j.PatternLayout 25 | log4j.appender.system.layout.ConversionPattern=%p %m %n 26 | -------------------------------------------------------------------------------- /scripts/logrotate: -------------------------------------------------------------------------------- 1 | /var/log/flowvisor/flowvisor-db.log /var/log/flowvisor/flowvisor-stderr.log { 2 | weekly 3 | size 1M 4 | copytruncate 5 | rotate 10 6 | compress 7 | maxage 100 8 | missingok 9 | } 10 | -------------------------------------------------------------------------------- /scripts/make-release-repo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | fv_main=src/org/flowvisor/FlowVisor.java 4 | 5 | if [ "X$1" = "X" ] ; then 6 | echo "Usage: $0 release-type" >&2 7 | exit 1 8 | fi 9 | 10 | rtype=$1 11 | 12 | release=`sed -n '/FLOWVISOR_VERSION = [^ ]\+/p' $fv_main | awk {' print $7 '} | sed 's/;//' | sed 's/\"//g'` 13 | version=`echo $release | sed -e 's/^flowvisor-//'` 14 | 15 | echo "Making debian package (using sudo)" >&2 16 | sudo ./scripts/make-deb-repo.sh $version $rtype 17 | 18 | echo "Making rpm package (using sudo)" >&2 19 | sudo ./scripts/make-rpm-repo.sh $version $rtype 20 | 21 | sudo make clean 22 | -------------------------------------------------------------------------------- /scripts/make-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | fv_main=src/org/flowvisor/FlowVisor.java 4 | 5 | if [ "X$1" = "X" ] ; then 6 | echo "Usage: $0 release-type" >&2 7 | exit 1 8 | fi 9 | 10 | rtype=$1 11 | 12 | release=`sed -n '/FLOWVISOR_VERSION = [^ ]\+/p' $fv_main | awk {' print $7 '} | sed 's/;//' | sed 's/\"//g'` 13 | 14 | echo "Making debian package (using sudo)" >&2 15 | version=`echo $release | sed -e 's/^flowvisor-//'` 16 | sudo ./scripts/make-deb.sh $version $rtype 17 | sudo make clean 18 | sudo chown -R jenkins:nogroup ./scripts/DEB 19 | -------------------------------------------------------------------------------- /scripts/make-repo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Deb 4 | # Assumes mini-dinstall has initialized (run once like below) 5 | mini-dinstall -c /var/packages/repo/mini-dinstall.conf -b 6 | s3cmd --verbose --acl-public --recursive sync /var/packages/repo/debian/stable s3://updates.onlab.us/debian/ 7 | s3cmd --verbose --acl-public --recursive sync /var/packages/repo/debian/staging s3://updates.onlab.us/debian/ 8 | s3cmd --verbose --acl-public --recursive sync /var/packages/repo/debian/unstable s3://updates.onlab.us/debian/ 9 | 10 | # Rpm 11 | # Assumes createrepo has initialized all three directories (run w/o --update) 12 | createrepo --update --database /var/packages/repo/rpm/stable 13 | createrepo --update --database /var/packages/repo/rpm/staging 14 | createrepo --update --database /var/packages/repo/rpm/unstable 15 | s3cmd --verbose --acl-public --recursive sync /var/packages/repo/rpm/stable s3://updates.onlab.us/rpm/ 16 | s3cmd --verbose --acl-public --recursive sync /var/packages/repo/rpm/staging s3://updates.onlab.us/rpm/ 17 | s3cmd --verbose --acl-public --recursive sync /var/packages/repo/rpm/unstable s3://updates.onlab.us/rpm/ 18 | -------------------------------------------------------------------------------- /scripts/run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | REV=$1 5 | REPO=git://github.com/OPENNETWORKINGLAB/flowvisor-test.git 6 | ./scripts/fvconfig.sh generateCert 7 | 8 | git clone $REPO 9 | cd flowvisor-test 10 | git checkout $REV 11 | 12 | cd tests 13 | 14 | ./fvt --verbose --fv-cmd=../../scripts/flowvisor-emma.sh 15 | 16 | if [ $? -gt "0" ]; then 17 | exit 1 18 | else 19 | exit 0 20 | fi 21 | -------------------------------------------------------------------------------- /scripts/xmlrpc_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import xmlrpclib 3 | 4 | user="root" 5 | passwd="0fw0rk" 6 | s = xmlrpclib.ServerProxy("https://" + user + ":" + passwd + "@localhost:8080/xmlrpc") 7 | print "=============== Root's view ================" 8 | print s.api.ping("Joe mama") 9 | for x in s.api.listFlowSpace(): 10 | print x 11 | 12 | user="alice" 13 | passwd="alicePass" 14 | s = xmlrpclib.ServerProxy("https://" + user + ":" + passwd + "@localhost:8080/xmlrpc") 15 | print "=============== Alice's view ================" 16 | print s.api.ping("Joe mama") 17 | for x in s.api.listFlowSpace(): 18 | print x 19 | print s.api.getDevices() 20 | #print s.api.change_passwd("alice","foo") 21 | user="bob" 22 | passwd="bobPass" 23 | s = xmlrpclib.ServerProxy("https://" + user + ":" + passwd + "@localhost:8080/xmlrpc") 24 | print "=============== Bob's view ================" 25 | print s.api.ping("Joe mama") 26 | for x in s.api.listFlowSpace(): 27 | print x 28 | #print s.api.changePasswd("alice","foo") 29 | 30 | #### FIXME 31 | #print "=============== available methods ============" 32 | # Print list of available methods 33 | #print s.system.listMethods() 34 | -------------------------------------------------------------------------------- /src.tests/org/flowvisor/config/BracketParseTest.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import junit.framework.TestCase; 4 | 5 | import org.flowvisor.flows.FlowEntry; 6 | import org.flowvisor.flows.SliceAction; 7 | import org.flowvisor.log.DevNullLogger; 8 | import org.flowvisor.log.FVLog; 9 | import org.flowvisor.openflow.protocol.FVMatch; 10 | import org.openflow.protocol.OFMatch; 11 | 12 | public class BracketParseTest extends TestCase { 13 | 14 | @Override 15 | protected void setUp() { 16 | FVLog.setDefaultLogger(new DevNullLogger()); 17 | } 18 | public void testBracketParse() { 19 | FVMatch match = new FVMatch(); 20 | match.setWildcards(OFMatch.OFPFW_ALL & (~OFMatch.OFPFW_IN_PORT)); 21 | match.setInputPort((short) 4); 22 | 23 | FlowEntry rule = new FlowEntry(FlowEntry.ALL_DPIDS, match, 24 | new SliceAction("bob", SliceAction.WRITE)); 25 | String test = rule.toString(); 26 | FlowEntry testRule = FlowEntry.fromString(test); 27 | TestCase.assertEquals(rule, testRule); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src.tests/org/flowvisor/flows/FlowTestOpTest.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.flows; 2 | 3 | import junit.framework.TestCase; 4 | 5 | import org.flowvisor.log.DevNullLogger; 6 | import org.flowvisor.log.FVLog; 7 | import org.flowvisor.openflow.protocol.FVMatch; 8 | 9 | 10 | public class FlowTestOpTest extends TestCase { 11 | 12 | @Override 13 | protected void setUp() { 14 | // don't do logging in unittests 15 | FVLog.setDefaultLogger(new DevNullLogger()); 16 | } 17 | 18 | public void testCIDRMatch() { 19 | FlowEntry flowEntry = new FlowEntry(new FVMatch() 20 | .setWildcards(FVMatch.OFPFW_ALL), new SliceAction("alice", 21 | SliceAction.WRITE)); 22 | FlowIntersect intersect = new FlowIntersect(flowEntry); 23 | int rip = 0xaabbccdd; 24 | int ip = FlowTestOp.testFieldMask(intersect, 25 | FVMatch.OFPFW_NW_DST_SHIFT, 32, 0, rip, 0x00000000); 26 | TestCase.assertEquals(rip, ip); 27 | int dmask = intersect.getMatch().getNetworkDestinationMaskLen(); 28 | TestCase.assertEquals(32, dmask); 29 | int goodBits = (~FVMatch.OFPFW_NW_DST_MASK) & FVMatch.OFPFW_ALL; 30 | int wildcards = intersect.getMatch().getWildcards(); 31 | TestCase.assertEquals(goodBits, wildcards); 32 | 33 | rip = 0; 34 | ip = FlowTestOp.testFieldMask(intersect, FVMatch.OFPFW_NW_SRC_SHIFT, 0, 35 | 0, rip, 0x00000000); 36 | TestCase.assertEquals(rip, ip); 37 | dmask = intersect.getMatch().getNetworkSourceMaskLen(); 38 | TestCase.assertEquals(0, dmask); 39 | wildcards = intersect.getMatch().getWildcards(); 40 | TestCase.assertEquals(goodBits, wildcards); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/org/flowvisor/ShutdownHook.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor; 2 | 3 | import org.flowvisor.config.FVConfigurationController; 4 | import org.flowvisor.log.FVLog; 5 | import org.flowvisor.log.LogLevel; 6 | 7 | /** 8 | * 9 | * Attempts to hook into the VM to detect a shutdown 10 | * procedure. It is not guaranteed but better than 11 | * nothing. 12 | * 13 | * Shuts down the db backend cleanly. 14 | * 15 | * 16 | * @author ash 17 | * 18 | */ 19 | public class ShutdownHook extends Thread { 20 | public void run() { 21 | FVLog.log(LogLevel.INFO, null, "Shutting down config database."); 22 | FVConfigurationController.instance().shutdown(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/APIUserCred.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api; 2 | 3 | 4 | /** 5 | * Thread-local list of this User's credentials 6 | * 7 | * used as a HACK to get around the fact that servlets are stateless 8 | * 9 | * @author capveg 10 | * 11 | */ 12 | public class APIUserCred { 13 | String userName; 14 | String ip; 15 | 16 | private final static ThreadLocal threadCred = new ThreadLocal(); 17 | 18 | public APIUserCred() { 19 | this.userName = "unknown"; 20 | this.ip = "unknown"; 21 | } 22 | 23 | static public String getIP() { 24 | return APIUserCred.getThreadCred().ip; 25 | } 26 | 27 | static public void setIP(String ip) { 28 | APIUserCred.getThreadCred().ip = ip; 29 | } 30 | 31 | static public String getUserName() { 32 | return APIUserCred.getThreadCred().userName; 33 | } 34 | 35 | static public void setUserName(String userName) { 36 | APIUserCred cred = APIUserCred.getThreadCred(); 37 | cred.userName = userName; 38 | } 39 | 40 | static public void setThreadCred(APIUserCred cred) { 41 | threadCred.set(cred); 42 | } 43 | 44 | static public APIUserCred getThreadCred() { 45 | 46 | APIUserCred cred = threadCred.get(); 47 | if (cred == null) { 48 | cred = new APIUserCred(); 49 | threadCred.set(cred); 50 | } 51 | return cred; 52 | } 53 | } -------------------------------------------------------------------------------- /src/org/flowvisor/api/FVRpcErrorLogger.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api; 2 | 3 | import org.apache.xmlrpc.server.XmlRpcErrorLogger; 4 | import org.flowvisor.exceptions.FVException; 5 | import org.flowvisor.log.FVLog; 6 | import org.flowvisor.log.LogLevel; 7 | 8 | 9 | /** 10 | * A wrapper around FVLog for the XMLRPC webserver 11 | * 12 | * @author capveg 13 | * 14 | */ 15 | 16 | public class FVRpcErrorLogger extends XmlRpcErrorLogger { 17 | 18 | /** 19 | * Wrapper around FVLog; 20 | * 21 | * If the throwable is an FVException or SSLException, assume 22 | * that it's just an API call that is intentionally propagating an 23 | * error back to the caller, so we just log it as DEBUG. 24 | * Else log as WARN. 25 | * @param msg A string to log 26 | * @param throwable an exception to log 27 | */ 28 | 29 | @Override 30 | public void log(String msg, Throwable throwable) { 31 | LogLevel logLevel = LogLevel.WARN; 32 | Throwable cause = throwable.getCause(); 33 | if (cause instanceof FVException || 34 | cause instanceof javax.net.ssl.SSLException) 35 | logLevel = LogLevel.DEBUG; 36 | if (cause != null) 37 | throwable = cause; // skip down to the inner exception 38 | StackTraceElement[] stackTrace= throwable.getStackTrace(); 39 | FVLog.log(logLevel, null, msg, "(exception = ",throwable.getClass(),")" ); 40 | for(int i=0; i< stackTrace.length; i++) 41 | FVLog.log(logLevel, null, " at ", stackTrace[i]); 42 | } 43 | 44 | @Override 45 | public void log(String msg) { 46 | FVLog.log(LogLevel.INFO, null, msg); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/FVUserAPIJSON.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api; 2 | 3 | import java.net.MalformedURLException; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | import org.flowvisor.config.ConfigError; 8 | import org.flowvisor.exceptions.FlowEntryNotFound; 9 | import org.flowvisor.exceptions.PermissionDeniedException; 10 | import org.flowvisor.flows.FlowEntry; 11 | 12 | public interface FVUserAPIJSON extends FVUserAPI { 13 | 14 | /** 15 | * Lists all the flowspace this user has control over 16 | * 17 | * @return 18 | * @throws ConfigError 19 | */ 20 | public Collection listFlowSpace() throws ConfigError; 21 | 22 | Collection changeFlowSpace(List changes) 23 | throws PermissionDeniedException, FlowEntryNotFound, ConfigError; 24 | 25 | public Boolean registerTopologyEventCallback(String URL, String method, String eventType) throws MalformedURLException; 26 | 27 | public boolean deregisterTopologyEventCallback(String method, String eventType); 28 | } 29 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/FlowSpaceChangeRequest.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api; 2 | 3 | import org.flowvisor.flows.FlowEntry; 4 | 5 | public class FlowSpaceChangeRequest { 6 | 7 | FlowEntry entry; 8 | String changeType; 9 | 10 | protected FlowSpaceChangeRequest(){ 11 | // For Serializaton 12 | } 13 | 14 | public FlowSpaceChangeRequest(FlowEntry entry, String changeType){ 15 | this.entry = entry; 16 | this.changeType = changeType; 17 | } 18 | 19 | public FlowEntry getEntry() { 20 | return entry; 21 | } 22 | 23 | public String getChangeType() { 24 | return changeType; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/FlowVisorLoginService.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api; 2 | 3 | import javax.security.auth.Subject; 4 | 5 | import org.eclipse.jetty.security.DefaultIdentityService; 6 | import org.eclipse.jetty.security.DefaultUserIdentity; 7 | import org.eclipse.jetty.security.IdentityService; 8 | import org.eclipse.jetty.security.LoginService; 9 | import org.eclipse.jetty.server.Authentication; 10 | import org.eclipse.jetty.server.UserIdentity; 11 | import org.eclipse.jetty.server.UserIdentity.Scope; 12 | 13 | public class FlowVisorLoginService implements LoginService { 14 | 15 | private IdentityService identityService = new DefaultIdentityService(); 16 | 17 | @Override 18 | public IdentityService getIdentityService() { 19 | return identityService; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return JettyServer.REALM_NAME; 25 | } 26 | 27 | @Override 28 | public UserIdentity login(String username, Object credentials) { 29 | if (APIAuth.isAuthorized(username, (String) credentials, "")) { 30 | FlowVisorAuthenticatedUser user = 31 | new FlowVisorAuthenticatedUser(username, (String) credentials); 32 | return user.getUserIdentity(); 33 | } 34 | return null; 35 | } 36 | 37 | @Override 38 | public void setIdentityService(IdentityService ids) {} 39 | 40 | @Override 41 | public boolean validate(UserIdentity arg0) { 42 | return false; 43 | } 44 | 45 | public class FlowVisorAuthenticatedUser implements Authentication.User { 46 | 47 | 48 | public FlowVisorAuthenticatedUser(String username, String password){ 49 | 50 | } 51 | 52 | @Override 53 | public String getAuthMethod() { 54 | return "JettyFlowVisor"; 55 | } 56 | 57 | @Override 58 | public UserIdentity getUserIdentity() { 59 | return new DefaultUserIdentity(new Subject(), null, new String[] {"user"}); 60 | } 61 | 62 | @Override 63 | public boolean isUserInRole(Scope arg0, String arg1) { 64 | return true; 65 | } 66 | 67 | @Override 68 | public void logout() { 69 | // TODO Auto-generated method stub 70 | 71 | } 72 | 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/SSLWebServer.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api; 2 | 3 | import java.net.ServerSocket; 4 | 5 | import javax.net.ssl.SSLServerSocketFactory; 6 | 7 | import org.apache.xmlrpc.webserver.WebServer; 8 | import org.flowvisor.log.FVLog; 9 | import org.flowvisor.log.LogLevel; 10 | 11 | public class SSLWebServer extends WebServer { 12 | 13 | public SSLWebServer(int pPort) { 14 | super(pPort); 15 | // TODO Auto-generated constructor stub 16 | } 17 | 18 | @Override 19 | protected ServerSocket createServerSocket(int pPort, int backlog, 20 | java.net.InetAddress addr) { 21 | try { 22 | //ServerSocketFactory sslFactory = (ServerSocketFactory) ServerSocketFactory 23 | SSLServerSocketFactory sslFactory = (SSLServerSocketFactory) SSLServerSocketFactory 24 | .getDefault(); 25 | String[] ciphers = sslFactory.getDefaultCipherSuites(); 26 | if (ciphers.length == 0) 27 | throw new RuntimeException( 28 | "Need to configure SSL: no ciphers found"); 29 | else { 30 | FVLog.log(LogLevel.DEBUG, null, "SSL Supports " 31 | + ciphers.length + " Ciphers:: "); 32 | for (int i = 0; i < ciphers.length; i++) 33 | FVLog.log(LogLevel.DEBUG, null, " " + ciphers[i]); 34 | } 35 | return sslFactory.createServerSocket(pPort, backlog, addr); 36 | } catch (Exception e) { 37 | e.printStackTrace(); 38 | throw new RuntimeException(e); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/configuration/ListFSInsertionStatus.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.configuration; 2 | 3 | import java.util.Map; 4 | 5 | import org.flowvisor.api.handlers.ApiHandler; 6 | import org.flowvisor.api.handlers.HandlerUtils; 7 | import org.flowvisor.config.FVConfigurationController; 8 | import org.flowvisor.exceptions.MissingRequiredField; 9 | 10 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Error; 11 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 12 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 13 | 14 | public class ListFSInsertionStatus implements ApiHandler> { 15 | 16 | 17 | 18 | 19 | @Override 20 | public JSONRPC2Response process(Map params) { 21 | JSONRPC2Response resp = null; 22 | 23 | try { 24 | Integer id = HandlerUtils.fetchField(FSID, params, true, null).intValue(); 25 | 26 | String status = FVConfigurationController.instance().flowSpaceStatus(id); 27 | resp = new JSONRPC2Response(status, 0); 28 | } catch (ClassCastException e) { 29 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 30 | cmdName() + ": " + e.getMessage()), 0); 31 | } catch (MissingRequiredField e) { 32 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 33 | cmdName() + ": " + e.getMessage()), 0); 34 | } catch (NullPointerException e) { 35 | e.printStackTrace(); 36 | } 37 | return resp; 38 | 39 | } 40 | 41 | 42 | @Override 43 | public JSONRPC2ParamsType getType() { 44 | return JSONRPC2ParamsType.OBJECT; 45 | } 46 | 47 | @Override 48 | public String cmdName() { 49 | return "list-fs-status"; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/configuration/ListSlices.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.configuration; 2 | 3 | import java.util.HashMap; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | import org.flowvisor.api.handlers.ApiHandler; 8 | import org.flowvisor.config.ConfigError; 9 | import org.flowvisor.config.SliceImpl; 10 | 11 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Error; 12 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 13 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 14 | 15 | public class ListSlices implements ApiHandler { 16 | 17 | 18 | 19 | @SuppressWarnings("unchecked") 20 | @Override 21 | public JSONRPC2Response process(Object params) { 22 | JSONRPC2Response resp = null; 23 | try { 24 | List> list = new LinkedList>(); 25 | HashMap slicers = new HashMap(); 26 | List slices = SliceImpl.getProxy().getAllSliceNames(); 27 | for (String slice : slices) { 28 | slicers.put(SLICENAME, slice); 29 | slicers.put(ADMINSTATUS, SliceImpl.getProxy().isSliceUp(slice)); 30 | list.add((HashMap)slicers.clone() ); 31 | slicers.clear(); 32 | } 33 | resp = new JSONRPC2Response(list, 0); 34 | } catch (ConfigError e) { 35 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(), 36 | cmdName() + ": Unable to fetch slice list : " + e.getMessage()), 0); 37 | } 38 | return resp; 39 | 40 | } 41 | 42 | @Override 43 | public JSONRPC2ParamsType getType() { 44 | return JSONRPC2ParamsType.NO_PARAMS; 45 | } 46 | 47 | @Override 48 | public String cmdName() { 49 | return "list-slices"; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/configuration/ListVersion.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.configuration; 2 | 3 | import java.util.HashMap; 4 | 5 | import org.flowvisor.FlowVisor; 6 | import org.flowvisor.api.handlers.ApiHandler; 7 | 8 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 9 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 10 | 11 | public class ListVersion implements ApiHandler { 12 | 13 | 14 | 15 | @Override 16 | public JSONRPC2Response process(Object params) { 17 | 18 | @SuppressWarnings("serial") 19 | HashMap versions = new HashMap() {{ 20 | put("flowvisor-version", FlowVisor.FLOWVISOR_VERSION); 21 | put("db-version", String.valueOf(FlowVisor.FLOWVISOR_DB_VERSION)); 22 | }}; 23 | 24 | return new JSONRPC2Response(versions, 0); 25 | 26 | 27 | } 28 | 29 | @Override 30 | public JSONRPC2ParamsType getType() { 31 | return JSONRPC2ParamsType.NO_PARAMS; 32 | } 33 | 34 | @Override 35 | public String cmdName() { 36 | return "list-version"; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/configuration/RemoveFlowSpace.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.configuration; 2 | 3 | import java.util.List; 4 | 5 | import org.flowvisor.api.handlers.ApiHandler; 6 | import org.flowvisor.config.ConfigError; 7 | import org.flowvisor.config.FVConfig; 8 | import org.flowvisor.config.FlowSpaceImpl; 9 | import org.flowvisor.exceptions.FlowEntryNotFound; 10 | import org.flowvisor.flows.FlowMap; 11 | 12 | 13 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Error; 14 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 15 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 16 | 17 | public class RemoveFlowSpace implements ApiHandler> { 18 | 19 | 20 | 21 | @Override 22 | public JSONRPC2Response process(List params) { 23 | if (params.size() < 1) 24 | return new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 25 | cmdName() + ": Nothing to remove"), 0); 26 | JSONRPC2Response resp = null; 27 | try { 28 | final FlowMap flowSpace = FVConfig.getFlowSpaceFlowMap(); 29 | for (String name : params) { 30 | flowSpace.removeRule(flowSpace.findRuleByName(name).getId()); 31 | } 32 | FlowSpaceImpl.getProxy().removeRuleByName(params); 33 | FlowSpaceImpl.getProxy().notifyChange(flowSpace); 34 | resp = new JSONRPC2Response(true, 0); 35 | } catch (ConfigError e) { 36 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(), 37 | "remove-flowspace: Unable to get flowspace : " + e.getMessage()), 0); 38 | } catch (FlowEntryNotFound e) { 39 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(), 40 | "remove-flowspace: unable to find flow entry : " + e.getMessage()), 0); 41 | } catch (NullPointerException e) { 42 | e.printStackTrace(); 43 | } 44 | return resp; 45 | 46 | } 47 | 48 | @Override 49 | public JSONRPC2ParamsType getType() { 50 | return JSONRPC2ParamsType.ARRAY; 51 | } 52 | 53 | @Override 54 | public String cmdName() { 55 | return "remove-flowspace"; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/configuration/RemoveSlice.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.configuration; 2 | 3 | import java.util.Map; 4 | 5 | import org.flowvisor.api.handlers.ApiHandler; 6 | import org.flowvisor.api.handlers.HandlerUtils; 7 | import org.flowvisor.config.FVConfig; 8 | import org.flowvisor.config.FlowSpaceImpl; 9 | import org.flowvisor.config.InvalidSliceName; 10 | import org.flowvisor.config.SliceImpl; 11 | import org.flowvisor.exceptions.MissingRequiredField; 12 | import org.flowvisor.flows.FlowMap; 13 | 14 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Error; 15 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 16 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 17 | 18 | public class RemoveSlice implements ApiHandler> { 19 | 20 | 21 | 22 | @Override 23 | public JSONRPC2Response process(Map params) { 24 | JSONRPC2Response resp = null; 25 | try { 26 | /* 27 | * TODO: put notifyChange in futureTask 28 | */ 29 | String sliceName = HandlerUtils.fetchField(SLICENAME, params, true, null); 30 | //Boolean preserve = HandlerUtils.fetchField(PRESERVE, params, false, false); 31 | SliceImpl.getProxy().deleteSlice(sliceName); 32 | FlowMap flowSpace = FVConfig.getFlowSpaceFlowMap(); 33 | FlowSpaceImpl.getProxy().notifyChange(flowSpace); 34 | resp = new JSONRPC2Response(true, 0); 35 | } catch (ClassCastException e) { 36 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 37 | cmdName() + ": " + e.getMessage()), 0); 38 | } catch (MissingRequiredField e) { 39 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 40 | cmdName() + ": " + e.getMessage()), 0); 41 | } catch (InvalidSliceName e) { 42 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 43 | cmdName() + ": " + e.getMessage()), 0); 44 | } 45 | return resp; 46 | 47 | } 48 | 49 | @Override 50 | public JSONRPC2ParamsType getType() { 51 | return JSONRPC2ParamsType.OBJECT; 52 | } 53 | 54 | @Override 55 | public String cmdName() { 56 | return "remove-slice"; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/configuration/SaveConfig.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.configuration; 2 | 3 | 4 | import org.flowvisor.api.handlers.ApiHandler; 5 | import org.flowvisor.config.FVConfig; 6 | 7 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 8 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 9 | 10 | public class SaveConfig implements ApiHandler { 11 | 12 | 13 | 14 | @Override 15 | public JSONRPC2Response process(Object params) { 16 | 17 | 18 | return new JSONRPC2Response(FVConfig.getConfig(), 0); 19 | 20 | 21 | } 22 | 23 | @Override 24 | public JSONRPC2ParamsType getType() { 25 | return JSONRPC2ParamsType.NO_PARAMS; 26 | } 27 | 28 | @Override 29 | public String cmdName() { 30 | return "save-config"; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/monitoring/ListDatapathFlowDB.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.monitoring; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import org.flowvisor.api.handlers.ApiHandler; 8 | import org.flowvisor.api.handlers.HandlerUtils; 9 | import org.flowvisor.classifier.FVClassifier; 10 | import org.flowvisor.config.FlowSpace; 11 | import org.flowvisor.exceptions.DPIDNotFound; 12 | import org.flowvisor.exceptions.MissingRequiredField; 13 | import org.flowvisor.flows.FlowDBEntry; 14 | import org.flowvisor.flows.FlowSpaceUtil; 15 | 16 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Error; 17 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 18 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 19 | 20 | public class ListDatapathFlowDB implements ApiHandler> { 21 | 22 | 23 | 24 | @Override 25 | public JSONRPC2Response process(Map params) { 26 | JSONRPC2Response resp = null; 27 | List> retvals = new LinkedList>(); 28 | 29 | try { 30 | Long dpid = FlowSpaceUtil.parseDPID( 31 | HandlerUtils.fetchField(FlowSpace.DPID, params, true, null)); 32 | FVClassifier classifier = HandlerUtils.getClassifierByDPID(dpid); 33 | for (FlowDBEntry fbe : classifier.getFlowDB()) { 34 | retvals.add(fbe.toMap()); 35 | } 36 | 37 | resp = new JSONRPC2Response(retvals, 0); 38 | } catch (ClassCastException e) { 39 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 40 | cmdName() + ": " + e.getMessage()), 0); 41 | } catch (MissingRequiredField e) { 42 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 43 | cmdName() + ": " + e.getMessage()), 0); 44 | } catch (DPIDNotFound e) { 45 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 46 | cmdName() + ": " + e.getMessage()), 0); 47 | } 48 | return resp; 49 | 50 | } 51 | 52 | 53 | 54 | @Override 55 | public JSONRPC2ParamsType getType() { 56 | return JSONRPC2ParamsType.OBJECT; 57 | } 58 | 59 | @Override 60 | public String cmdName() { 61 | return "list-datapath-info"; 62 | } 63 | 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/monitoring/ListDatapathStats.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.monitoring; 2 | 3 | import java.util.Map; 4 | 5 | import org.flowvisor.api.handlers.ApiHandler; 6 | import org.flowvisor.api.handlers.HandlerUtils; 7 | import org.flowvisor.config.FlowSpace; 8 | import org.flowvisor.exceptions.DPIDNotFound; 9 | import org.flowvisor.exceptions.MissingRequiredField; 10 | import org.flowvisor.flows.FlowSpaceUtil; 11 | 12 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Error; 13 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 14 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 15 | 16 | public class ListDatapathStats implements ApiHandler> { 17 | 18 | 19 | 20 | @Override 21 | public JSONRPC2Response process(Map params) { 22 | JSONRPC2Response resp = null; 23 | try { 24 | Long dpid = FlowSpaceUtil.parseDPID( 25 | HandlerUtils.fetchField(FlowSpace.DPID, params, true, null)); 26 | resp = new JSONRPC2Response( 27 | HandlerUtils.getClassifierByDPID(dpid).getStats().toMap(), 0); 28 | } catch (ClassCastException e) { 29 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 30 | cmdName() + ": " + e.getMessage()), 0); 31 | } catch (MissingRequiredField e) { 32 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 33 | cmdName() + ": " + e.getMessage()), 0); 34 | } catch (DPIDNotFound e) { 35 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 36 | cmdName() + ": " + e.getMessage()), 0); 37 | } 38 | return resp; 39 | 40 | } 41 | 42 | 43 | 44 | @Override 45 | public JSONRPC2ParamsType getType() { 46 | return JSONRPC2ParamsType.OBJECT; 47 | } 48 | 49 | @Override 50 | public String cmdName() { 51 | return "list-datapath-stats"; 52 | } 53 | 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/monitoring/ListDatapaths.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.monitoring; 2 | 3 | import org.flowvisor.api.handlers.ApiHandler; 4 | import org.flowvisor.api.handlers.HandlerUtils; 5 | 6 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 7 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 8 | 9 | public class ListDatapaths implements ApiHandler { 10 | 11 | 12 | 13 | @Override 14 | public JSONRPC2Response process(Object params) { 15 | JSONRPC2Response resp = null; 16 | 17 | 18 | resp = new JSONRPC2Response(HandlerUtils.getAllDevices(), 0); 19 | 20 | return resp; 21 | 22 | } 23 | 24 | 25 | 26 | @Override 27 | public JSONRPC2ParamsType getType() { 28 | return JSONRPC2ParamsType.NO_PARAMS; 29 | } 30 | 31 | @Override 32 | public String cmdName() { 33 | return "list-datapaths"; 34 | } 35 | 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/monitoring/ListFVHealth.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.monitoring; 2 | 3 | import java.util.HashMap; 4 | 5 | import org.flowvisor.api.handlers.ApiHandler; 6 | import org.flowvisor.events.FVEventUtils; 7 | 8 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 9 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 10 | 11 | public class ListFVHealth implements ApiHandler { 12 | 13 | 14 | 15 | @Override 16 | public JSONRPC2Response process(Object params) { 17 | JSONRPC2Response resp = null; 18 | HashMap retvals = new HashMap(); 19 | retvals.put(AVGDELAY, FVEventUtils.averageDelay); 20 | retvals.put(INSTDELAY, FVEventUtils.instDelay); 21 | /*retvals.put(ACTIVE, FVConfigurationController.instance().getSettings().getNumActive() ); 22 | retvals.put(IDLE, FVConfigurationController.instance().getSettings().getNumIdle());*/ 23 | 24 | 25 | resp = new JSONRPC2Response(retvals, 0); 26 | 27 | return resp; 28 | 29 | } 30 | 31 | 32 | 33 | 34 | @Override 35 | public JSONRPC2ParamsType getType() { 36 | return JSONRPC2ParamsType.NO_PARAMS; 37 | } 38 | 39 | @Override 40 | public String cmdName() { 41 | return "list-fv-health"; 42 | } 43 | 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/org/flowvisor/api/handlers/monitoring/ListSliceStats.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.api.handlers.monitoring; 2 | 3 | import java.util.Map; 4 | 5 | import org.flowvisor.api.handlers.ApiHandler; 6 | import org.flowvisor.api.handlers.HandlerUtils; 7 | import org.flowvisor.config.ConfigError; 8 | import org.flowvisor.exceptions.MissingRequiredField; 9 | import org.flowvisor.log.SendRecvDropStats; 10 | import org.flowvisor.slicer.FVSlicer; 11 | 12 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Error; 13 | import com.thetransactioncompany.jsonrpc2.JSONRPC2ParamsType; 14 | import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; 15 | 16 | public class ListSliceStats implements ApiHandler> { 17 | 18 | 19 | 20 | @Override 21 | public JSONRPC2Response process(Map params) { 22 | JSONRPC2Response resp = null; 23 | try { 24 | String sliceName = HandlerUtils.fetchField(SLICENAME, params, true, null); 25 | if (!HandlerUtils.sliceExists(sliceName)) 26 | return new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 27 | cmdName() + ": slice does not exist : " + sliceName), 0); 28 | FVSlicer slicer = HandlerUtils.getSlicerByName(sliceName); 29 | if (slicer == null) 30 | return new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(), 31 | cmdName() + ": " + SendRecvDropStats.NO_STATS_AVAILABLE_MSG + " : " + sliceName), 0); 32 | 33 | resp = new JSONRPC2Response(slicer.getStats().toMap(), 0); 34 | } catch (ClassCastException e) { 35 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 36 | cmdName() + ": " + e.getMessage()), 0); 37 | } catch (MissingRequiredField e) { 38 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), 39 | cmdName() + ": " + e.getMessage()), 0); 40 | } catch (ConfigError e) { 41 | resp = new JSONRPC2Response(new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(), 42 | cmdName() + ": failed to fetch slice stats" + e.getMessage()), 0); 43 | } 44 | return resp; 45 | 46 | } 47 | 48 | 49 | 50 | @Override 51 | public JSONRPC2ParamsType getType() { 52 | return JSONRPC2ParamsType.OBJECT; 53 | } 54 | 55 | @Override 56 | public String cmdName() { 57 | return "list-slice-stats"; 58 | } 59 | 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/org/flowvisor/classifier/CookiePair.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.classifier; 5 | 6 | 7 | /** 8 | * @author capveg 9 | * 10 | */ 11 | public class CookiePair { 12 | long cookie; 13 | String sliceName; 14 | 15 | public CookiePair(long xid, String sliceName) { 16 | this.cookie = xid; 17 | this.sliceName = sliceName; 18 | } 19 | 20 | public long getCookie() { 21 | return cookie; 22 | } 23 | 24 | public void setXid(Long cookie) { 25 | this.cookie = cookie; 26 | } 27 | 28 | /** 29 | * @return the sliceName 30 | */ 31 | public String getSliceName() { 32 | return sliceName; 33 | } 34 | 35 | /** 36 | * @param sliceName the sliceName to set 37 | */ 38 | public void setSliceName(String sliceName) { 39 | this.sliceName = sliceName; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/org/flowvisor/classifier/CookieTranslator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.classifier; 5 | 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Map.Entry; 9 | 10 | import org.flowvisor.slicer.FVSlicer; 11 | import org.openflow.util.LRULinkedHashMap; 12 | 13 | /** 14 | * @author alshabib 15 | * 16 | */ 17 | public class CookieTranslator { 18 | 19 | static final long MIN_COOKIE = 256; 20 | static final int INIT_SIZE = (1 << 12); 21 | static final int MAX_SIZE = (1 << 16); // must be larger than the max 22 | // lifetime of an XID * rate of 23 | // mesgs/sec 24 | long nextID; 25 | 26 | LRULinkedHashMap cookieMap; 27 | 28 | public CookieTranslator() { 29 | this.nextID = MIN_COOKIE; 30 | this.cookieMap = new LRULinkedHashMap(INIT_SIZE, 31 | MAX_SIZE); 32 | 33 | } 34 | 35 | public CookiePair untranslateAndRemove(Long cookie) { 36 | return cookieMap.remove(cookie); 37 | } 38 | 39 | public CookiePair untranslate(Long cookie) { 40 | return cookieMap.get(cookie); 41 | } 42 | 43 | public long translate(Long cookie, FVSlicer fvSlicer) { 44 | long ret = this.nextID++; 45 | if (nextID < MIN_COOKIE) 46 | nextID = MIN_COOKIE; 47 | cookieMap.put(ret, new CookiePair(cookie, fvSlicer.getSliceName())); 48 | return ret; 49 | } 50 | 51 | public List getCookieList(String deleteSlice) { 52 | List cookies = new LinkedList(); 53 | for (Entry entry : cookieMap.entrySet()) { 54 | if (entry.getValue().sliceName.equalsIgnoreCase(deleteSlice)) 55 | cookies.add(entry.getValue().getCookie()); 56 | } 57 | return cookies; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/org/flowvisor/classifier/FVSendMsg.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.classifier; 2 | 3 | import org.flowvisor.log.SendRecvDropStats; 4 | import org.openflow.protocol.OFMessage; 5 | 6 | public interface FVSendMsg { 7 | public void sendMsg(OFMessage msg, FVSendMsg from); 8 | 9 | public void dropMsg(OFMessage msg, FVSendMsg from); 10 | 11 | public SendRecvDropStats getStats(); 12 | 13 | public String getConnectionName(); 14 | 15 | public String getName(); 16 | } 17 | -------------------------------------------------------------------------------- /src/org/flowvisor/classifier/XidPair.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.classifier; 5 | 6 | 7 | /** 8 | * @author capveg 9 | * 10 | */ 11 | public class XidPair { 12 | int xid; 13 | String sliceName; 14 | 15 | public XidPair(int xid, String sliceName) { 16 | this.xid = xid; 17 | this.sliceName = sliceName; 18 | } 19 | 20 | public int getXid() { 21 | return xid; 22 | } 23 | 24 | public void setXid(int xid) { 25 | this.xid = xid; 26 | } 27 | 28 | /** 29 | * @return the sliceName 30 | */ 31 | public String getSliceName() { 32 | return sliceName; 33 | } 34 | 35 | /** 36 | * @param sliceName the sliceName to set 37 | */ 38 | public void setSliceName(String sliceName) { 39 | this.sliceName = sliceName; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/org/flowvisor/classifier/XidPairWithMessage.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.classifier; 2 | 3 | import org.flowvisor.slicer.FVSlicer; 4 | import org.openflow.protocol.OFMessage; 5 | 6 | public class XidPairWithMessage extends XidPair { 7 | 8 | OFMessage msg; 9 | FVSlicer fvSlicer; 10 | 11 | public XidPairWithMessage(XidPair xidPair, OFMessage ofMessage) { 12 | super(xidPair.xid, xidPair.sliceName); 13 | this.msg = ofMessage; 14 | } 15 | 16 | public OFMessage getOFMessage() { 17 | return msg; 18 | } 19 | 20 | public void setSlicer(FVSlicer slicer) { 21 | this.fvSlicer = slicer; 22 | 23 | } 24 | 25 | public FVSlicer getSlicer() { 26 | return fvSlicer; 27 | } 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/org/flowvisor/classifier/XidTranslator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.classifier; 5 | 6 | import org.flowvisor.slicer.FVSlicer; 7 | import org.openflow.util.LRULinkedHashMap; 8 | 9 | /** 10 | * @author capveg 11 | * 12 | */ 13 | public class XidTranslator { 14 | 15 | static final int MIN_XID = 256; 16 | static final int INIT_SIZE = (1 << 12); 17 | static final int MAX_SIZE = (1 << 14); // must be larger than the max 18 | // lifetime of an XID * rate of 19 | // mesgs/sec 20 | int nextID; 21 | LRULinkedHashMap xidMap; 22 | 23 | public XidTranslator() { 24 | this.nextID = MIN_XID; 25 | this.xidMap = new LRULinkedHashMap(INIT_SIZE, 26 | MAX_SIZE); 27 | 28 | } 29 | 30 | public XidPair untranslate(int xid) { 31 | return xidMap.get(Integer.valueOf(xid)); 32 | } 33 | 34 | public int translate(int xid, FVSlicer fvSlicer) { 35 | int ret = this.nextID++; 36 | if (nextID < MIN_XID) 37 | nextID = MIN_XID; 38 | xidMap.put(Integer.valueOf(ret), new XidPair(xid, fvSlicer.getSliceName())); 39 | return ret; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/org/flowvisor/classifier/XidTranslatorWithMessage.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.classifier; 2 | 3 | import org.flowvisor.slicer.FVSlicer; 4 | import org.openflow.protocol.OFMessage; 5 | import org.openflow.util.LRULinkedHashMap; 6 | 7 | public class XidTranslatorWithMessage extends XidTranslator { 8 | 9 | 10 | LRULinkedHashMap msgMap; 11 | 12 | public XidTranslatorWithMessage() { 13 | super(); 14 | this.msgMap = new LRULinkedHashMap(INIT_SIZE, 15 | MAX_SIZE); 16 | } 17 | 18 | public int translate(OFMessage original, int xid, FVSlicer fvSlicer) { 19 | int ret = translate(xid, fvSlicer); 20 | msgMap.put(Integer.valueOf(ret), original); 21 | return ret; 22 | } 23 | 24 | public XidPairWithMessage untranslate(int xid) { 25 | XidPair xidPair = super.untranslate(xid); 26 | if (xidPair == null) 27 | return null; 28 | return new XidPairWithMessage(xidPair, msgMap.get(xid)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/Bracketable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * 10 | * This entire thing is a horrible hack around the fact that my XML encoder 11 | * sucks 12 | * 13 | * I should probably find a better way of dealing with that... 14 | * 15 | * @author capveg 16 | * 17 | */ 18 | public interface Bracketable { 19 | public Map toBracketMap(); 20 | 21 | public E fromBacketMap(Map bracketMap); 22 | } 23 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/ChangedListener.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | /** 4 | * Interface for listeners to the data repository. 5 | * @author ash 6 | * 7 | */ 8 | public interface ChangedListener { 9 | 10 | /** 11 | * Key to the listener data structure for 12 | * a flowmap. 13 | */ 14 | public static String FLOWMAP = "__flowmap"; 15 | 16 | /** 17 | * Key to the listener data structure for 18 | * a flowvisor. 19 | */ 20 | public static String FLOWVISOR = "__flowvisor"; 21 | 22 | 23 | /** 24 | * Callback method implementing the listener. 25 | * 26 | * 27 | * @param event contains the name of the method to 28 | * call for this callback. The method is called 29 | * using reflection. 30 | */ 31 | public void processChange(ConfigurationEvent event); 32 | } 33 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/ConfDBHandler.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | 6 | import javax.sql.DataSource; 7 | 8 | import org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource; 9 | import org.apache.derby.jdbc.EmbeddedDataSource; 10 | import org.flowvisor.log.FVLog; 11 | import org.flowvisor.log.LogLevel; 12 | 13 | 14 | /** 15 | * Defines a connection pool to derby. 16 | * Guarantees that the status of a returned connection 17 | * is valid. 18 | * 19 | * 20 | * @author ash 21 | * 22 | */ 23 | public class ConfDBHandler implements ConfDBSettings { 24 | 25 | private String dbName = null; 26 | 27 | 28 | private EmbeddedConnectionPoolDataSource pds = null; 29 | 30 | 31 | public ConfDBHandler(String dbName) { 32 | this.dbName = System.getProperty("derby.system.home") + "/" + dbName; 33 | } 34 | 35 | public ConfDBHandler() { 36 | this("FlowVisorDB"); 37 | } 38 | 39 | private DataSource getDataSource() { 40 | if (pds != null) 41 | return pds; 42 | 43 | 44 | 45 | pds = new EmbeddedConnectionPoolDataSource(); 46 | pds.setDatabaseName(this.dbName); 47 | 48 | return pds; 49 | } 50 | 51 | @Override 52 | public Connection getConnection() throws SQLException { 53 | return getDataSource().getConnection(); 54 | } 55 | 56 | @Override 57 | public Connection getConnection(String user, String pass) 58 | throws SQLException { 59 | return getDataSource().getConnection(user, pass); 60 | } 61 | 62 | 63 | @Override 64 | public void shutdown() { 65 | try { 66 | //gop.close(); 67 | ((EmbeddedDataSource) getDataSource()).setShutdownDatabase("shutdown"); 68 | } catch (ClassCastException cce) { 69 | //Isn't this a derby db? 70 | } catch (Exception e) { 71 | FVLog.log(LogLevel.WARN, null, "Error on closing connection pool to derby"); 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/ConfDBSettings.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | 6 | 7 | /** 8 | * 9 | * As FV doesn't mandate that derby be the only repository 10 | * type, we define this interface to enforce that no matter 11 | * what the data repository is the behaviour of FV will not 12 | * be modified. In theory, of course. 13 | * 14 | * @author ash 15 | * 16 | */ 17 | public interface ConfDBSettings { 18 | /** 19 | * Obtain a connection for the underlying data 20 | * repository. 21 | * 22 | * 23 | * @return an active connection. 24 | * @throws SQLException 25 | */ 26 | public Connection getConnection() throws SQLException; 27 | 28 | /** 29 | * Obtain a connection for the underlying data 30 | * repository given a username and password. 31 | * 32 | * @param user the username 33 | * @param pass the password 34 | * @return an active connection 35 | * @throws SQLException 36 | */ 37 | public Connection getConnection(String user, String pass) throws SQLException; 38 | 39 | 40 | 41 | /** 42 | * Shutdown the data repository cleanly. 43 | */ 44 | public void shutdown(); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/ConfigError.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config; 5 | 6 | /** 7 | * @author capveg 8 | * 9 | */ 10 | public class ConfigError extends Exception { 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = 1L; 16 | 17 | public ConfigError(String err) { 18 | super(err); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/ConfigurationEvent.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import org.flowvisor.log.FVLog; 6 | import org.flowvisor.log.LogLevel; 7 | 8 | public class ConfigurationEvent { 9 | private String toCall = null; 10 | private Object newValue = null; 11 | private ChangedListener base = null; 12 | 13 | /** 14 | * Constructs a new configuration event. 15 | * 16 | * @param toCall the method to call. 17 | * @param base the base class 18 | * @param newValue parameter to the method 19 | */ 20 | public ConfigurationEvent(String toCall, ChangedListener base, Object newValue) { 21 | this.toCall = toCall; 22 | this.newValue = newValue; 23 | this.base = base; 24 | } 25 | 26 | /** 27 | * Finds and invokes the method that implements the callback 28 | * in the listener class. 29 | */ 30 | public void invoke() { 31 | Method m = null; 32 | try { 33 | try { 34 | m = base.getClass().getMethod(toCall, newValue.getClass()); 35 | } catch (Throwable e) { 36 | /* 37 | * Stupid work around to perform a flowspace callback. 38 | * One day these will go and we will only do differential 39 | * updates.... 40 | */ 41 | 42 | m = base.getClass().getMethod(toCall, newValue.getClass().getInterfaces()[0]); 43 | } 44 | Object arglist[] = new Object[1]; 45 | arglist[0] = newValue; 46 | m.invoke(base, arglist); 47 | } catch (Throwable e) { 48 | e.printStackTrace(); 49 | FVLog.log(LogLevel.CRIT, null, e.getMessage() + " " + m + " " + base); 50 | } 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/FVAppConfig.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import java.io.IOException; 4 | import java.sql.Connection; 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | 8 | public interface FVAppConfig { 9 | /* 10 | * This is an empty interface, and its supposed to be like that! 11 | * It is used so that we don't have to create multiple proxies 12 | * for each datatype. 13 | * 14 | * well it's not exactly empty but whatever, the below methods don't count. 15 | */ 16 | public void setSettings(ConfDBSettings settings); 17 | public void close(Object o); 18 | public void close(Connection conn); 19 | public void notify(Object key, String method, Object newValue); 20 | public HashMap toJson(HashMap output); 21 | public void fromJson(ArrayList> input) throws IOException; 22 | 23 | public void updateDB(int version); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/FVConfigProxy.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | 7 | 8 | public class FVConfigProxy implements InvocationHandler { 9 | 10 | private Object delegate = null; 11 | 12 | public FVConfigProxy(Object delegate) { 13 | this.delegate = delegate; 14 | } 15 | 16 | @Override 17 | public Object invoke(Object proxy, Method method, Object[] args) 18 | throws Throwable { 19 | Object value = null; 20 | try { 21 | value = method.invoke(delegate, args); 22 | return value; 23 | } 24 | catch (InvocationTargetException ex) { 25 | throw ex.getCause(); 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/FlowMapChangedListener.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import org.flowvisor.flows.FlowMap; 4 | 5 | /** 6 | * A listener for a change to the flowmap. 7 | * 8 | * @author ash 9 | * 10 | */ 11 | public interface FlowMapChangedListener extends ChangedListener { 12 | 13 | /** 14 | * Callback method for the flowmap change. 15 | * 16 | * @param in the changed flowmap. 17 | */ 18 | public void flowMapChanged (FlowMap in); 19 | } 20 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/FlowvisorChangedListener.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | public interface FlowvisorChangedListener extends ChangedListener { 4 | public void setFlowTracking(Boolean in); 5 | public void setStatsDescHack(Boolean in); 6 | public void setFloodPerm(String in); 7 | } 8 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/InvalidDropPolicy.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import org.flowvisor.exceptions.FVException; 4 | 5 | public class InvalidDropPolicy extends FVException { 6 | 7 | public InvalidDropPolicy(String err) { 8 | super(err); 9 | } 10 | /** 11 | * 12 | */ 13 | private static final long serialVersionUID = 1L; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/InvalidSliceName.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import org.flowvisor.exceptions.FVException; 4 | 5 | public class InvalidSliceName extends FVException { 6 | 7 | public InvalidSliceName(String err) { 8 | super(err); 9 | } 10 | 11 | /** 12 | * 13 | */ 14 | private static final long serialVersionUID = 1L; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/SliceChangedListener.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | 4 | public interface SliceChangedListener extends ChangedListener { 5 | public void setLLDP(Boolean in); 6 | public void setDropPolicy(String in); 7 | public void setControllerHost(String in); 8 | public void setControllerPort(Integer in); 9 | public void setFlowModLimit(Integer in); 10 | } 11 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/Switch.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import org.openflow.protocol.OFFlowMod; 4 | 5 | public interface Switch extends FVAppConfig { 6 | 7 | // COLUMN NAMES 8 | public static String FLOOD = "flood_perm"; 9 | public static String DPID = "dpid"; 10 | public static final String MFRDESC = "mfr_desc"; 11 | public static final String HWDESC = "hw_desc"; 12 | public static final String SWDESC = "sw_desc"; 13 | public static final String SERIAL = "serial_num"; 14 | public static final String DPDESC = "dp_desc"; 15 | public static final String CAPA = "capabilities"; 16 | 17 | public static final String SWITCH_ID = "switch_id"; 18 | public static final String SLICE_ID = "slice_id"; 19 | public static final String FMLIMIT = "maximum_flow_mods"; 20 | public static final String RATELIMIT = "rate_limit"; 21 | 22 | public static final String LIMITS = "limits"; 23 | 24 | //Table name 25 | public static String TSWITCH = "Switch"; 26 | public static String TLIMIT = "jSliceSwitchLimits"; 27 | 28 | public static String SWITCH = "switches"; 29 | 30 | public String getFloodPerm(Long dpid) throws ConfigError; 31 | public Integer getMaxFlowMods(String sliceName, Long dp) throws ConfigError; 32 | public Integer getRateLimit(String sliceName, Long dp) throws ConfigError; 33 | 34 | public void setFloodPerm(Long dpid, String flood_perm) throws ConfigError; 35 | public void setMaxFlowMods(String sliceName, Long dp, int limit) throws ConfigError; 36 | public void setRateLimit(String sliceName, Long dp, int rate) throws ConfigError; 37 | 38 | public int pushFlowMod(OFFlowMod flowMod, String sliceName, long dpid); 39 | 40 | public void pullFlowMod(int id); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/SwitchChangedListener.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config; 2 | 3 | import java.util.HashMap; 4 | 5 | public interface SwitchChangedListener extends ChangedListener { 6 | public void setFloodPerm(String in); 7 | public void setFlowModLimit(HashMap in); 8 | public void setRateLimit(HashMap in); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfBoolEntry.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config.convertor; 5 | /** 6 | * @author capveg 7 | * 8 | */ 9 | public class ConfBoolEntry extends ConfigEntry { 10 | private boolean bool; 11 | 12 | public ConfBoolEntry() { 13 | super(ConfigType.BOOL); 14 | } 15 | 16 | public ConfBoolEntry(String name) { 17 | super(name, ConfigType.BOOL); 18 | } 19 | 20 | /** 21 | * @return the bool 22 | */ 23 | public boolean getBool() { 24 | return bool; 25 | } 26 | 27 | /** 28 | * @param bool 29 | * the bool to set 30 | */ 31 | public void setBool(boolean bool) { 32 | this.bool = bool; 33 | } 34 | 35 | @Override 36 | public String[] getValue() { 37 | String[] ret = new String[1]; 38 | ret[0] = Boolean.toString(this.bool); 39 | return ret; 40 | } 41 | 42 | @Override 43 | public void setValue(String s) { 44 | this.bool = Boolean.valueOf(s); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfDirEntry.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config.convertor; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collection; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | 11 | /** 12 | * A directory in the config hierarchy. Does not support multiple nodes with the 13 | * same name; they will overwrite 14 | * 15 | * @author capveg 16 | * 17 | */ 18 | public class ConfDirEntry extends ConfigEntry { 19 | HashMap entries; 20 | 21 | /** 22 | * A directory entry in the Config Hierarchy 23 | * 24 | * @param name 25 | */ 26 | public ConfDirEntry(String name) { 27 | super(name, ConfigType.DIR); 28 | this.entries = new HashMap(); 29 | } 30 | 31 | public ConfDirEntry() { 32 | super(ConfigType.DIR); 33 | } 34 | 35 | public HashMap getEntries() { 36 | return entries; 37 | } 38 | 39 | public void setEntries(HashMap entries) { 40 | this.entries = entries; 41 | } 42 | 43 | /** 44 | * Lookup an entry in this directory 45 | * 46 | * @param name 47 | * entry name 48 | * @return 49 | */ 50 | 51 | public ConfigEntry lookup(String name) { 52 | return entries.get(name); 53 | } 54 | 55 | /** 56 | * Add an entry to this directory 57 | * 58 | * @param entry 59 | */ 60 | public void add(ConfigEntry entry) { 61 | entries.put(entry.getName(), entry); 62 | } 63 | 64 | /** 65 | * Remove an entry from this direclty 66 | * 67 | * @param name 68 | * name of entry 69 | */ 70 | public void remove(String name) { 71 | entries.remove(name); 72 | } 73 | 74 | /** 75 | * Return a list of entries for this node 76 | * 77 | * @return 78 | */ 79 | public List list() { 80 | return new ArrayList(entries.keySet()); 81 | } 82 | 83 | public Collection listEntries() { 84 | return entries.values(); 85 | } 86 | 87 | @Override 88 | public String[] getValue() { 89 | return (String[]) entries.keySet().toArray(new String[entries.size()]); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfFlowMapEntry.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config.convertor; 5 | import org.flowvisor.flows.*; 6 | 7 | /** 8 | * @author capveg 9 | * 10 | */ 11 | public class ConfFlowMapEntry extends ConfigEntry { 12 | public FlowMap flowMap; 13 | 14 | public ConfFlowMapEntry(String name) { 15 | super(name, ConfigType.FLOWMAP); 16 | } 17 | 18 | public ConfFlowMapEntry() { 19 | super(ConfigType.FLOWMAP); 20 | } 21 | 22 | public FlowMap getFlowMap() { 23 | return flowMap; 24 | } 25 | 26 | public void setFlowMap(FlowMap flowMap) { 27 | this.flowMap = flowMap; 28 | } 29 | 30 | @Override 31 | public String[] getValue() { 32 | String[] ret = new String[flowMap.countRules()]; 33 | int i = 0; 34 | 35 | for (FlowEntry rule : flowMap.getRules()) { 36 | ret[i] = "" + i + " " + rule.toString(); 37 | i++; 38 | } 39 | return ret; 40 | } 41 | 42 | /** 43 | * This will get called iteratively for each flow entry in this flow map 44 | */ 45 | @Override 46 | public void setValue(String val) { 47 | String[] tokens = val.split(" "); 48 | if (tokens.length < 2) 49 | throw new IllegalArgumentException( 50 | "Expected but got '" + val + "'"); 51 | FlowEntry rule = FlowEntry.fromString(tokens[1]); 52 | flowMap.addRule(rule); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfIntEntry.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config.convertor; 2 | 3 | public class ConfIntEntry extends ConfigEntry { 4 | 5 | int val; 6 | 7 | public ConfIntEntry(String name) { 8 | super(name, ConfigType.INT); 9 | } 10 | 11 | public ConfIntEntry() { 12 | super(ConfigType.INT); 13 | } 14 | 15 | /** 16 | * Get the node's value 17 | * 18 | * @return 19 | */ 20 | public int getInt() { 21 | return this.val; 22 | } 23 | 24 | /** 25 | * Set the node's value 26 | * 27 | * @param val 28 | */ 29 | public void setInt(int val) { 30 | this.val = val; 31 | } 32 | 33 | /** 34 | * Convert val to an integer and store it 35 | * 36 | * @param val 37 | * e.g., "12345" 38 | */ 39 | @Override 40 | public void setValue(String val) { 41 | this.val = Integer.decode(val); 42 | } 43 | 44 | @Override 45 | /** 46 | * @return an string representation of value 47 | */ 48 | public String[] getValue() { 49 | String[] ret = new String[1]; 50 | ret[0] = Integer.toString(this.val); 51 | return ret; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfRealEntry.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config.convertor; 5 | 6 | /** 7 | * @author capveg 8 | * 9 | */ 10 | public class ConfRealEntry extends ConfigEntry { 11 | double val; 12 | 13 | public ConfRealEntry(String name) { 14 | super(name, ConfigType.REAL); 15 | } 16 | 17 | public double getDouble() { 18 | return val; 19 | } 20 | 21 | public void setDouble(double val) { 22 | this.val = val; 23 | } 24 | 25 | @Override 26 | public String[] getValue() { 27 | String[] ret = new String[1]; 28 | ret[0] = Double.toString(this.val); 29 | return ret; 30 | } 31 | 32 | @Override 33 | public void setValue(String s) { 34 | this.val = Double.parseDouble(s); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfStrEntry.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config.convertor; 5 | 6 | /** 7 | * @author capveg 8 | * 9 | */ 10 | public class ConfStrEntry extends ConfigEntry { 11 | String val; 12 | 13 | public ConfStrEntry(String name) { 14 | super(name, ConfigType.STR); 15 | } 16 | 17 | public ConfStrEntry() { 18 | super(ConfigType.STR); 19 | } 20 | 21 | @Override 22 | public String[] getValue() { 23 | String ret[] = new String[1]; 24 | ret[0] = this.val; 25 | return ret; 26 | } 27 | 28 | @Override 29 | public void setValue(String val) { 30 | this.val = val; 31 | } 32 | 33 | public String getString() { 34 | return val; 35 | } 36 | 37 | public void setString(String val) { 38 | this.val = val; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfigCantCreateError.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config.convertor; 5 | /** 6 | * @author capveg 7 | * 8 | */ 9 | public class ConfigCantCreateError extends ConfigError { 10 | 11 | /** 12 | * 13 | */ 14 | private static final long serialVersionUID = 1L; 15 | 16 | /** 17 | * @param err 18 | */ 19 | public ConfigCantCreateError(String err) { 20 | super(err); 21 | // TODO Auto-generated constructor stub 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfigDumper.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config.convertor; 2 | import java.io.PrintStream; 3 | 4 | public class ConfigDumper implements ConfigIterator { 5 | 6 | PrintStream out; 7 | 8 | public ConfigDumper(PrintStream out) { 9 | this.out = out; 10 | } 11 | 12 | @Override 13 | public void visit(String path, ConfigEntry entry) { 14 | ConfigType type = entry.getType(); 15 | String[] values = entry.getValue(); 16 | int i; 17 | for (i = 0; i < values.length; i++) 18 | this.out.println(path + "::" + type + " : " + values[i]); 19 | } 20 | } -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfigError.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config.convertor; 5 | /** 6 | * @author capveg 7 | * 8 | */ 9 | public class ConfigError extends Exception { 10 | 11 | /** 12 | * 13 | */ 14 | private static final long serialVersionUID = 1L; 15 | 16 | public ConfigError(String err) { 17 | super(err); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfigIterator.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config.convertor; 2 | /** 3 | * Interface to walk the config directory 4 | * 5 | * @author capveg 6 | * 7 | */ 8 | 9 | public interface ConfigIterator { 10 | /** 11 | * Called on each node in the subdirectory 12 | * 13 | * @param path 14 | * The path to this entry, e.g.., "slices.alice" 15 | * @param entry 16 | * The actual entry 17 | */ 18 | public void visit(String path, ConfigEntry entry); 19 | } 20 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfigNotFoundError.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config.convertor; 5 | /** 6 | * @author capveg 7 | * 8 | */ 9 | public class ConfigNotFoundError extends ConfigError { 10 | 11 | /** 12 | * 13 | */ 14 | private static final long serialVersionUID = 1L; 15 | 16 | public ConfigNotFoundError(String err) { 17 | super(err); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfigPrinter.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.config.convertor; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | public class ConfigPrinter implements ConfigIterator { 7 | String prefix; 8 | List out; 9 | 10 | public ConfigPrinter(String prefix) { 11 | this.prefix = prefix; 12 | this.out = new LinkedList(); 13 | } 14 | 15 | @Override 16 | public void visit(String path, ConfigEntry entry) { 17 | ConfigType type = entry.getType(); 18 | String[] values = entry.getValue(); 19 | int i; 20 | for (i = 0; i < values.length; i++) 21 | this.out.add(prefix + path + "::" + type + " : " + values[i]); 22 | } 23 | 24 | /** 25 | * @return the out 26 | */ 27 | public List getOut() { 28 | return out; 29 | } 30 | 31 | /** 32 | * @param out 33 | * the out to set 34 | */ 35 | public void setOut(List out) { 36 | this.out = out; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfigType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config.convertor; 5 | 6 | /** 7 | * @author capveg 8 | * 9 | */ 10 | public enum ConfigType { 11 | 12 | DIR(ConfDirEntry.class), // directory 13 | STR(ConfStrEntry.class), // string 14 | INT(ConfIntEntry.class), // integer 15 | REAL(ConfRealEntry.class), // real 16 | FLOWMAP(ConfFlowMapEntry.class), // flowmap 17 | BOOL(ConfBoolEntry.class), // boolean 18 | // FLOWENTRY(ConfigEntry.class) 19 | ; // flow rule/flow entry 20 | 21 | protected Class clazz; 22 | 23 | ConfigType(Class clazz) { 24 | this.clazz = clazz; 25 | } 26 | 27 | public Class toClass() { 28 | return this.clazz; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/org/flowvisor/config/convertor/ConfigWrongTypeError.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.config.convertor; 5 | 6 | /** 7 | * @author capveg 8 | * 9 | */ 10 | public class ConfigWrongTypeError extends ConfigError { 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = 1L; 16 | 17 | /** 18 | * @param err 19 | */ 20 | public ConfigWrongTypeError(String err) { 21 | super(err); 22 | // TODO Auto-generated constructor stub 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/org/flowvisor/events/ConfigUpdateEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.events; 5 | 6 | 7 | /** 8 | * Let an event handler know that a config element that it was watching needs 9 | * updating 10 | * 11 | * @author capveg 12 | * 13 | */ 14 | public class ConfigUpdateEvent extends FVEvent { 15 | String config; 16 | 17 | /** 18 | * @param dst 19 | * Destination event handler 20 | * @param config 21 | * The config element that needs updating 22 | */ 23 | public ConfigUpdateEvent(FVEventHandler dst, String config) { 24 | super(null, dst); 25 | this.config = config; 26 | } 27 | 28 | public ConfigUpdateEvent(ConfigUpdateEvent e) { 29 | super(e); 30 | this.config = e.config; 31 | } 32 | 33 | /** 34 | * Get the name of the config element that needs updating 35 | */ 36 | public String getConfig() { 37 | return this.config; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/org/flowvisor/events/ExampleHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.events; 5 | 6 | import org.flowvisor.exceptions.*; 7 | 8 | /** 9 | * Basic implementation of an event handler Both for reference and used in 10 | * derived classes 11 | * 12 | * @author capveg 13 | * 14 | */ 15 | public class ExampleHandler implements FVEventHandler { 16 | 17 | FVEventLoop loop; 18 | 19 | /** 20 | * Construct a basic event handler 21 | * 22 | * @param loop 23 | * the event loop this handler will reside in 24 | */ 25 | public ExampleHandler(FVEventLoop loop) { 26 | this.loop = loop; 27 | } 28 | 29 | /* 30 | * (non-Javadoc) 31 | * 32 | * @see org.flowvisor.events.FVEventHandler#getThreadContext() 33 | */ 34 | @Override 35 | public long getThreadContext() { 36 | return loop.getThreadContext(); 37 | } 38 | 39 | /* 40 | * (non-Javadoc) 41 | * 42 | * @see 43 | * org.flowvisor.events.FVEventHandler#handleEvent(org.flowvisor.events. 44 | * FVEvent) 45 | */ 46 | @Override 47 | public void handleEvent(FVEvent e) throws UnhandledEvent { 48 | if (Thread.currentThread().getId() != this.getThreadContext()) { 49 | // this event was sent from a different thread context 50 | loop.queueEvent(e); // queue event 51 | return; // and process later 52 | } 53 | // do something with the event here 54 | // .... 55 | 56 | // throw unhandled event for everthing else 57 | throw new UnhandledEvent(e); 58 | } 59 | 60 | /** 61 | * (non-Javadoc) 62 | * 63 | * @see org.flowvisor.events.FVEventHandler#getName() 64 | */ 65 | public String getName() { 66 | return "ExampleHandler"; 67 | } 68 | 69 | /** 70 | * @see org.flowvisor.events.FVEventHandler#tearDown() 71 | */ 72 | @Override 73 | public void tearDown() { 74 | // do nothing 75 | 76 | } 77 | 78 | @Override 79 | public boolean needsConnect() { 80 | return false; // this event never wants connect events 81 | } 82 | 83 | @Override 84 | public boolean needsRead() { 85 | return true; // we always want read events 86 | } 87 | 88 | @Override 89 | public boolean needsWrite() { 90 | return false; // never want write events 91 | } 92 | 93 | @Override 94 | public boolean needsAccept() { 95 | // TODO Auto-generated method stub 96 | return false; 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/org/flowvisor/events/FVEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.events; 5 | 6 | /** 7 | * Basic unit of information passed between FV's logical units Derived classes 8 | * express the specific msg information 9 | * 10 | * @author capveg 11 | * 12 | */ 13 | public class FVEvent { 14 | private FVEventHandler src, dst; 15 | 16 | public FVEvent(FVEventHandler src, FVEventHandler dst) { 17 | this.src = src; 18 | this.dst = dst; 19 | } 20 | 21 | public FVEvent(FVEvent e) { 22 | this.src = e.getSrc(); 23 | this.dst = e.getDst(); 24 | } 25 | 26 | /** 27 | * Get the sending msg handler (could be null) 28 | * 29 | * @return 30 | */ 31 | public FVEventHandler getSrc() { 32 | return src; 33 | } 34 | 35 | /** 36 | * Set the sending Event handler 37 | * 38 | * @param src 39 | * could be null 40 | */ 41 | public FVEvent setSrc(FVEventHandler src) { 42 | this.src = src; 43 | return this; 44 | } 45 | 46 | /** 47 | * Get the destination of this message 48 | * 49 | * @return dst dst reference 50 | */ 51 | public FVEventHandler getDst() { 52 | return dst; 53 | } 54 | 55 | /** 56 | * Set the destination Event handler 57 | * 58 | * @param dst 59 | */ 60 | public FVEvent setDst(FVEventHandler dst) { 61 | this.dst = dst; 62 | return this; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/org/flowvisor/events/FVEventHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.events; 5 | 6 | import org.flowvisor.exceptions.*; 7 | 8 | /** 9 | * Basic processing module for message passing in FV 10 | * 11 | * @author capveg 12 | * 13 | */ 14 | public interface FVEventHandler { 15 | 16 | /** 17 | * Pass a message to this Handler. If the dst is in the same thread context 18 | * as the caller, the message is processed immediately (blocking) Else, the 19 | * message is queued and processed later (non-blocking) If sender is null, 20 | * the message is always queued 21 | * 22 | * @param e 23 | * A FVEvent 24 | */ 25 | public void handleEvent(FVEvent e) throws UnhandledEvent; 26 | 27 | /** 28 | * Returns an integer that identifies the threading context that this 29 | * handler runs in 30 | * 31 | * @return A long that identifies this thread 32 | */ 33 | public long getThreadContext(); 34 | 35 | /** 36 | * Return a human readable string (no spaces) that describes this handler 37 | * 38 | * @return String 39 | */ 40 | public String getName(); 41 | 42 | /** 43 | * Tell the Handler to stop what it's doing and clean up all of its state 44 | */ 45 | public void tearDown(); 46 | 47 | /** 48 | * Return true if this Event handler wants read events 49 | * 50 | * @return 51 | */ 52 | public boolean needsRead(); 53 | 54 | /** 55 | * Return true if this Event handler wants connect events 56 | * 57 | * @return 58 | */ 59 | public boolean needsConnect(); 60 | 61 | /** 62 | * Return true if this Event handler wants write events 63 | * 64 | * @return 65 | */ 66 | public boolean needsWrite(); 67 | 68 | /** 69 | * Return true if this Event handler wants accept events 70 | * 71 | * @return 72 | */ 73 | public boolean needsAccept(); 74 | } 75 | -------------------------------------------------------------------------------- /src/org/flowvisor/events/FVEventUtils.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.events; 2 | 3 | import org.flowvisor.config.FVConfig; 4 | import org.flowvisor.log.FVLog; 5 | import org.flowvisor.log.LogLevel; 6 | 7 | public class FVEventUtils { 8 | 9 | static long eventCount = 0; 10 | static long total = 0; 11 | public static long averageDelay = 0; 12 | public static long instDelay = 0; 13 | 14 | 15 | /** 16 | * Test to see if more than FVConfig.DelayWarning ms have passed, and if so, 17 | * issue a warning log msg 18 | * 19 | * @param startCounter 20 | * @param handler 21 | * @param e 22 | */ 23 | static public void starvationTest(long startCounter, 24 | FVEventHandler handler, FVEvent e) { 25 | long delay = System.currentTimeMillis() - startCounter; 26 | FVEventUtils.processDelay(delay); 27 | if (delay > FVConfig.DelayWarning) { 28 | FVLog.log(LogLevel.ALERT, e.getDst(), 29 | "STARVING: handling event took " 30 | + delay + "ms: " + e); 31 | } 32 | } 33 | 34 | /* 35 | * Lazy-ly hoping that the counter won't wrap... 36 | * ha! 37 | */ 38 | static void processDelay(long delay) { 39 | eventCount++; 40 | total += delay; 41 | averageDelay = total/eventCount; 42 | instDelay = delay; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/org/flowvisor/events/FVIOEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.events; 5 | 6 | import org.flowvisor.events.FVEvent; 7 | import java.nio.channels.*; 8 | 9 | /** 10 | * Event: underlying socket has pending I/O 11 | * 12 | * @author capveg 13 | * 14 | */ 15 | public class FVIOEvent extends FVEvent { 16 | SelectionKey sk; 17 | 18 | public FVIOEvent(SelectionKey sk, FVEventHandler src, FVEventHandler dst) { 19 | super(src, dst); 20 | this.sk = sk; 21 | } 22 | 23 | public SelectionKey getSelectionKey() { 24 | return sk; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/org/flowvisor/events/FVRequestTimeoutEvent.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.events; 2 | 3 | public class FVRequestTimeoutEvent extends FVTimerEvent { 4 | 5 | public static final long WAIT_TIME = 5000; 6 | 7 | public FVRequestTimeoutEvent(FVEventHandler handler) { 8 | super(0, handler, handler, null); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/org/flowvisor/events/FVStatsTimer.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.events; 2 | 3 | public class FVStatsTimer extends FVTimerEvent { 4 | 5 | public static final long WAIT_TIME = 30000; 6 | 7 | public FVStatsTimer(FVEventHandler handler) { 8 | super(0, handler, handler, null); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/org/flowvisor/events/OFKeepAlive.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.events; 5 | 6 | import org.flowvisor.classifier.FVSendMsg; 7 | import org.flowvisor.message.FVMessageFactory; 8 | import org.openflow.protocol.OFEchoRequest; 9 | import org.openflow.protocol.OFType; 10 | 11 | /** 12 | * @author capveg 13 | * 14 | */ 15 | public class OFKeepAlive extends FVTimerEvent { 16 | long lastPongTime; 17 | long timeout; 18 | long pingPeriod; 19 | int xid; 20 | private final FVMessageFactory offactory; 21 | FVEventLoop loop; 22 | private final FVSendMsg sendMsg; 23 | 24 | public OFKeepAlive(FVEventHandler handler, FVSendMsg sendMsg, 25 | FVEventLoop loop) { 26 | super(0, handler, handler, null); 27 | this.loop = loop; 28 | this.sendMsg = sendMsg; 29 | this.pingPeriod = 5000; // 5 seconds 30 | this.timeout = 10100; // ~10 seconds == 2 ping periods + a little 31 | this.lastPongTime = System.currentTimeMillis(); 32 | this.xid = 100; 33 | this.offactory = new FVMessageFactory(); 34 | } 35 | 36 | /** 37 | * @return the timeout 38 | */ 39 | public long getTimeout() { 40 | return timeout; 41 | } 42 | 43 | /** 44 | * @param timeout 45 | * the timeout to set 46 | */ 47 | public void setTimeout(long timeout) { 48 | this.timeout = timeout; 49 | } 50 | 51 | /** 52 | * @return the pingPeriod 53 | */ 54 | public long getPingPeriod() { 55 | return pingPeriod; 56 | } 57 | 58 | /** 59 | * @param pingPeriod 60 | * the pingPeriod to set 61 | */ 62 | public void setPingPeriod(long pingPeriod) { 63 | this.pingPeriod = pingPeriod; 64 | } 65 | 66 | public void sendPing() { 67 | OFEchoRequest ping = (OFEchoRequest) offactory 68 | .getMessage(OFType.ECHO_REQUEST); 69 | ping.setXid(xid++); 70 | ping.computeLength(); 71 | this.sendMsg.sendMsg(ping, this.sendMsg); 72 | } 73 | 74 | public void registerPong() { 75 | lastPongTime = System.currentTimeMillis(); 76 | } 77 | 78 | /** 79 | * Have we gotten a pong in the timeout period? 80 | * 81 | * @return 82 | */ 83 | public boolean isAlive() { 84 | return ((this.lastPongTime + this.timeout) > System.currentTimeMillis()); 85 | } 86 | 87 | public void scheduleNextCheck() { 88 | this.setExpireTime(System.currentTimeMillis() + this.pingPeriod); 89 | loop.addTimer(this); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/org/flowvisor/events/TearDownEvent.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.events; 2 | 3 | /** 4 | * Signal that the event handler should be torn down 5 | * 6 | * @author capveg 7 | * 8 | */ 9 | 10 | public class TearDownEvent extends FVEvent { 11 | 12 | public TearDownEvent(FVEventHandler src, FVEventHandler dst) { 13 | super(src, dst); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/ActionDisallowedException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.exceptions; 5 | 6 | 7 | import org.openflow.protocol.OFError.OFBadActionCode; 8 | 9 | /** 10 | * Signal that an action in an actions list was not allowed 11 | * 12 | * @author capveg 13 | * 14 | */ 15 | public class ActionDisallowedException extends FVException { 16 | 17 | private OFBadActionCode error = null; 18 | 19 | public ActionDisallowedException(String string, OFBadActionCode err) { 20 | super(string); 21 | error = err; 22 | } 23 | 24 | public OFBadActionCode getError() { 25 | return error; 26 | } 27 | 28 | /** 29 | * 30 | */ 31 | private static final long serialVersionUID = 1L; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/BufferFull.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | import java.io.IOException; 4 | 5 | public class BufferFull extends IOException { 6 | 7 | public BufferFull(String string) { 8 | super(string); 9 | } 10 | 11 | /** 12 | * 13 | */ 14 | private static final long serialVersionUID = 1L; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/DPIDNotFound.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.exceptions; 5 | 6 | /** 7 | * @author capveg 8 | * 9 | */ 10 | public class DPIDNotFound extends FVException { 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = 1L; 16 | 17 | public DPIDNotFound(String arg0) { 18 | super("dpid does not exist or has not yet connected: " + arg0); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/DuplicateControllerException.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | import org.flowvisor.exceptions.FVException; 4 | 5 | public class DuplicateControllerException extends FVException { 6 | 7 | private static final long serialVersionUID = 1L; 8 | 9 | public DuplicateControllerException(String controllerHostname, int controllerPort, String sliceName, String changeType) { 10 | super("A slice with this controller: " + controllerHostname + ":" + controllerPort + 11 | " already exists, this slice (" + sliceName + ") will not be " + changeType); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/FVException.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class FVException extends Exception { 4 | /** 5 | * 6 | */ 7 | private static final long serialVersionUID = -4548551349904898191L; 8 | 9 | public FVException(String err) { 10 | super(err); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/FlowEntryNotFound.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class FlowEntryNotFound extends FVException { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 1L; 9 | 10 | public FlowEntryNotFound(int id) { 11 | super(String.valueOf(id)); 12 | } 13 | 14 | public FlowEntryNotFound(String name) { 15 | super(name); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/InvalidUserInfoKey.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class InvalidUserInfoKey extends Exception { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 1L; 9 | 10 | public InvalidUserInfoKey(String s) { 11 | super(s); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/MalformedControllerURL.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class MalformedControllerURL extends FVException { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 1L; 9 | 10 | public MalformedControllerURL(String err) { 11 | super(err); 12 | // TODO Auto-generated constructor stub 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/MalformedFlowChange.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class MalformedFlowChange extends FVException { 4 | 5 | public MalformedFlowChange(String err) { 6 | super(err); 7 | // TODO Auto-generated constructor stub 8 | } 9 | 10 | /** 11 | * 12 | */ 13 | private static final long serialVersionUID = 1L; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/MalformedOFMessage.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class MalformedOFMessage extends Exception { 4 | 5 | public MalformedOFMessage(String string) { 6 | super(string); 7 | } 8 | 9 | /** 10 | * 11 | */ 12 | private static final long serialVersionUID = 1L; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/MapUnparsable.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class MapUnparsable extends FVException { 4 | 5 | public MapUnparsable(String err) { 6 | super(err); 7 | } 8 | 9 | /** 10 | * 11 | */ 12 | private static final long serialVersionUID = 1L; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/MissingRequiredField.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.exceptions; 5 | 6 | /** 7 | * @author alshabib 8 | * 9 | */ 10 | public class MissingRequiredField extends FVException { 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = 1L; 16 | 17 | public MissingRequiredField(String fieldName) { 18 | super(fieldName + " is required "); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/NoMatch.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.exceptions; 5 | 6 | /** 7 | * @author capveg 8 | * 9 | */ 10 | public class NoMatch extends FVException { 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = 1L; 16 | 17 | public NoMatch(String str) { 18 | super(str); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/NoParamException.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class NoParamException extends Exception { 4 | /** 5 | * 6 | */ 7 | private static final long serialVersionUID = 1L; 8 | 9 | public NoParamException(String err) { 10 | super(err); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/PermissionDeniedException.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class PermissionDeniedException extends FVException { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 1L; 9 | 10 | public PermissionDeniedException(String err) { 11 | super(err); 12 | // TODO Auto-generated constructor stub 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/RPCException.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class RPCException extends Exception { 4 | 5 | 6 | private static final long serialVersionUID = 1L; 7 | 8 | public static final int PARSE_ERROR = -3; 9 | public static final int METHOD_NOT_FOUND = -4; 10 | public static final int INTERNAL_ERROR = -5; 11 | 12 | private long errorCode; 13 | 14 | private String message; 15 | 16 | private Exception exception; 17 | 18 | private String data; 19 | 20 | public RPCException(long code, String msg, Exception e){ 21 | this.errorCode = code; 22 | this.message = msg; 23 | this.exception = e; 24 | } 25 | 26 | public long getErrorCode() { 27 | return errorCode; 28 | } 29 | 30 | public String getMessage() { 31 | return message; 32 | } 33 | 34 | public Exception getException() { 35 | return exception; 36 | } 37 | 38 | public String getData() { 39 | return data; 40 | } 41 | 42 | public void setData(String data){ 43 | this.data = data; 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/SliceNameDisallowedException.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class SliceNameDisallowedException extends Exception { 4 | public SliceNameDisallowedException(String err) { 5 | super(err); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/SliceNotFound.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class SliceNotFound extends FVException { 4 | 5 | /** 6 | * 7 | */ 8 | private static final long serialVersionUID = 1L; 9 | 10 | public SliceNotFound(String err) { 11 | super(err); 12 | // TODO Auto-generated constructor stub 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/StatDisallowedException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.exceptions; 5 | 6 | 7 | import org.openflow.protocol.OFError.OFBadRequestCode; 8 | 9 | /** 10 | * Signal that an action in an actions list was not allowed 11 | * 12 | * @author ash 13 | * 14 | */ 15 | public class StatDisallowedException extends FVException { 16 | 17 | private OFBadRequestCode error = null; 18 | 19 | public StatDisallowedException(String string, OFBadRequestCode err) { 20 | super(string); 21 | error = err; 22 | } 23 | 24 | public OFBadRequestCode getError() { 25 | return error; 26 | } 27 | 28 | /** 29 | * 30 | */ 31 | private static final long serialVersionUID = 1L; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/UnhandledEvent.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | import org.flowvisor.events.FVEvent; 4 | 5 | public class UnhandledEvent extends FVException { 6 | 7 | /** 8 | * 9 | */ 10 | private static final long serialVersionUID = 9059842200519560846L; 11 | 12 | public UnhandledEvent(String err) { 13 | super(err); 14 | // TODO Auto-generated constructor stub 15 | } 16 | 17 | public UnhandledEvent(FVEvent e) { 18 | super("Unhandled event: " + e.toString()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/UnknownFieldType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.exceptions; 5 | 6 | /** 7 | * @author alshabib 8 | * 9 | */ 10 | public class UnknownFieldType extends FVException { 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = 1L; 16 | 17 | public UnknownFieldType(String fieldName, String type) { 18 | super(fieldName + " is not of type " + type); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/org/flowvisor/exceptions/UnknownMatchField.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.exceptions; 2 | 3 | public class UnknownMatchField extends Exception { 4 | /** 5 | * 6 | */ 7 | private static final long serialVersionUID = 1L; 8 | 9 | public UnknownMatchField(String str) { 10 | super(str); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/org/flowvisor/flows/FlowDB.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.flows; 5 | 6 | import java.util.Iterator; 7 | 8 | import org.openflow.protocol.OFFlowMod; 9 | import org.openflow.protocol.OFFlowRemoved; 10 | 11 | /** 12 | * An FV-local copy of the flow table state on the switch 13 | * 14 | * track flow_mods and flow_expire messages 15 | * 16 | * @author capveg 17 | * 18 | */ 19 | public interface FlowDB extends Iterable { 20 | /** 21 | * Update the contents of the FlowDB with 22 | * 23 | * @param flowMod 24 | * @param Slicename 25 | */ 26 | public void processFlowMod(OFFlowMod flowMod, long dpid, String sliceName); 27 | 28 | /** 29 | * Update the database with a flow_removed message 30 | * 31 | * @param flowRemoved 32 | * the new information 33 | * @param dpid 34 | * the switch it came from 35 | * @return the name of the slice that inserted the flow or null if none 36 | */ 37 | public String processFlowRemoved(OFFlowRemoved flowRemoved, long dpid); 38 | 39 | public Iterator iterator(); 40 | 41 | public int size(); 42 | } 43 | -------------------------------------------------------------------------------- /src/org/flowvisor/flows/FlowIntersect.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.flows; 5 | 6 | import org.flowvisor.openflow.protocol.FVMatch; 7 | 8 | 9 | /** 10 | * Describe the intersection between two FlowEntry's. 11 | * 12 | * Contains an MatchType and if MatchType != NONE, then a FlowEntry structure 13 | * that describes the overlap 14 | * 15 | * @author capveg 16 | * 17 | */ 18 | public class FlowIntersect implements Comparable { 19 | MatchType matchType; 20 | FlowEntry flowEntry; 21 | public boolean maybeSubset; 22 | public boolean maybeSuperset; 23 | 24 | public FlowIntersect(FlowEntry flowEntry) { 25 | this.matchType = MatchType.UNKNOWN; 26 | this.flowEntry = flowEntry; 27 | this.maybeSubset = true; 28 | this.maybeSuperset = true; 29 | } 30 | 31 | public MatchType getMatchType() { 32 | return this.matchType; 33 | } 34 | 35 | public FlowIntersect setMatchType(MatchType matchType) { 36 | this.matchType = matchType; 37 | return this; 38 | } 39 | 40 | public FlowEntry getFlowEntry() { 41 | return flowEntry; 42 | } 43 | 44 | public void setFlowEntry(FlowEntry flowEntry) { 45 | this.flowEntry = flowEntry; 46 | } 47 | 48 | public FVMatch getMatch() { 49 | return this.flowEntry.getRuleMatch(); 50 | } 51 | 52 | public void setMatch(FVMatch match) { 53 | this.flowEntry.setRuleMatch(match); 54 | } 55 | 56 | public long getDpid() { 57 | return this.flowEntry.getDpid(); 58 | } 59 | 60 | public void setDpid(long dpid) { 61 | this.flowEntry.setDpid(dpid); 62 | } 63 | 64 | /* 65 | * (non-Javadoc) 66 | * 67 | * @see java.lang.Object#toString() 68 | */ 69 | @Override 70 | public String toString() { 71 | return "FlowIntersect[matchType=" + matchType + ",flowEntry=" 72 | + flowEntry + "]"; 73 | } 74 | 75 | @Override 76 | public int compareTo(FlowIntersect o) { 77 | return this.flowEntry.compareTo(o.flowEntry); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/org/flowvisor/flows/FlowRewriteDB.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.flows; 2 | 3 | /** 4 | * Very similar to FlowDB, but instead of containing a list of 5 | * flows in the switch, it contains the map of how flows were 6 | * rewritten by the flowvisor, i.e., 7 | * 8 | * alice sends flow f which the flowvisor rewrites as f1..fn 9 | * so FlowRewriteDB stores the "f --> f1..fn" mapping 10 | */ 11 | 12 | import java.io.Serializable; 13 | import java.util.Set; 14 | 15 | import org.openflow.protocol.OFFlowMod; 16 | import org.openflow.protocol.OFFlowRemoved; 17 | 18 | public interface FlowRewriteDB extends Serializable { 19 | /** 20 | * Update the contents of the FlowDB with 21 | * 22 | * @param flowMod 23 | * @param Slicename 24 | */ 25 | 26 | public void processFlowMods(OFFlowMod original, OFFlowMod rewrite); 27 | 28 | public void processFlowRemoved(OFFlowRemoved flowRemoved); 29 | 30 | public Set originals(); 31 | 32 | public FlowDB getRewrites(FlowDBEntry original); 33 | 34 | public int size(); 35 | } 36 | -------------------------------------------------------------------------------- /src/org/flowvisor/flows/MatchType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.flows; 5 | 6 | /** 7 | * @author capveg Describe the overlap between matches A and B 8 | */ 9 | public enum MatchType { 10 | UNKNOWN, // not yet calculated 11 | NONE, // no overlap between A and B 12 | SUBSET, // match A is a subset of B 13 | SUPERSET, // match A is a superset of match B 14 | INTERSECT, // match A and B overlap, but neither subsumes the other 15 | EQUAL; // match A and B are exactly the same 16 | } 17 | -------------------------------------------------------------------------------- /src/org/flowvisor/flows/NoopFlowDB.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.flows; 5 | 6 | import java.util.Iterator; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | 10 | import org.openflow.protocol.OFFlowMod; 11 | import org.openflow.protocol.OFFlowRemoved; 12 | 13 | /** 14 | * implement the FlowDB interface, but do nothing used when FlowTracking is 15 | * disabled because it's easier and cleaner than having a lot of if/then's in 16 | * the code 17 | * 18 | * @author capveg 19 | * 20 | */ 21 | public class NoopFlowDB implements FlowDB { 22 | 23 | List emptyList; 24 | 25 | public NoopFlowDB() { 26 | this.emptyList = new LinkedList(); 27 | } 28 | 29 | @Override 30 | public void processFlowMod(OFFlowMod flowMod, long dpid, String sliceName) { 31 | // do nothing 32 | } 33 | 34 | @Override 35 | public String processFlowRemoved(OFFlowRemoved flowRemoved, long dpid) { 36 | // do nothing 37 | return null; 38 | } 39 | 40 | @Override 41 | public Iterator iterator() { 42 | return emptyList.iterator(); 43 | } 44 | 45 | @Override 46 | public int size() { 47 | return 0; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/org/flowvisor/flows/NoopFlowRewriteDB.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.flows; 5 | 6 | import java.util.Set; 7 | import java.util.TreeSet; 8 | 9 | import org.flowvisor.events.FVEventHandler; 10 | import org.openflow.protocol.OFFlowMod; 11 | import org.openflow.protocol.OFFlowRemoved; 12 | 13 | /** 14 | * This is a stub class that's loaded when flow tracking is disabled 15 | * 16 | * @author capveg 17 | * 18 | */ 19 | public class NoopFlowRewriteDB implements FlowRewriteDB { 20 | 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = 1L; 25 | 26 | FVEventHandler fvEventHandler; 27 | Set set; 28 | 29 | public NoopFlowRewriteDB(FVEventHandler fvEventHandler, String sliceName, 30 | long dpid) { 31 | this.fvEventHandler = fvEventHandler; 32 | this.set = new TreeSet(); 33 | } 34 | 35 | /* 36 | * (non-Javadoc) 37 | * 38 | * @see 39 | * org.flowvisor.flows.FlowRewriteDB#processFlowMods(org.flowvisor.message 40 | * .FVFlowMod, org.flowvisor.message.FVFlowMod) 41 | */ 42 | @Override 43 | public void processFlowMods(OFFlowMod original, OFFlowMod rewrite) { 44 | // do nothing 45 | } 46 | 47 | /* 48 | * (non-Javadoc) 49 | * 50 | * @see 51 | * org.flowvisor.flows.FlowRewriteDB#processFlowRemoved(org.flowvisor.message 52 | * .FVFlowRemoved) 53 | */ 54 | @Override 55 | public void processFlowRemoved(OFFlowRemoved flowRemoved) { 56 | // do nothing 57 | } 58 | 59 | /* 60 | * (non-Javadoc) 61 | * 62 | * @see org.flowvisor.flows.FlowRewriteDB#originals() 63 | */ 64 | @Override 65 | public Set originals() { 66 | return this.set; // return set with zero entries 67 | } 68 | 69 | /* 70 | * (non-Javadoc) Always returns null 71 | * 72 | * @see 73 | * org.flowvisor.flows.FlowRewriteDB#getRewrites(org.flowvisor.flows.FlowDBEntry 74 | * ) 75 | */ 76 | @Override 77 | public FlowDB getRewrites(FlowDBEntry original) { 78 | return null; 79 | } 80 | 81 | /* 82 | * (non-Javadoc) 83 | * 84 | * @see org.flowvisor.flows.FlowRewriteDB#size() 85 | */ 86 | @Override 87 | public int size() { 88 | return 0; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/org/flowvisor/log/DevNullLogger.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.log; 2 | 3 | import org.flowvisor.events.FVEventHandler; 4 | 5 | public class DevNullLogger implements FVLogInterface { 6 | 7 | @Override 8 | public boolean init() { 9 | return false; 10 | } 11 | 12 | @Override 13 | public void log(LogLevel level, long time, FVEventHandler source, String msg) { 14 | // NOOP 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/org/flowvisor/log/FVLogInterface.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.log; 5 | 6 | import org.flowvisor.events.FVEventHandler; 7 | 8 | /** 9 | * Generic interface for logging in FV 10 | * 11 | * @author capveg 12 | * 13 | */ 14 | public interface FVLogInterface { 15 | 16 | /** 17 | * Do any sort of logging method initializations 18 | * 19 | * @return did we change the config? 20 | */ 21 | public boolean init(); 22 | 23 | /** 24 | * Log a message 25 | * 26 | * @param level 27 | * Priority of message 28 | * @param source 29 | * Source of message; might be null 30 | * @param msg 31 | * Actual message 32 | */ 33 | public void log(LogLevel level, long time, FVEventHandler source, String msg); 34 | } 35 | -------------------------------------------------------------------------------- /src/org/flowvisor/log/JettyLog.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.log; 2 | 3 | import org.eclipse.jetty.util.log.Logger; 4 | 5 | 6 | public class JettyLog implements Logger{ 7 | 8 | @Override 9 | public void debug(String arg0) { 10 | FVLog.log(LogLevel.DEBUG,null, arg0); 11 | } 12 | 13 | @Override 14 | public void debug(String arg0, Throwable arg1) { 15 | FVLog.log(LogLevel.DEBUG,null, arg0, arg1); 16 | } 17 | 18 | @Override 19 | public void debug(String arg0, Object arg1, Object arg2) { 20 | FVLog.log(LogLevel.DEBUG,null, arg0, arg1, arg2); 21 | } 22 | 23 | 24 | @Override 25 | public String getName() { 26 | return FVLog.logger.getClass().getName(); 27 | } 28 | 29 | @Override 30 | public void info(String arg0) { 31 | FVLog.log(LogLevel.INFO, null, arg0); 32 | 33 | } 34 | 35 | @Override 36 | public void info(String arg0, Object arg1, Object arg2) { 37 | FVLog.log(LogLevel.INFO, null, arg0, arg1, arg2); 38 | } 39 | 40 | @Override 41 | public boolean isDebugEnabled() { 42 | return FVLog.getThreshold() == LogLevel.DEBUG; 43 | } 44 | 45 | @Override 46 | public void setDebugEnabled(boolean arg0) { 47 | FVLog.setThreshold(LogLevel.DEBUG); 48 | } 49 | 50 | @Override 51 | public void warn(String arg0) { 52 | FVLog.log(LogLevel.WARN, null, arg0); 53 | 54 | } 55 | 56 | @Override 57 | public void warn(String arg0, Throwable arg1) { 58 | FVLog.log(LogLevel.WARN, null, arg0, arg1); 59 | } 60 | 61 | @Override 62 | public void warn(String arg0, Object arg1, Object arg2) { 63 | FVLog.log(LogLevel.WARN, null, arg0, arg1, arg2); 64 | } 65 | 66 | @Override 67 | public Logger getLogger(String arg0) { 68 | return this; 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/org/flowvisor/log/LogLevel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.log; 5 | 6 | import org.apache.log4j.Level; 7 | 8 | /** 9 | * Logging Priority Levels (very similar to syslog) Sorted in descending order 10 | * of importance. 11 | * 12 | * @author capveg 13 | * 14 | */ 15 | public enum LogLevel { 16 | FATAL(Level.FATAL), // The world is on fire 17 | CRIT(Level.ERROR), // Will always want to know 18 | ALERT(Level.ERROR), // Will typically want to know 19 | WARN(Level.WARN), // Might want to know cuz it's possibly 20 | // bad 21 | INFO(Level.INFO), // Maybe worth knowing, maybe not -- not bad 22 | NOTE(Level.INFO), 23 | 24 | DEBUG(Level.DEBUG), /* Debug */ 25 | MOBUG(Level.TRACE); // more debugging; rarely worth knowing 26 | 27 | @Override 28 | public String toString() { 29 | return this.name(); 30 | } 31 | 32 | Level priority; 33 | 34 | LogLevel(Level priority) { 35 | this.priority = priority; 36 | } 37 | 38 | LogLevel() { 39 | this.priority = null; 40 | } 41 | 42 | public Level getPriority() { 43 | return this.priority; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/org/flowvisor/log/SendRecvDropStats.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.log; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.flowvisor.classifier.FVSendMsg; 7 | import org.openflow.protocol.OFMessage; 8 | 9 | public class SendRecvDropStats { 10 | 11 | public static final String NO_STATS_AVAILABLE_MSG = "No stats exist for this slice"; 12 | 13 | public enum FVStatsType { 14 | SEND, RECV, DROP 15 | } 16 | 17 | Map stats; 18 | 19 | public SendRecvDropStats() { 20 | this(new FVStatsGroup(), new FVStatsGroup(), new FVStatsGroup()); 21 | } 22 | 23 | public SendRecvDropStats(FVStatsGroup send, FVStatsGroup recv, 24 | FVStatsGroup drop) { 25 | this.stats = new HashMap(); 26 | this.stats.put(FVStatsType.SEND, send); 27 | this.stats.put(FVStatsType.RECV, recv); 28 | this.stats.put(FVStatsType.DROP, drop); 29 | } 30 | 31 | public String combinedString() { 32 | StringBuffer ret = new StringBuffer(); 33 | ret.append("---Sent---\n"); 34 | ret.append(this.stats.get(FVStatsType.SEND).toString()); 35 | ret.append("---Recv---\n"); 36 | ret.append(this.stats.get(FVStatsType.RECV).toString()); 37 | ret.append("---Drop---\n"); 38 | ret.append(this.stats.get(FVStatsType.DROP).toString()); 39 | return ret.toString(); 40 | } 41 | 42 | public HashMap toMap() { 43 | HashMap ret = new HashMap(); 44 | ret.put("tx", this.stats.get(FVStatsType.SEND).toMap()); 45 | ret.put("rx", this.stats.get(FVStatsType.RECV).toMap()); 46 | ret.put("drop", this.stats.get(FVStatsType.DROP).toMap()); 47 | return ret; 48 | } 49 | 50 | public void increment(FVStatsType stat, FVSendMsg from, OFMessage ofm) { 51 | this.stats.get(stat).increment(from, ofm); 52 | } 53 | 54 | public long get(FVStatsType stat, FVSendMsg from, OFMessage ofm) { 55 | return this.stats.get(stat).get(from, ofm); 56 | } 57 | 58 | public FVStats getTotal(FVStatsType stat) { 59 | return this.stats.get(stat).total; 60 | } 61 | 62 | public long getTotal(FVStatsType stat, OFMessage ofm) { 63 | return this.stats.get(stat).getTotal(ofm); 64 | } 65 | 66 | public static SendRecvDropStats createSharedStats(String owner) { 67 | return new SendRecvDropStats(FVStatsGroup.createSharedStats(owner 68 | + FVStatsType.SEND), FVStatsGroup.createSharedStats(owner 69 | + FVStatsType.RECV), FVStatsGroup.createSharedStats(owner 70 | + FVStatsType.DROP)); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/org/flowvisor/log/StderrLogger.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.log; 5 | 6 | import java.text.DateFormat; 7 | import java.text.SimpleDateFormat; 8 | 9 | import org.flowvisor.events.FVEventHandler; 10 | 11 | /** 12 | * @author capveg 13 | * 14 | */ 15 | public class StderrLogger implements FVLogInterface { 16 | 17 | DateFormat df; 18 | 19 | /* 20 | * (non-Javadoc) 21 | * 22 | * @see org.flowvisor.log.FVLogInterface#init() 23 | */ 24 | @Override 25 | public boolean init() { 26 | // this.df = 27 | // DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT); 28 | this.df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); 29 | return false; 30 | } 31 | 32 | /* 33 | * (non-Javadoc) 34 | * 35 | * @see org.flowvisor.log.FVLogInterface#log(org.flowvisor.log.FVLogLevel, 36 | * org.flowvisor.events.FVEventHandler, java.lang.String) 37 | */ 38 | @Override 39 | public void log(LogLevel level, long time, FVEventHandler source, String msg) { 40 | String srcString = null; 41 | if (source != null) 42 | srcString = source.getName(); 43 | else 44 | srcString = "none"; 45 | System.err.println(String.format("%5s", level.toString()) + ":" 46 | + df.format(time) + ":" + srcString + ":: " + msg); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/org/flowvisor/log/ThreadLogger.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.log; 2 | 3 | import java.lang.Thread.UncaughtExceptionHandler; 4 | 5 | public class ThreadLogger implements UncaughtExceptionHandler { 6 | 7 | @Override 8 | public void uncaughtException(Thread thread, Throwable exception) { 9 | 10 | FVLog.log(LogLevel.CRIT, null, "----- exception in thread " 11 | + thread.toString() + "::" + exception.toString()); 12 | StackTraceElement[] stackTrace = exception.getStackTrace(); 13 | for (int i = 0; i < stackTrace.length; i++) 14 | FVLog.log(LogLevel.CRIT, null, stackTrace[i].toString()); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/Classifiable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | 8 | /** 9 | * The interface for classifying this message and sending it on to the correct 10 | * FVSlicer instance 11 | * 12 | * Does switch-specific, slice agnostic rewriting 13 | * 14 | * @author capveg 15 | * 16 | */ 17 | public interface Classifiable { 18 | 19 | /** 20 | * Given a message from a switch, send it to the appropriate FVSlicer 21 | * instance(s) 22 | * 23 | * Possibly do some rewriting, record state, or even drop 24 | * 25 | * @param fvClassifier 26 | * Switch state 27 | */ 28 | public void classifyFromSwitch(FVClassifier fvClassifier); 29 | } 30 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVBarrierReply.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.slicer.FVSlicer; 8 | 9 | /** 10 | * @author capveg 11 | * 12 | */ 13 | public class FVBarrierReply extends org.openflow.protocol.OFBarrierReply 14 | implements Classifiable, Slicable { 15 | 16 | /* 17 | * (non-Javadoc) 18 | * 19 | * @seeorg.flowvisor.message.Classifiable#classifyFromSwitch(org.flowvisor. 20 | * classifier.FVClassifier) 21 | */ 22 | @Override 23 | public void classifyFromSwitch(FVClassifier fvClassifier) { 24 | FVMessageUtil.untranslateXidAndSend(this, fvClassifier); 25 | } 26 | 27 | /* 28 | * (non-Javadoc) 29 | * 30 | * @see 31 | * org.flowvisor.message.Slicable#sliceFromController(org.flowvisor.classifier 32 | * .FVClassifier, org.flowvisor.slicer.FVSlicer) 33 | */ 34 | @Override 35 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 36 | FVMessageUtil.dropUnexpectedMesg(this, fvSlicer); 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVBarrierRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.slicer.FVSlicer; 8 | 9 | 10 | /** 11 | * @author capveg 12 | * 13 | */ 14 | public class FVBarrierRequest extends org.openflow.protocol.OFBarrierRequest 15 | implements Slicable, Classifiable { 16 | 17 | /* 18 | * (non-Javadoc) 19 | * 20 | * @see 21 | * org.flowvisor.message.Slicable#sliceFromController(org.flowvisor.classifier 22 | * .FVClassifier, org.flowvisor.slicer.FVSlicer) 23 | */ 24 | @Override 25 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 26 | FVMessageUtil.translateXidAndSend(this, fvClassifier, fvSlicer); 27 | } 28 | 29 | /* 30 | * (non-Javadoc) 31 | * 32 | * @seeorg.flowvisor.message.Classifiable#classifyFromSwitch(org.flowvisor. 33 | * classifier.FVClassifier) 34 | */ 35 | @Override 36 | public void classifyFromSwitch(FVClassifier fvClassifier) { 37 | FVMessageUtil.dropUnexpectedMesg(this, fvClassifier); 38 | } 39 | 40 | 41 | @Override 42 | public String toString() { 43 | return "FVBarrierRequest []"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVEchoReply.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.slicer.FVSlicer; 5 | 6 | public class FVEchoReply extends org.openflow.protocol.OFEchoReply implements 7 | Slicable, Classifiable { 8 | 9 | @Override 10 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 11 | fvSlicer.registerPong(); 12 | } 13 | 14 | @Override 15 | public void classifyFromSwitch(FVClassifier fvClassifier) { 16 | fvClassifier.registerPong(); 17 | } 18 | 19 | 20 | @Override 21 | public String toString() { 22 | return "FVEchoReply [ payload=" + this.getPayload() + "]"; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVEchoRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.ofswitch.TopologyConnection; 8 | import org.flowvisor.slicer.FVSlicer; 9 | 10 | 11 | /** 12 | * Given an echo request, just send an immediate response from the fv 13 | * 14 | * FIXME consider sending these all the way through instead of faking NEED to 15 | * update regression tests 16 | * 17 | * @author capveg 18 | * 19 | */ 20 | public class FVEchoRequest extends org.openflow.protocol.OFEchoRequest 21 | implements Classifiable, Slicable, TopologyControllable { 22 | 23 | /* 24 | * (non-Javadoc) 25 | * 26 | * @seeorg.flowvisor.message.Classifiable#classifyFromSwitch(org.flowvisor. 27 | * classifier.FVClassifier) 28 | */ 29 | @Override 30 | public void classifyFromSwitch(FVClassifier fvClassifier) { 31 | FVEchoReply reply = new FVEchoReply(); 32 | reply.setXid(this.getXid()); 33 | fvClassifier.sendMsg(reply, fvClassifier); 34 | } 35 | 36 | /* 37 | * (non-Javadoc) 38 | * 39 | * @see 40 | * org.flowvisor.message.Slicable#sliceFromController(org.flowvisor.classifier 41 | * .FVClassifier, org.flowvisor.slicer.FVSlicer) 42 | */ 43 | @Override 44 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 45 | fvSlicer.sendMsg(makeReply(), fvSlicer); 46 | } 47 | 48 | @Override 49 | public void topologyController(TopologyConnection topologyConnection) { 50 | topologyConnection.sendMsg(makeReply(), topologyConnection); 51 | } 52 | 53 | FVEchoReply makeReply() { 54 | FVEchoReply reply = new FVEchoReply(); 55 | reply.setLength(this.getLength()); 56 | reply.setXid(this.getXid()); 57 | reply.setPayload(this.getPayload()); 58 | return reply; 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return "FVEchoRequest [ payload=" + this.getPayload() + "]"; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVError.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.log.FVLog; 8 | import org.flowvisor.log.LogLevel; 9 | import org.flowvisor.slicer.FVSlicer; 10 | import org.openflow.protocol.OFMessage; 11 | 12 | /** 13 | * @author capveg 14 | * 15 | */ 16 | public class FVError extends org.openflow.protocol.OFError implements 17 | Classifiable, Slicable { 18 | 19 | /* 20 | * (non-Javadoc) 21 | * 22 | * @seeorg.flowvisor.message.Classifiable#classifyFromSwitch(org.flowvisor. 23 | * classifier.FVClassifier) 24 | */ 25 | @Override 26 | public void classifyFromSwitch(FVClassifier fvClassifier) { 27 | FVSlicer fvSlicer = FVMessageUtil.untranslateXid(this, fvClassifier); 28 | if (fvSlicer == null) { 29 | FVLog.log(LogLevel.WARN, fvClassifier, 30 | "dropping msg with unknown xid: " + this); 31 | return; 32 | } 33 | if (this.errorType == (short) OFErrorType.OFPET_BAD_ACTION.ordinal() 34 | || this.errorType == (short) OFErrorType.OFPET_FLOW_MOD_FAILED.ordinal()) { 35 | fvSlicer.decrementFlowRules(); 36 | } 37 | fvSlicer.sendMsg(this, fvClassifier); 38 | }; 39 | 40 | /* 41 | * (non-Javadoc) 42 | * 43 | * @see 44 | * org.flowvisor.message.Slicable#sliceFromController(org.flowvisor.classifier 45 | * .FVClassifier, org.flowvisor.slicer.FVSlicer) 46 | */ 47 | @Override 48 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 49 | FVMessageUtil.dropUnexpectedMesg(this, fvSlicer); 50 | } 51 | 52 | /* 53 | * (non-Javadoc) 54 | * 55 | * @see java.lang.Object#toString() 56 | */ 57 | @Override 58 | public String toString() { 59 | String ret = /*super.toString() + */ "c=" + this.getErrorCode() + ";t=" 60 | + getErrorType(); 61 | 62 | OFMessage offendingMsg = null; 63 | if (!isErrorIsAscii() && (offendingMsg = getOffendingMsg()) != null) 64 | ret += ";msg=" + offendingMsg.toString(); 65 | 66 | if (error != null) { 67 | if (errorIsAscii) 68 | ret += ";err=" + new String(error); 69 | else 70 | ret += ";err=[" + error.length + "]"; 71 | } else 72 | ret += ";msg=NONE(!?)"; 73 | return ret; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVFeaturesReply.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.flows.FlowSpaceUtil; 8 | import org.flowvisor.log.FVLog; 9 | import org.flowvisor.log.LogLevel; 10 | import org.flowvisor.ofswitch.TopologyConnection; 11 | import org.flowvisor.slicer.FVSlicer; 12 | import org.openflow.protocol.OFPhysicalPort; 13 | 14 | public class FVFeaturesReply extends org.openflow.protocol.OFFeaturesReply 15 | implements Classifiable, Slicable, TopologyControllable { 16 | 17 | /** 18 | * Prune the listed ports to only those that appear in the slice 19 | */ 20 | @Override 21 | public void classifyFromSwitch(FVClassifier fvClassifier) { 22 | FVSlicer fvSlicer = FVMessageUtil.untranslateXid(this, fvClassifier); 23 | if (fvSlicer == null) { 24 | FVLog.log(LogLevel.WARN, fvClassifier, 25 | " dropping msg with un-untranslatable xid: " + this); 26 | return; 27 | } 28 | this.prunePorts(fvSlicer); // remove ports that are not part of slice 29 | // TODO: rewrite DPID if this is a virtual switch 30 | fvSlicer.sendMsg(this, fvClassifier); 31 | } 32 | 33 | // rewrite the ports list to only the set of ports allowed by the slice 34 | // definition 35 | private void prunePorts(FVSlicer fvSlicer) { 36 | List newPorts = new ArrayList(); 37 | for (OFPhysicalPort phyPort : this.getPorts()) { 38 | if (fvSlicer.getPorts().contains(phyPort.getPortNumber())) 39 | newPorts.add(phyPort); 40 | } 41 | this.setPorts(newPorts); 42 | } 43 | 44 | @Override 45 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 46 | FVMessageUtil.dropUnexpectedMesg(this, fvSlicer); 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "FVFeaturesReply [ dpid=" + FlowSpaceUtil.dpidToString(this.datapathId) 52 | + ",ports=" + this.getPorts().size() + "]"; 53 | } 54 | 55 | /** 56 | * If a topologyConnection gets this message, then register it 57 | * 58 | */ 59 | @Override 60 | public void topologyController(TopologyConnection topologyConnection) { 61 | topologyConnection.setFeaturesReply(this); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVFeaturesRequest.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.slicer.FVSlicer; 5 | import org.openflow.protocol.OFFeaturesRequest; 6 | 7 | public class FVFeaturesRequest extends OFFeaturesRequest implements 8 | Classifiable, Slicable { 9 | 10 | @Override 11 | public void classifyFromSwitch(FVClassifier fvClassifier) { 12 | FVMessageUtil.dropUnexpectedMesg(this, fvClassifier); 13 | } 14 | 15 | @Override 16 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 17 | FVMessageUtil.translateXidAndSend(this, fvClassifier, fvSlicer); 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "FVFeaturesRequest []"; 23 | } 24 | 25 | 26 | } -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVGetConfigReply.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.log.FVLog; 5 | import org.flowvisor.log.LogLevel; 6 | import org.flowvisor.slicer.FVSlicer; 7 | import org.openflow.protocol.OFGetConfigReply; 8 | 9 | public class FVGetConfigReply extends OFGetConfigReply implements Classifiable, 10 | Slicable { 11 | 12 | @Override 13 | public void classifyFromSwitch(FVClassifier fvClassifier) { 14 | FVSlicer fvSlicer = FVMessageUtil.untranslateXid(this, fvClassifier); 15 | if (fvSlicer == null) { 16 | FVLog.log(LogLevel.WARN, fvClassifier, 17 | "dropping unclassifiable xid in GetConfigReply: " + this); 18 | return; 19 | } 20 | this.setMissSendLength(fvSlicer.getMissSendLength()); 21 | fvSlicer.sendMsg(this, fvClassifier); 22 | } 23 | 24 | @Override 25 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 26 | FVMessageUtil.dropUnexpectedMesg(this, fvSlicer); 27 | } 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVGetConfigRequest.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.slicer.FVSlicer; 5 | import org.openflow.protocol.OFGetConfigRequest; 6 | 7 | public class FVGetConfigRequest extends OFGetConfigRequest implements 8 | Classifiable, Slicable { 9 | 10 | @Override 11 | public void classifyFromSwitch(FVClassifier fvClassifier) { 12 | FVMessageUtil.dropUnexpectedMesg(this, fvClassifier); 13 | } 14 | 15 | @Override 16 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 17 | FVMessageUtil.translateXidAndSend(this, fvClassifier, fvSlicer); 18 | } 19 | 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVHello.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.ofswitch.TopologyConnection; 8 | import org.flowvisor.slicer.FVSlicer; 9 | 10 | /** 11 | * @author capveg 12 | * 13 | */ 14 | public class FVHello extends org.openflow.protocol.OFHello implements 15 | Classifiable, Slicable, TopologyControllable { 16 | 17 | /* 18 | * (non-Javadoc) 19 | * 20 | * @seeorg.flowvisor.message.Classifiable#classifyFromSwitch(org.flowvisor. 21 | * classifier.FVClassifier) 22 | */ 23 | @Override 24 | public void classifyFromSwitch(FVClassifier fvClassifier) { 25 | // silently drop all Hello msgs 26 | } 27 | 28 | /* 29 | * (non-Javadoc) 30 | * 31 | * @see 32 | * org.flowvisor.message.Slicable#sliceFromController(org.flowvisor.classifier 33 | * .FVClassifier, org.flowvisor.slicer.FVSlicer) 34 | */ 35 | @Override 36 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 37 | // silently drop all Hello msgs 38 | } 39 | 40 | @Override 41 | public void topologyController(TopologyConnection topologyConnection) { 42 | // silently drop all Hello msgs 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVPortMod.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.log.FVLog; 5 | import org.flowvisor.log.LogLevel; 6 | import org.flowvisor.slicer.FVSlicer; 7 | import org.openflow.protocol.OFPhysicalPort; 8 | import org.openflow.protocol.OFPortMod; 9 | import org.openflow.protocol.OFError.OFPortModFailedCode; 10 | 11 | public class FVPortMod extends OFPortMod implements Classifiable, Slicable { 12 | 13 | /** 14 | * Send to all slices with this port 15 | * 16 | * FIXME: decide if port_mod's can come *up* from switch? 17 | */ 18 | @Override 19 | public void classifyFromSwitch(FVClassifier fvClassifier) { 20 | FVLog.log(LogLevel.DEBUG, fvClassifier, "recv from switch: " + this); 21 | for (FVSlicer fvSlicer : fvClassifier.getSlicers()) 22 | if (fvSlicer.portInSlice(this.portNumber)) 23 | fvSlicer.sendMsg(this, fvClassifier); 24 | } 25 | 26 | /** 27 | * First, check to see if this port is available in this slice Second, check 28 | * to see if they're changing the FLOOD bit FIXME: prevent slices from 29 | * administratrively bringing down a port! 30 | */ 31 | @Override 32 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 33 | // First, check if this port is in the slice 34 | if (!fvSlicer.portInSlice(this.portNumber)) { 35 | fvSlicer.sendMsg(FVMessageUtil.makeErrorMsg( 36 | OFPortModFailedCode.OFPPMFC_BAD_PORT, this), fvClassifier); 37 | return; 38 | } 39 | // Second, update the port's flood state 40 | // boolean oldValue = fvSlicer.getFloodPortStatus(this.portNumber); 41 | fvSlicer.setFloodPortStatus(this.portNumber, 42 | (this.mask & OFPhysicalPort.OFPortConfig.OFPPC_NO_FLOOD 43 | .getValue()) == 0); 44 | // if (oldValue != fvSlicer.getFloodPortStatus(this.portNumber)) 45 | // FVLog.log(LogLevel.CRIT, fvSlicer, 46 | // "FIXME: need to implement FLOODING port changes"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVQueueConfigRequest.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.slicer.FVSlicer; 5 | import org.openflow.protocol.OFError.OFBadRequestCode; 6 | import org.openflow.protocol.OFQueueConfigRequest; 7 | 8 | 9 | public class FVQueueConfigRequest extends OFQueueConfigRequest implements 10 | Classifiable, Slicable { 11 | 12 | @Override 13 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 14 | if (!fvSlicer.portInSlice(this.port)) { 15 | fvSlicer.sendMsg(FVMessageUtil.makeErrorMsg( 16 | OFBadRequestCode.OFPBRC_EPERM, this), fvClassifier); 17 | return; 18 | } 19 | 20 | FVMessageUtil.translateXidAndSend(this, fvClassifier, fvSlicer); 21 | 22 | } 23 | 24 | @Override 25 | public void classifyFromSwitch(FVClassifier fvClassifier) { 26 | FVMessageUtil.dropUnexpectedMesg(this, fvClassifier); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVSetConfig.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.slicer.FVSlicer; 5 | import org.openflow.protocol.OFSetConfig; 6 | import org.openflow.util.U16; 7 | 8 | public class FVSetConfig extends OFSetConfig implements Classifiable, Slicable { 9 | 10 | @Override 11 | public void classifyFromSwitch(FVClassifier fvClassifier) { 12 | FVMessageUtil.dropUnexpectedMesg(this, fvClassifier); 13 | } 14 | 15 | /** 16 | * Fake variable missSendLength parameters 17 | * 18 | * Save the missSendLength parameter for this slice and the switch
19 | * 20 | * The switch should always use the MAX missLen of all the slices. 21 | * 22 | * Update the switch's missLen if it's larger than previously asked for 23 | * Replace the missSendLength param with with one for the switch and send it 24 | * on the switch 25 | * 26 | */ 27 | @Override 28 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 29 | short missSendLength = this.getMissSendLength(); 30 | fvSlicer.setMissSendLength(missSendLength); 31 | // check to see if this is a larger missLen param then previously asked 32 | // for 33 | if (U16.f(fvClassifier.getMissSendLength()) < U16.f(missSendLength)) 34 | fvClassifier.setMissSendLength(missSendLength); 35 | else 36 | this.setMissSendLength(fvClassifier.getMissSendLength()); 37 | FVMessageUtil.translateXidAndSend(this, fvClassifier, fvSlicer); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVUnknownMessage.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import org.flowvisor.classifier.FVClassifier; 6 | import org.flowvisor.log.FVLog; 7 | import org.flowvisor.log.LogLevel; 8 | import org.flowvisor.slicer.FVSlicer; 9 | import org.openflow.protocol.OFMessage; 10 | import org.openflow.util.U32; 11 | import org.openflow.util.U8; 12 | 13 | public class FVUnknownMessage extends OFMessage implements Classifiable, 14 | Slicable { 15 | byte[] data; 16 | byte unknownType; 17 | 18 | public FVUnknownMessage() { 19 | super(); 20 | this.unknownType = -1; 21 | 22 | } 23 | 24 | @Override 25 | public void readFrom(ByteBuffer bb) { 26 | int pos = bb.position(); // intentionally ignoring mark() in case it's 27 | // in use 28 | this.unknownType = bb.get(pos + 1); 29 | bb.position(pos); 30 | FVLog.log(LogLevel.WARN, null, "read unhandled OFMessage type " 31 | + this.type); 32 | super.readFrom(bb); 33 | int left = this.length - OFMessage.MINIMUM_LENGTH; 34 | if (left > 0) { 35 | this.data = new byte[left]; 36 | bb.get(this.data); 37 | } 38 | } 39 | 40 | @Override 41 | public void writeTo(ByteBuffer bb) { 42 | super.writeTo(bb); 43 | if (data != null && data.length > 0) 44 | bb.put(data); 45 | } 46 | 47 | @Override 48 | public void classifyFromSwitch(FVClassifier fvClassifier) { 49 | FVLog.log(LogLevel.WARN, fvClassifier, 50 | "tried to classify UNKNOWN OF message: giving up"); 51 | } 52 | 53 | @Override 54 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 55 | FVLog.log(LogLevel.WARN, fvSlicer, 56 | "tried to slice UNKNOWN OF message: giving up"); 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return "ofmsg" + ":v=" + U8.f(this.getVersion()) + ";t=" + "UNKNOWN-" 62 | + this.unknownType + ";l=" + this.getLengthU() + ";x=" 63 | + U32.f(this.getXid()); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/FVVendor.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.slicer.FVSlicer; 5 | import org.openflow.protocol.OFVendor; 6 | 7 | public class FVVendor extends OFVendor implements Classifiable, Slicable { 8 | 9 | @Override 10 | public void classifyFromSwitch(FVClassifier fvClassifier) { 11 | // Just blindly forward vendor messages 12 | FVMessageUtil.untranslateXidAndSend(this, fvClassifier); 13 | } 14 | 15 | @Override 16 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer) { 17 | // Just blindly forward vendor messages 18 | FVMessageUtil.translateXidAndSend(this, fvClassifier, fvSlicer); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/SanityCheckable.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | public interface SanityCheckable { 4 | /** 5 | * A sanity check on the message to decide if it is safe to send or not 6 | * 7 | * @return true --> safe to send, false --> should be dropped 8 | */ 9 | public boolean isSane(); 10 | } 11 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/Slicable.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.slicer.FVSlicer; 5 | 6 | /** 7 | * Interface for slice specific, message specific rewriting 8 | * 9 | * @author capveg 10 | * 11 | */ 12 | 13 | public interface Slicable { 14 | /** 15 | * Send a sliced version of this message to the switch 16 | * 17 | * Sliced could mean rewritten or not sent at all (if the policy does not 18 | * allow it) 19 | * 20 | * @param fvClassifier 21 | * The potential destination 22 | * @param fvSlicer 23 | * The slicing policy and source of the message 24 | */ 25 | public void sliceFromController(FVClassifier fvClassifier, FVSlicer fvSlicer); 26 | } 27 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/TopologyControllable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message; 5 | 6 | import org.flowvisor.ofswitch.TopologyConnection; 7 | 8 | /** 9 | * Messages that are handled by the topology controller implement the 10 | * TopologyControllerable interface 11 | * 12 | * @author capveg 13 | * 14 | */ 15 | public interface TopologyControllable { 16 | void topologyController(TopologyConnection topologyConnection); 17 | } 18 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionDataLayerDestination.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message.actions; 5 | 6 | import java.util.Iterator; 7 | import java.util.List; 8 | 9 | import org.flowvisor.classifier.FVClassifier; 10 | import org.flowvisor.exceptions.ActionDisallowedException; 11 | import org.flowvisor.flows.FlowEntry; 12 | import org.flowvisor.flows.FlowSpaceUtil; 13 | import org.flowvisor.flows.SliceAction; 14 | import org.flowvisor.log.FVLog; 15 | import org.flowvisor.log.LogLevel; 16 | import org.flowvisor.openflow.protocol.FVMatch; 17 | import org.flowvisor.slicer.FVSlicer; 18 | import org.openflow.protocol.OFMatch; 19 | import org.openflow.protocol.OFError.OFBadActionCode; 20 | import org.openflow.protocol.action.OFAction; 21 | import org.openflow.protocol.action.OFActionDataLayerDestination; 22 | 23 | /** 24 | * @author capveg 25 | * 26 | */ 27 | public class FVActionDataLayerDestination extends OFActionDataLayerDestination 28 | implements SlicableAction { 29 | 30 | /* 31 | * (non-Javadoc) 32 | * 33 | * @see org.flowvisor.message.actions.SlicableAction#slice(java.util.List, 34 | * org.openflow.protocol.OFMatch, org.flowvisor.classifier.FVClassifier, 35 | * org.flowvisor.slicer.FVSlicer) 36 | */ 37 | @Override 38 | public void slice(List approvedActions, OFMatch match, 39 | FVClassifier fvClassifier, FVSlicer fvSlicer) 40 | throws ActionDisallowedException { 41 | FVMatch neoMatch = new FVMatch(match); 42 | neoMatch.setDataLayerDestination(this.dataLayerAddress); 43 | List flowEntries = fvClassifier.getSwitchFlowMap().matches(fvClassifier.getDPID(), neoMatch); 44 | for (FlowEntry fe : flowEntries) { 45 | Iterator it = fe.getActionsList().iterator(); 46 | while (it.hasNext()) { 47 | OFAction act = it.next(); 48 | if (act instanceof SliceAction) { 49 | SliceAction action = (SliceAction) act; 50 | if (action.getSliceName().equals(fvSlicer.getSliceName())) { 51 | FVLog.log(LogLevel.DEBUG, fvSlicer, "Approving " + this + 52 | " for " + match); 53 | approvedActions.add(this); 54 | return; 55 | } 56 | } 57 | } 58 | } 59 | throw new ActionDisallowedException( 60 | "Slice " + fvSlicer.getSliceName() + " may not rewrite destination " + 61 | "mac to " + FlowSpaceUtil.toLong(this.dataLayerAddress), 62 | OFBadActionCode.OFPBAC_BAD_ARGUMENT); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionDataLayerSource.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.exceptions.ActionDisallowedException; 8 | import org.flowvisor.flows.FlowEntry; 9 | import org.flowvisor.flows.FlowSpaceUtil; 10 | import org.flowvisor.flows.SliceAction; 11 | import org.flowvisor.log.FVLog; 12 | import org.flowvisor.log.LogLevel; 13 | import org.flowvisor.openflow.protocol.FVMatch; 14 | import org.flowvisor.slicer.FVSlicer; 15 | import org.openflow.protocol.OFMatch; 16 | import org.openflow.protocol.OFError.OFBadActionCode; 17 | import org.openflow.protocol.action.OFAction; 18 | import org.openflow.protocol.action.OFActionDataLayerSource; 19 | 20 | public class FVActionDataLayerSource extends OFActionDataLayerSource implements 21 | SlicableAction { 22 | 23 | @Override 24 | public void slice(List approvedActions, OFMatch match, 25 | FVClassifier fvClassifier, FVSlicer fvSlicer) 26 | throws ActionDisallowedException { 27 | FVMatch neoMatch = new FVMatch(match); 28 | neoMatch.setDataLayerSource(this.dataLayerAddress); 29 | List flowEntries = fvClassifier.getSwitchFlowMap().matches(fvClassifier.getDPID(), neoMatch); 30 | for (FlowEntry fe : flowEntries) { 31 | Iterator it = fe.getActionsList().iterator(); 32 | while (it.hasNext()) { 33 | OFAction act = it.next(); 34 | if (act instanceof SliceAction) { 35 | SliceAction action = (SliceAction) act; 36 | if (action.getSliceName().equals(fvSlicer.getSliceName())) { 37 | FVLog.log(LogLevel.DEBUG, fvSlicer, "Approving " + this + 38 | " for " + match); 39 | approvedActions.add(this); 40 | return; 41 | } 42 | } 43 | } 44 | } 45 | throw new ActionDisallowedException( 46 | "Slice " + fvSlicer.getSliceName() + " may not rewrite source " + 47 | "mac to " + FlowSpaceUtil.toLong(this.dataLayerAddress), 48 | OFBadActionCode.OFPBAC_BAD_ARGUMENT); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionEnqueue.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.List; 4 | 5 | import org.flowvisor.classifier.FVClassifier; 6 | import org.flowvisor.exceptions.ActionDisallowedException; 7 | import org.flowvisor.flows.FlowEntry; 8 | import org.flowvisor.flows.SliceAction; 9 | import org.flowvisor.openflow.protocol.FVMatch; 10 | import org.flowvisor.slicer.FVSlicer; 11 | import org.openflow.protocol.OFMatch; 12 | import org.openflow.protocol.OFError.OFBadActionCode; 13 | import org.openflow.protocol.action.OFAction; 14 | import org.openflow.protocol.action.OFActionEnqueue; 15 | 16 | public class FVActionEnqueue extends OFActionEnqueue implements SlicableAction { 17 | 18 | @Override 19 | public void slice(List approvedActions, OFMatch match, 20 | FVClassifier fvClassifier, FVSlicer fvSlicer) 21 | throws ActionDisallowedException { 22 | 23 | /* 24 | * Match OFMatch, if flowentry has queue id then OK. 25 | */ 26 | FVMatch neoMatch = new FVMatch(match); 27 | neoMatch.setInputPort(this.port); 28 | List entries = fvSlicer.getFlowSpace().matches(fvClassifier.getDPID(), neoMatch); 29 | for (FlowEntry fe : entries) { 30 | for (OFAction act : fe.getActionsList()) { 31 | SliceAction sa = (SliceAction) act; 32 | if (sa.getSliceName().equals(fvSlicer.getSliceName()) && 33 | fe.getQueueId().contains(this.queueId)) { 34 | approvedActions.add(this); 35 | return; 36 | } 37 | } 38 | } 39 | throw new ActionDisallowedException("Slice " + 40 | fvSlicer.getSliceName() + " may not enqueue to queue " + this.queueId 41 | + " for port " + this.port, 42 | OFBadActionCode.OFPBAC_BAD_QUEUE); 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionNetworkLayerDestination.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.exceptions.ActionDisallowedException; 8 | import org.flowvisor.flows.FlowEntry; 9 | import org.flowvisor.flows.FlowSpaceUtil; 10 | import org.flowvisor.flows.SliceAction; 11 | import org.flowvisor.log.FVLog; 12 | import org.flowvisor.log.LogLevel; 13 | import org.flowvisor.openflow.protocol.FVMatch; 14 | import org.flowvisor.slicer.FVSlicer; 15 | import org.openflow.protocol.OFMatch; 16 | import org.openflow.protocol.OFError.OFBadActionCode; 17 | import org.openflow.protocol.action.OFAction; 18 | import org.openflow.protocol.action.OFActionNetworkLayerDestination; 19 | 20 | public class FVActionNetworkLayerDestination extends 21 | OFActionNetworkLayerDestination implements SlicableAction { 22 | 23 | @Override 24 | public void slice(List approvedActions, OFMatch match, 25 | FVClassifier fvClassifier, FVSlicer fvSlicer) 26 | throws ActionDisallowedException { 27 | FVMatch neoMatch = new FVMatch(match); 28 | neoMatch.setNetworkDestination(this.networkAddress); 29 | List flowEntries = fvClassifier.getSwitchFlowMap().matches(fvClassifier.getDPID(), neoMatch); 30 | for (FlowEntry fe : flowEntries) { 31 | Iterator it = fe.getActionsList().iterator(); 32 | while (it.hasNext()) { 33 | OFAction act = it.next(); 34 | if (act instanceof SliceAction) { 35 | SliceAction action = (SliceAction) act; 36 | if (action.getSliceName().equals(fvSlicer.getSliceName())) { 37 | FVLog.log(LogLevel.DEBUG, fvSlicer, "Approving " + this + 38 | " for " + match); 39 | approvedActions.add(this); 40 | return; 41 | } 42 | } 43 | } 44 | } 45 | throw new ActionDisallowedException( 46 | "Slice " + fvSlicer.getSliceName() + " may not rewrite destination " + 47 | "IP to " + FlowSpaceUtil.intToIp(this.networkAddress), 48 | OFBadActionCode.OFPBAC_BAD_ARGUMENT); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionNetworkLayerSource.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.exceptions.ActionDisallowedException; 8 | import org.flowvisor.flows.FlowEntry; 9 | import org.flowvisor.flows.FlowSpaceUtil; 10 | import org.flowvisor.flows.SliceAction; 11 | import org.flowvisor.log.FVLog; 12 | import org.flowvisor.log.LogLevel; 13 | import org.flowvisor.openflow.protocol.FVMatch; 14 | import org.flowvisor.slicer.FVSlicer; 15 | import org.openflow.protocol.OFMatch; 16 | import org.openflow.protocol.OFError.OFBadActionCode; 17 | import org.openflow.protocol.action.OFAction; 18 | import org.openflow.protocol.action.OFActionNetworkLayerSource; 19 | 20 | public class FVActionNetworkLayerSource extends OFActionNetworkLayerSource 21 | implements SlicableAction { 22 | 23 | @Override 24 | public void slice(List approvedActions, OFMatch match, 25 | FVClassifier fvClassifier, FVSlicer fvSlicer) 26 | throws ActionDisallowedException { 27 | FVMatch neoMatch = new FVMatch(match); 28 | neoMatch.setNetworkSource(this.networkAddress); 29 | List flowEntries = fvClassifier.getSwitchFlowMap().matches(fvClassifier.getDPID(), neoMatch); 30 | for (FlowEntry fe : flowEntries) { 31 | Iterator it = fe.getActionsList().iterator(); 32 | while (it.hasNext()) { 33 | OFAction act = it.next(); 34 | if (act instanceof SliceAction) { 35 | SliceAction action = (SliceAction) act; 36 | if (action.getSliceName().equals(fvSlicer.getSliceName())) { 37 | FVLog.log(LogLevel.DEBUG, fvSlicer, "Approving " + this + 38 | " for " + match); 39 | approvedActions.add(this); 40 | return; 41 | } 42 | } 43 | } 44 | } 45 | throw new ActionDisallowedException( 46 | "Slice " + fvSlicer.getSliceName() + " may not rewrite source " + 47 | "IP to " + FlowSpaceUtil.intToIp(this.networkAddress), 48 | OFBadActionCode.OFPBAC_BAD_ARGUMENT); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionNetworkTypeOfService.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.exceptions.ActionDisallowedException; 8 | import org.flowvisor.flows.FlowEntry; 9 | import org.flowvisor.flows.SliceAction; 10 | import org.flowvisor.log.FVLog; 11 | import org.flowvisor.log.LogLevel; 12 | import org.flowvisor.openflow.protocol.FVMatch; 13 | import org.flowvisor.slicer.FVSlicer; 14 | import org.openflow.protocol.OFMatch; 15 | import org.openflow.protocol.OFError.OFBadActionCode; 16 | import org.openflow.protocol.action.OFAction; 17 | import org.openflow.protocol.action.OFActionNetworkTypeOfService; 18 | 19 | public class FVActionNetworkTypeOfService extends OFActionNetworkTypeOfService 20 | implements SlicableAction { 21 | 22 | @Override 23 | public void slice(List approvedActions, OFMatch match, 24 | FVClassifier fvClassifier, FVSlicer fvSlicer) 25 | throws ActionDisallowedException { 26 | FVMatch neoMatch = new FVMatch(match); 27 | neoMatch.setNetworkTypeOfService(this.networkTypeOfService); 28 | List flowEntries = fvClassifier.getSwitchFlowMap().matches(fvClassifier.getDPID(), neoMatch); 29 | for (FlowEntry fe : flowEntries) { 30 | Iterator it = fe.getActionsList().iterator(); 31 | while (it.hasNext()) { 32 | OFAction act = it.next(); 33 | if (act instanceof SliceAction) { 34 | SliceAction action = (SliceAction) act; 35 | if (action.getSliceName().equals(fvSlicer.getSliceName())) { 36 | FVLog.log(LogLevel.DEBUG, fvSlicer, "Approving " + this + 37 | " for " + match); 38 | approvedActions.add(this); 39 | return; 40 | } 41 | } 42 | } 43 | } 44 | throw new ActionDisallowedException( 45 | "Slice " + fvSlicer.getSliceName() + " may not TOS " + 46 | "field to " + this.networkTypeOfService, 47 | OFBadActionCode.OFPBAC_BAD_ARGUMENT); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionStripVirtualLan.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.exceptions.ActionDisallowedException; 8 | import org.flowvisor.flows.FlowEntry; 9 | import org.flowvisor.flows.FlowSpaceRuleStore; 10 | import org.flowvisor.flows.SliceAction; 11 | import org.flowvisor.log.FVLog; 12 | import org.flowvisor.log.LogLevel; 13 | import org.flowvisor.openflow.protocol.FVMatch; 14 | import org.flowvisor.slicer.FVSlicer; 15 | import org.openflow.protocol.OFMatch; 16 | import org.openflow.protocol.OFError.OFBadActionCode; 17 | import org.openflow.protocol.action.OFAction; 18 | import org.openflow.protocol.action.OFActionStripVirtualLan; 19 | 20 | public class FVActionStripVirtualLan extends OFActionStripVirtualLan implements 21 | SlicableAction { 22 | 23 | @Override 24 | public void slice(List approvedActions, OFMatch match, 25 | FVClassifier fvClassifier, FVSlicer fvSlicer) 26 | throws ActionDisallowedException { 27 | FVMatch neoMatch = new FVMatch(match); 28 | neoMatch.setDataLayerVirtualLan(FlowSpaceRuleStore.ANY_VLAN_ID); 29 | List flowEntries = fvClassifier.getSwitchFlowMap().matches(fvClassifier.getDPID(), neoMatch); 30 | for (FlowEntry fe : flowEntries) { 31 | Iterator it = fe.getActionsList().iterator(); 32 | while (it.hasNext()) { 33 | OFAction act = it.next(); 34 | if (act instanceof SliceAction) { 35 | SliceAction action = (SliceAction) act; 36 | if (action.getSliceName().equals(fvSlicer.getSliceName())) { 37 | FVLog.log(LogLevel.DEBUG, fvSlicer, "Approving " + this + 38 | " for " + match); 39 | approvedActions.add(this); 40 | return; 41 | } 42 | } 43 | } 44 | } 45 | throw new ActionDisallowedException( 46 | "Slice " + fvSlicer.getSliceName() + " may not strip the vlan tag.", 47 | OFBadActionCode.OFPBAC_BAD_ARGUMENT); 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionTransportLayerDestination.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.exceptions.ActionDisallowedException; 8 | import org.flowvisor.flows.FlowEntry; 9 | import org.flowvisor.flows.SliceAction; 10 | import org.flowvisor.log.FVLog; 11 | import org.flowvisor.log.LogLevel; 12 | import org.flowvisor.openflow.protocol.FVMatch; 13 | import org.flowvisor.slicer.FVSlicer; 14 | import org.openflow.protocol.OFMatch; 15 | import org.openflow.protocol.OFError.OFBadActionCode; 16 | import org.openflow.protocol.action.OFAction; 17 | import org.openflow.protocol.action.OFActionTransportLayerDestination; 18 | 19 | public class FVActionTransportLayerDestination extends 20 | OFActionTransportLayerDestination implements SlicableAction { 21 | 22 | @Override 23 | public void slice(List approvedActions, OFMatch match, 24 | FVClassifier fvClassifier, FVSlicer fvSlicer) 25 | throws ActionDisallowedException { 26 | FVMatch neoMatch = new FVMatch(match); 27 | neoMatch.setTransportDestination(this.transportPort); 28 | List flowEntries = fvClassifier.getSwitchFlowMap().matches(fvClassifier.getDPID(), neoMatch); 29 | for (FlowEntry fe : flowEntries) { 30 | Iterator it = fe.getActionsList().iterator(); 31 | while (it.hasNext()) { 32 | OFAction act = it.next(); 33 | if (act instanceof SliceAction) { 34 | SliceAction action = (SliceAction) act; 35 | if (action.getSliceName().equals(fvSlicer.getSliceName())) { 36 | FVLog.log(LogLevel.DEBUG, fvSlicer, "Approving " + this + 37 | " for " + match); 38 | approvedActions.add(this); 39 | return; 40 | } 41 | } 42 | } 43 | } 44 | throw new ActionDisallowedException( 45 | "Slice " + fvSlicer.getSliceName() + " may not rewrite transport " + 46 | "dst port to " + this.transportPort, 47 | OFBadActionCode.OFPBAC_BAD_ARGUMENT); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionTransportLayerSource.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.exceptions.ActionDisallowedException; 8 | import org.flowvisor.flows.FlowEntry; 9 | import org.flowvisor.flows.SliceAction; 10 | import org.flowvisor.log.FVLog; 11 | import org.flowvisor.log.LogLevel; 12 | import org.flowvisor.openflow.protocol.FVMatch; 13 | import org.flowvisor.slicer.FVSlicer; 14 | import org.openflow.protocol.OFMatch; 15 | import org.openflow.protocol.OFError.OFBadActionCode; 16 | import org.openflow.protocol.action.OFAction; 17 | import org.openflow.protocol.action.OFActionTransportLayerSource; 18 | 19 | public class FVActionTransportLayerSource extends OFActionTransportLayerSource 20 | implements SlicableAction { 21 | 22 | @Override 23 | public void slice(List approvedActions, OFMatch match, 24 | FVClassifier fvClassifier, FVSlicer fvSlicer) 25 | throws ActionDisallowedException { 26 | FVMatch neoMatch = new FVMatch(match); 27 | neoMatch.setTransportSource(this.transportPort); 28 | List flowEntries = fvClassifier.getSwitchFlowMap().matches(fvClassifier.getDPID(), neoMatch); 29 | for (FlowEntry fe : flowEntries) { 30 | Iterator it = fe.getActionsList().iterator(); 31 | while (it.hasNext()) { 32 | OFAction act = it.next(); 33 | if (act instanceof SliceAction) { 34 | SliceAction action = (SliceAction) act; 35 | if (action.getSliceName().equals(fvSlicer.getSliceName())) { 36 | FVLog.log(LogLevel.DEBUG, fvSlicer, "Approving " + this + 37 | " for " + match); 38 | approvedActions.add(this); 39 | return; 40 | } 41 | } 42 | } 43 | } 44 | throw new ActionDisallowedException( 45 | "Slice " + fvSlicer.getSliceName() + " may not rewrite transport " + 46 | "src port to " + this.transportPort, 47 | OFBadActionCode.OFPBAC_BAD_ARGUMENT); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionVendor.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.List; 4 | 5 | import org.flowvisor.classifier.FVClassifier; 6 | import org.flowvisor.exceptions.ActionDisallowedException; 7 | import org.flowvisor.log.FVLog; 8 | import org.flowvisor.log.LogLevel; 9 | import org.flowvisor.slicer.FVSlicer; 10 | import org.openflow.protocol.OFMatch; 11 | import org.openflow.protocol.action.OFAction; 12 | import org.openflow.protocol.action.OFActionVendor; 13 | 14 | public class FVActionVendor extends OFActionVendor implements SlicableAction { 15 | 16 | @Override 17 | public void slice(List approvedActions, OFMatch match, 18 | FVClassifier fvClassifier, FVSlicer fvSlicer) 19 | throws ActionDisallowedException { 20 | FVLog.log(LogLevel.CRIT, fvSlicer, 21 | "action slicing unimplemented for type: " + this); 22 | approvedActions.add(this); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionVirtualLanIdentifier.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.exceptions.ActionDisallowedException; 8 | import org.flowvisor.flows.FlowEntry; 9 | import org.flowvisor.flows.SliceAction; 10 | import org.flowvisor.log.FVLog; 11 | import org.flowvisor.log.LogLevel; 12 | import org.flowvisor.openflow.protocol.FVMatch; 13 | import org.flowvisor.slicer.FVSlicer; 14 | import org.openflow.protocol.OFMatch; 15 | import org.openflow.protocol.OFError.OFBadActionCode; 16 | import org.openflow.protocol.action.OFAction; 17 | import org.openflow.protocol.action.OFActionVirtualLanIdentifier; 18 | 19 | public class FVActionVirtualLanIdentifier extends OFActionVirtualLanIdentifier 20 | implements SlicableAction { 21 | 22 | @Override 23 | public void slice(List approvedActions, OFMatch match, 24 | FVClassifier fvClassifier, FVSlicer fvSlicer) 25 | throws ActionDisallowedException { 26 | FVMatch neoMatch = new FVMatch(match); 27 | neoMatch.setDataLayerVirtualLan(this.virtualLanIdentifier); 28 | List flowEntries = fvClassifier.getSwitchFlowMap().matches(fvClassifier.getDPID(), neoMatch); 29 | for (FlowEntry fe : flowEntries) { 30 | Iterator it = fe.getActionsList().iterator(); 31 | while (it.hasNext()) { 32 | OFAction act = it.next(); 33 | if (act instanceof SliceAction) { 34 | SliceAction action = (SliceAction) act; 35 | if (action.getSliceName().equals(fvSlicer.getSliceName())) { 36 | FVLog.log(LogLevel.DEBUG, fvSlicer, "Approving " + this + 37 | " for " + match); 38 | approvedActions.add(this); 39 | return; 40 | } 41 | } 42 | } 43 | } 44 | throw new ActionDisallowedException( 45 | "Slice " + fvSlicer.getSliceName() + " may not rewrite vlan " + 46 | "tag to " + this.getVirtualLanIdentifier(), 47 | OFBadActionCode.OFPBAC_BAD_ARGUMENT); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/FVActionVirtualLanPriorityCodePoint.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.actions; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.exceptions.ActionDisallowedException; 8 | import org.flowvisor.flows.FlowEntry; 9 | import org.flowvisor.flows.SliceAction; 10 | import org.flowvisor.log.FVLog; 11 | import org.flowvisor.log.LogLevel; 12 | import org.flowvisor.openflow.protocol.FVMatch; 13 | import org.flowvisor.slicer.FVSlicer; 14 | import org.openflow.protocol.OFMatch; 15 | import org.openflow.protocol.OFError.OFBadActionCode; 16 | import org.openflow.protocol.action.OFAction; 17 | import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint; 18 | 19 | public class FVActionVirtualLanPriorityCodePoint extends 20 | OFActionVirtualLanPriorityCodePoint implements SlicableAction { 21 | 22 | @Override 23 | public void slice(List approvedActions, OFMatch match, 24 | FVClassifier fvClassifier, FVSlicer fvSlicer) 25 | throws ActionDisallowedException { 26 | FVMatch neoMatch = new FVMatch(match); 27 | neoMatch.setDataLayerVirtualLanPriorityCodePoint(this.virtualLanPriorityCodePoint); 28 | List flowEntries = fvClassifier.getSwitchFlowMap().matches(fvClassifier.getDPID(), neoMatch); 29 | for (FlowEntry fe : flowEntries) { 30 | Iterator it = fe.getActionsList().iterator(); 31 | while (it.hasNext()) { 32 | OFAction act = it.next(); 33 | if (act instanceof SliceAction) { 34 | SliceAction action = (SliceAction) act; 35 | if (action.getSliceName().equals(fvSlicer.getSliceName())) { 36 | FVLog.log(LogLevel.DEBUG, fvSlicer, "Approving " + this + 37 | " for " + match); 38 | approvedActions.add(this); 39 | return; 40 | } 41 | } 42 | } 43 | } 44 | throw new ActionDisallowedException( 45 | "Slice " + fvSlicer.getSliceName() + " may not rewrite vlan " + 46 | "priority to " + this.getVirtualLanPriorityCodePoint(), 47 | OFBadActionCode.OFPBAC_BAD_ARGUMENT); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/actions/SlicableAction.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message.actions; 5 | 6 | import java.util.List; 7 | 8 | import org.flowvisor.classifier.FVClassifier; 9 | import org.flowvisor.exceptions.ActionDisallowedException; 10 | import org.flowvisor.slicer.FVSlicer; 11 | import org.openflow.protocol.OFMatch; 12 | import org.openflow.protocol.action.OFAction; 13 | 14 | /** 15 | * @author capveg 16 | * 17 | */ 18 | public interface SlicableAction { 19 | 20 | /** 21 | * See if this action is allowed in the slice definition, given this match 22 | * If yes, then write it to the approvedActions list (possibly rewritten) or 23 | * expanded 24 | * 25 | * @param approvedActions 26 | * list of already approved actions 27 | * @param match 28 | * the context the action is used in ; the inport is set to the 29 | * inport of the packet_out 30 | * @param fvClassifier 31 | * switch definition 32 | * @param fvSlicer 33 | * slice definition 34 | * @throws if the action is not allowed 35 | */ 36 | 37 | public void slice(List approvedActions, OFMatch match, 38 | FVClassifier fvClassifier, FVSlicer fvSlicer) 39 | throws ActionDisallowedException; 40 | } 41 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/statistics/ClassifiableStatistic.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message.statistics; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.message.FVStatisticsReply; 8 | 9 | /** 10 | * @author capveg 11 | * 12 | */ 13 | public interface ClassifiableStatistic { 14 | /** 15 | * Given this stat and the slicer and classifier, figure out which slice this message is 16 | * for, rewrite anything as necessary, and send it onto the slice's 17 | * controller 18 | * 19 | * @param approuvedStats 20 | * @param fvClassifier 21 | * @param fvSlicer 22 | */ 23 | public void classifyFromSwitch(FVStatisticsReply msg, FVClassifier fvClassifier); 24 | 25 | 26 | /*public void classifyFromSwitch(OFMessage original, List approvedStats, FVClassifier fvClassifier, 27 | FVSlicer fvSlicer) throws StatDisallowedException;*/ 28 | } 29 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/statistics/FVAggregateStatisticsReply.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.statistics; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.log.FVLog; 8 | import org.flowvisor.log.LogLevel; 9 | import org.flowvisor.message.FVStatisticsReply; 10 | import org.flowvisor.message.FVStatisticsRequest; 11 | import org.flowvisor.slicer.FVSlicer; 12 | import org.openflow.protocol.statistics.OFAggregateStatisticsReply; 13 | import org.openflow.protocol.statistics.OFStatistics; 14 | 15 | public class FVAggregateStatisticsReply extends OFAggregateStatisticsReply 16 | implements SlicableStatistic, ClassifiableStatistic { 17 | 18 | private HashMap statsMap = new HashMap(); 19 | 20 | @Override 21 | public void classifyFromSwitch(FVStatisticsReply msg, FVClassifier fvClassifier) { 22 | FVLog.log(LogLevel.WARN, fvClassifier, "dropping unexpected msg: " 23 | + msg); 24 | //statsMap = toMap(msg); 25 | } 26 | 27 | @Override 28 | public void sliceFromController(FVStatisticsRequest msg, FVClassifier fvClassifier, 29 | FVSlicer fvSlicer) { 30 | FVLog.log(LogLevel.WARN, fvClassifier, "dropping unexpected msg: " 31 | + msg); 32 | 33 | } 34 | 35 | private HashMap toMap(FVStatisticsReply msg) { 36 | List stats = msg.getStatistics(); 37 | HashMap cache = new HashMap(); 38 | 39 | for (int i=0; i getMap(){ 49 | return statsMap; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/statistics/FVAggregateStatisticsRequest.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.statistics; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.log.FVLog; 5 | import org.flowvisor.log.LogLevel; 6 | import org.flowvisor.message.FVMessageUtil; 7 | import org.flowvisor.message.FVStatisticsReply; 8 | import org.flowvisor.message.FVStatisticsRequest; 9 | import org.flowvisor.slicer.FVSlicer; 10 | 11 | public class FVAggregateStatisticsRequest extends 12 | org.openflow.protocol.statistics.OFAggregateStatisticsRequest implements 13 | SlicableStatistic, ClassifiableStatistic { 14 | 15 | 16 | 17 | 18 | @Override 19 | public void classifyFromSwitch(FVStatisticsReply msg, FVClassifier fvClassifier) { 20 | FVLog.log(LogLevel.WARN, fvClassifier, "dropping unexpected msg: " 21 | + this); 22 | } 23 | 24 | @Override 25 | public void sliceFromController(FVStatisticsRequest msg, FVClassifier fvClassifier, 26 | FVSlicer fvSlicer) { 27 | FVMessageUtil.translateXidMsg(msg,fvClassifier, fvSlicer); 28 | if (!fvClassifier.pollFlowTableStats(msg)) 29 | fvClassifier.sendAggStatsResp(fvSlicer, msg); 30 | 31 | } 32 | 33 | 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/statistics/FVDescriptionStatistics.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.statistics; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import org.flowvisor.FlowVisor; 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.log.FVLog; 8 | import org.flowvisor.log.LogLevel; 9 | import org.flowvisor.message.FVMessageUtil; 10 | import org.flowvisor.message.FVStatisticsReply; 11 | import org.flowvisor.message.FVStatisticsRequest; 12 | import org.flowvisor.slicer.FVSlicer; 13 | import org.openflow.protocol.statistics.OFDescriptionStatistics; 14 | 15 | public class FVDescriptionStatistics extends OFDescriptionStatistics implements 16 | SlicableStatistic, ClassifiableStatistic { 17 | 18 | 19 | /** 20 | * NOTE: we no long do any DescriptionStatistics rewriting, now that 1.0 21 | * support dp_desc field. 22 | * 23 | * NOTE: now that no 1.0 vendors use dp_desc the way I wanted them to, we're 24 | * going to do rewriting again... *sigh* 25 | */ 26 | 27 | @Override 28 | public void classifyFromSwitch(FVStatisticsReply msg, FVClassifier fvClassifier) { 29 | 30 | if (fvClassifier.wantStatsDescHack()) { 31 | InetSocketAddress remote = (InetSocketAddress) fvClassifier 32 | .getSocketChannel().socket().getRemoteSocketAddress(); 33 | 34 | this.datapathDescription += " (" + remote.getAddress().getHostAddress() + ":" 35 | + remote.getPort() + ")"; 36 | this.datapathDescription += " (" + FlowVisor.FLOWVISOR_VERSION + ")"; 37 | 38 | if (this.datapathDescription.length() > FVDescriptionStatistics.DESCRIPTION_STRING_LENGTH) 39 | this.datapathDescription = this.datapathDescription.substring( 40 | 0, 41 | FVDescriptionStatistics.DESCRIPTION_STRING_LENGTH - 1); 42 | } 43 | FVMessageUtil.untranslateXidAndSend(msg, fvClassifier); 44 | 45 | } 46 | 47 | @Override 48 | public void sliceFromController(FVStatisticsRequest msg, FVClassifier fvClassifier, 49 | FVSlicer fvSlicer) { 50 | FVLog.log(LogLevel.INFO, fvSlicer, "FVDescriptions requests have no body; message is illegal. Dropping: ", this); 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/statistics/FVFlowStatisticsRequest.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.statistics; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.log.FVLog; 5 | import org.flowvisor.log.LogLevel; 6 | import org.flowvisor.message.FVMessageUtil; 7 | import org.flowvisor.message.FVStatisticsReply; 8 | import org.flowvisor.message.FVStatisticsRequest; 9 | import org.flowvisor.slicer.FVSlicer; 10 | import org.openflow.protocol.statistics.OFFlowStatisticsRequest; 11 | 12 | public final class FVFlowStatisticsRequest extends OFFlowStatisticsRequest 13 | implements SlicableStatistic, ClassifiableStatistic { 14 | 15 | 16 | 17 | @Override 18 | public void classifyFromSwitch(FVStatisticsReply msg, FVClassifier fvClassifier) { 19 | FVLog.log(LogLevel.WARN, fvClassifier, "dropping unexpected msg: " 20 | + this); 21 | 22 | } 23 | 24 | @Override 25 | public void sliceFromController(FVStatisticsRequest msg, FVClassifier fvClassifier, 26 | FVSlicer fvSlicer) { 27 | FVMessageUtil.translateXidMsg(msg,fvClassifier, fvSlicer); 28 | if (!fvClassifier.pollFlowTableStats(msg)) 29 | fvClassifier.sendFlowStatsResp(fvSlicer, msg, (short)0); 30 | 31 | } 32 | 33 | 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/statistics/FVPortStatisticsRequest.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.statistics; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.log.FVLog; 5 | import org.flowvisor.log.LogLevel; 6 | import org.flowvisor.message.FVMessageUtil; 7 | import org.flowvisor.message.FVStatisticsReply; 8 | import org.flowvisor.message.FVStatisticsRequest; 9 | import org.flowvisor.slicer.FVSlicer; 10 | import org.openflow.protocol.statistics.OFPortStatisticsRequest; 11 | 12 | public class FVPortStatisticsRequest extends OFPortStatisticsRequest implements 13 | ClassifiableStatistic, SlicableStatistic { 14 | 15 | 16 | 17 | @Override 18 | public void sliceFromController(FVStatisticsRequest msg, 19 | FVClassifier fvClassifier, FVSlicer fvSlicer) { 20 | //TODO: implement port stats 21 | FVMessageUtil.translateXidAndSend(msg, fvClassifier, fvSlicer); 22 | } 23 | 24 | @Override 25 | public void classifyFromSwitch(FVStatisticsReply msg, 26 | FVClassifier fvClassifier) { 27 | FVLog.log(LogLevel.WARN, fvClassifier, "dropping unexpected msg: " 28 | + this); 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/statistics/FVQueueStatisticsRequest.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.statistics; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.log.FVLog; 5 | import org.flowvisor.log.LogLevel; 6 | import org.flowvisor.message.FVMessageUtil; 7 | import org.flowvisor.message.FVStatisticsReply; 8 | import org.flowvisor.message.FVStatisticsRequest; 9 | import org.flowvisor.slicer.FVSlicer; 10 | import org.openflow.protocol.statistics.OFQueueStatisticsRequest; 11 | 12 | public class FVQueueStatisticsRequest extends OFQueueStatisticsRequest 13 | implements ClassifiableStatistic, SlicableStatistic, Cloneable { 14 | 15 | 16 | @Override 17 | public void classifyFromSwitch(FVStatisticsReply msg, FVClassifier fvClassifier) { 18 | FVLog.log(LogLevel.WARN, fvClassifier, "dropping unexpected msg: " 19 | + msg); 20 | } 21 | 22 | @Override 23 | public void sliceFromController(FVStatisticsRequest msg, FVClassifier fvClassifier, 24 | FVSlicer fvSlicer) { 25 | FVMessageUtil.translateXidAndSend(msg, fvClassifier, fvSlicer); 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/statistics/FVVendorStatistics.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.message.statistics; 2 | 3 | import org.flowvisor.classifier.FVClassifier; 4 | import org.flowvisor.message.FVMessageUtil; 5 | import org.flowvisor.message.FVStatisticsReply; 6 | import org.flowvisor.message.FVStatisticsRequest; 7 | import org.flowvisor.slicer.FVSlicer; 8 | import org.openflow.protocol.statistics.OFVendorStatistics; 9 | 10 | public class FVVendorStatistics extends OFVendorStatistics implements 11 | SlicableStatistic, ClassifiableStatistic { 12 | 13 | 14 | 15 | @Override 16 | public void classifyFromSwitch(FVStatisticsReply msg, 17 | FVClassifier fvClassifier) { 18 | FVMessageUtil.untranslateXidAndSend(msg, fvClassifier); 19 | } 20 | 21 | @Override 22 | public void sliceFromController(FVStatisticsRequest msg, 23 | FVClassifier fvClassifier, FVSlicer fvSlicer) { 24 | FVMessageUtil.translateXidAndSend(msg, fvClassifier, fvSlicer); 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/org/flowvisor/message/statistics/SlicableStatistic.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.message.statistics; 5 | 6 | import org.flowvisor.classifier.FVClassifier; 7 | import org.flowvisor.message.FVStatisticsRequest; 8 | import org.flowvisor.slicer.FVSlicer; 9 | 10 | /** 11 | * @author capveg 12 | * 13 | */ 14 | public interface SlicableStatistic { 15 | 16 | /** 17 | * Given this stat, classifier, and slicer decide how this statistic should 18 | * be rewritten coming from the controller 19 | * 20 | * @param approuvedStats 21 | * @param fvClassifier 22 | * @param fvSlicer 23 | */ 24 | 25 | public void sliceFromController(FVStatisticsRequest msg, FVClassifier fvClassifier, FVSlicer fvSlicer); 26 | 27 | /*public void sliceFromController(List approvedStats, FVClassifier fvClassifier, 28 | FVSlicer fvSlicer) throws StatDisallowedException;*/ 29 | } 30 | -------------------------------------------------------------------------------- /src/org/flowvisor/ofswitch/DPIDandPort.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.ofswitch; 2 | 3 | public class DPIDandPort { 4 | long dpid; 5 | short port; 6 | 7 | public DPIDandPort(long dpid, short port) { 8 | super(); 9 | this.dpid = dpid; 10 | this.port = port; 11 | } 12 | 13 | /** 14 | * @return the dpid 15 | */ 16 | public long getDpid() { 17 | return dpid; 18 | } 19 | 20 | /** 21 | * @param dpid 22 | * the dpid to set 23 | */ 24 | public void setDpid(long dpid) { 25 | this.dpid = dpid; 26 | } 27 | 28 | /** 29 | * @return the port 30 | */ 31 | public short getPort() { 32 | return port; 33 | } 34 | 35 | /** 36 | * @param port 37 | * the port to set 38 | */ 39 | public void setPort(short port) { 40 | this.port = port; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/org/flowvisor/resources/SlicerLimits.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.resources; 2 | 3 | import java.util.HashMap; 4 | 5 | import org.flowvisor.resources.ratelimit.TokenBucket; 6 | 7 | public class SlicerLimits { 8 | 9 | private HashMap sliceFMLimits = null; 10 | private HashMap rateLimits = null; 11 | 12 | public SlicerLimits() { 13 | this.sliceFMLimits = new HashMap(); 14 | this.rateLimits = new HashMap(); 15 | } 16 | 17 | public synchronized void incrementSliceFMCounter(String sliceName) { 18 | Integer curr = sliceFMLimits.get(sliceName); 19 | if (curr == null) 20 | curr = 0; 21 | sliceFMLimits.put(sliceName, ++curr); 22 | } 23 | 24 | public synchronized void decrementSliceFMCounter(String sliceName) { 25 | Integer curr = sliceFMLimits.get(sliceName); 26 | if (curr == null || curr <= 0) 27 | curr = 1; 28 | sliceFMLimits.put(sliceName, --curr); 29 | } 30 | 31 | public synchronized Integer getSliceFMLimit(String sliceName) { 32 | Integer curr = sliceFMLimits.get(sliceName); 33 | if (curr == null) 34 | curr = 0; 35 | return curr; 36 | } 37 | 38 | public TokenBucket getRateLimiter(String slice) { 39 | return rateLimits.get(slice); 40 | } 41 | 42 | public void setRateLimiter(String slice, TokenBucket bucket) { 43 | rateLimits.put(slice, bucket); 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/org/flowvisor/resources/ratelimit/FixedIntervalRefillStrategy.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.resources.ratelimit; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | 6 | public class FixedIntervalRefillStrategy implements RefillStrategy { 7 | 8 | private final long numTokens; 9 | private final long period; 10 | private long nextRefillTime; 11 | 12 | 13 | public FixedIntervalRefillStrategy(long numTokens, long period, TimeUnit unit) { 14 | this.numTokens = numTokens; 15 | this.period = unit.toNanos(period); 16 | this.nextRefillTime = -1; 17 | } 18 | 19 | public synchronized long refill() { 20 | 21 | long now = System.nanoTime(); 22 | if (now < nextRefillTime) { 23 | return 0; 24 | } 25 | nextRefillTime = now + period; 26 | return numTokens; 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/org/flowvisor/resources/ratelimit/NoLimitRefillStrategy.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.resources.ratelimit; 2 | 3 | 4 | public class NoLimitRefillStrategy implements RefillStrategy { 5 | 6 | private final long numTokens; 7 | 8 | public NoLimitRefillStrategy(long numTokens) { 9 | this.numTokens = numTokens; 10 | } 11 | 12 | public long refill() { 13 | 14 | return numTokens; 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/org/flowvisor/resources/ratelimit/RefillStrategy.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.resources.ratelimit; 2 | 3 | public interface RefillStrategy { 4 | 5 | /* 6 | * Defines the refill strategy for a given 7 | * token bucket 8 | */ 9 | long refill(); 10 | 11 | 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/org/flowvisor/resources/ratelimit/TokenBucket.java: -------------------------------------------------------------------------------- 1 | package org.flowvisor.resources.ratelimit; 2 | 3 | import org.flowvisor.log.FVLog; 4 | import org.flowvisor.log.LogLevel; 5 | 6 | 7 | public class TokenBucket { 8 | 9 | private final RefillStrategy strategy; 10 | private final long capacity; 11 | private long size; 12 | 13 | public TokenBucket(long capacity, RefillStrategy refillStrategy) { 14 | this.capacity = capacity; 15 | this.strategy = refillStrategy; 16 | this.size = capacity; 17 | } 18 | 19 | public TokenBucket() { 20 | this(200, new NoLimitRefillStrategy(200)); 21 | } 22 | 23 | /** 24 | * Attempt to consume a single token from the bucket. If it was consumed then {@code true} is returned, otherwise 25 | * {@code false} is returned. 26 | * 27 | * @return {@code true} if a token was consumed, {@code false} otherwise. 28 | */ 29 | public boolean consume() { 30 | return consume(1); 31 | } 32 | 33 | /** 34 | * Attempt to consume a specified number of tokens from the bucket. If the tokens were consumed then {@code true} 35 | * is returned, otherwise {@code false} is returned. 36 | * 37 | * @param numTokens The number of tokens to consume from the bucket, must be a positive number. 38 | * @return {@code true} if the tokens were consumed, {@code false} otherwise. 39 | */ 40 | public synchronized boolean consume(long numTokens) { 41 | 42 | // Give the refill strategy a chance to add tokens if it needs to 43 | long newTokens = Math.max(0, strategy.refill()); 44 | this.size = Math.max(0, Math.min(this.size + newTokens, capacity)); 45 | FVLog.log(LogLevel.DEBUG, null, "Refilled " + newTokens + " bucket has " + this.size); 46 | // Now try to consume some tokens 47 | if (numTokens <= this.size) { 48 | this.size -= numTokens; 49 | return true; 50 | } 51 | 52 | return false; 53 | } 54 | 55 | public long currentRate() { 56 | return this.capacity - this.size; 57 | } 58 | 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/org/flowvisor/slicer/ReconnectEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.flowvisor.slicer; 5 | 6 | import org.flowvisor.events.FVEventHandler; 7 | import org.flowvisor.events.FVTimerEvent; 8 | 9 | /** 10 | * @author capveg 11 | * 12 | */ 13 | public class ReconnectEvent extends FVTimerEvent { 14 | 15 | /** 16 | * Signal that we should reconnect in secondsToNextReconnect 17 | * 18 | * @param secondsToNextReconnect 19 | * relative time 20 | * @param src 21 | * both the source and the dest of the event 22 | */ 23 | public ReconnectEvent(int secondsToNextReconnect, FVEventHandler src) { 24 | super(0, src, src, null); 25 | this.setExpireTime(System.currentTimeMillis() + 1000 26 | * secondsToNextReconnect); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /utilities/README: -------------------------------------------------------------------------------- 1 | A bunch of utilities that help with using/debugging FV: 2 | 3 | ===== Nload ===== 4 | I use nload all the time to debug FV, so I've included it here. 5 | 6 | For example: 7 | 8 | 9 | # to count the lldp rate 10 | nload -i lo ether proto 0x88cc 11 | 12 | # to monitor for arp storms 13 | nload -i eth0 arp 14 | 15 | ==== Mrtg formatters === 16 | Simple utilities to translate get{Switch,Slice}Stats to mrtg friendly format 17 | 18 | 19 | ==== fvcli ==== 20 | Experimental interactive shell replacement for fvctl 21 | 22 | ==== init.d ==== 23 | Start scripts for different environments, e.g., CentOS 24 | -------------------------------------------------------------------------------- /utilities/find-syslog-jumps.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | $lasttime = 0; 4 | $delta = 2; # in seconds 5 | while(<>) { 6 | next unless(/flowvisor:/); 7 | chomp; 8 | @line = split; 9 | @time = split /:/, $line[2]; 10 | $nowtime = $time[0] * 3600 + $time[1] * 60 + $time[2]; 11 | if ( $lasttime > 0 and (($nowtime - $lasttime) > $delta)) { 12 | print "---------------------\n"; 13 | print $lastline, "\n"; 14 | print $_, "\n"; 15 | } 16 | # Jul 15 09:50:32 expedient flowvisor: ALERT-slicer_naxos-33102_ID__expedient_clemson_edu_9_dpid=06:d6:00:26:f1:3f:e4:80: STARVING: handling event took 16ms: org.flowvisor.events.FVIOEvent@4077db 17 | 18 | if (/STARVING: handling took (\d+)ms:/){ 19 | print "###### ", $_, "\n" if ($1 > 1500); 20 | } 21 | $lasttime = $nowtime; 22 | $lastline = $_; 23 | } 24 | -------------------------------------------------------------------------------- /utilities/init.d/flowvisor-citrix-startup.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # start/stop the OpenFlow flowvisor daemon 4 | # 5 | # processname: flowvisor 6 | # description: OpenFlow flowvisor daemon 7 | # chkconfig: 2345 85 15 8 | 9 | DAEMON=/usr/local/sbin/flowvisor 10 | NAME=flowvisor 11 | FLOWVISOR_ARGS="" 12 | FLOWVISOR_CONFIG_FILE=/usr/local/etc/flowvisor/flowvisor-config.xml 13 | FLOWVISOR_USER=netop 14 | FLOWVISOR_GROUP=netop 15 | FLOWVISOR_PIDFILE=/var/run/flowvisor 16 | DESC="OpenFlow daemon" 17 | 18 | ###test -x $DAEMON || exit 0 19 | 20 | # Source function library. 21 | . /etc/init.d/functions 22 | 23 | # Get config. 24 | . /etc/sysconfig/network 25 | 26 | # Check that networking is up. 27 | if [ ${NETWORKING} = "no" ] 28 | then 29 | exit 0 30 | fi 31 | 32 | export PATH="${PATH:+$PATH:}/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin" 33 | 34 | ###set -e 35 | 36 | start() { 37 | echo -n $"Starting $DESC: $NAME " 38 | 39 | if [ ! -s "$FLOWVISOR_CONFIG_FILE" ]; then 40 | echo "missing or empty config file $FLOWVISOR_CONFIG_FILE" 41 | exit 1 42 | fi 43 | 44 | daemon --user $FLOWVISOR_USER $DAEMON $FLOWVISOR_ARGS $FLOWVISOR_CONFIG_FILE 45 | RETVAL=$? 46 | FLOWVISOR_PID=`pgrep -f '^java -server .*flowvisor'` 47 | 48 | echo 49 | [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$NAME && echo $FLOWVISOR_PID > $FLOWVISOR_PIDFILE 50 | return $RETVAL 51 | } 52 | 53 | stop() { 54 | echo -n $"Stopping $DESC: $NAME " 55 | killproc -p $FLOWVISOR_PIDFILE 56 | RETVAL=$? 57 | 58 | echo 59 | [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$NAME 60 | return $RETVAL 61 | } 62 | 63 | restart() { 64 | stop 65 | start 66 | } 67 | 68 | # See how we were called. 69 | case "$1" in 70 | start) 71 | start 72 | ;; 73 | stop) 74 | stop 75 | ;; 76 | status) 77 | status -p $FLOWVISOR_PIDFILE 78 | ;; 79 | restart|reload) 80 | restart 81 | ;; 82 | condrestart) 83 | [ -f /var/lock/subsys/$NAME ] && restart || : 84 | ;; 85 | *) 86 | echo $"Usage: $0 {start|stop|status|restart}" 87 | exit 1 88 | ;; 89 | esac 90 | 91 | exit $? 92 | -------------------------------------------------------------------------------- /utilities/jsonrpc/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | Copyright (c) 2007 Jan-Klaas Kollhof 4 | 5 | This file is part of jsonrpc. 6 | 7 | jsonrpc is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU Lesser General Public License as published by 9 | the Free Software Foundation; either version 2.1 of the License, or 10 | (at your option) any later version. 11 | 12 | This software is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public License 18 | along with this software; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | """ 21 | 22 | from jsonrpc.proxy import ServiceProxy, JSONRPCException, JSONParam 23 | from jsonrpc.serviceHandler import ServiceMethod, ServiceHandler, ServiceMethodNotFound, ServiceException 24 | from jsonrpc.cgiwrapper import handleCGI 25 | from jsonrpc.modpywrapper import handler 26 | -------------------------------------------------------------------------------- /utilities/jsonrpc/cgiwrapper.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | from jsonrpc import ServiceHandler 3 | 4 | class CGIServiceHandler(ServiceHandler): 5 | def __init__(self, service): 6 | if service == None: 7 | import __main__ as service 8 | 9 | ServiceHandler.__init__(self, service) 10 | 11 | def handleRequest(self, fin=None, fout=None, env=None): 12 | if fin==None: 13 | fin = sys.stdin 14 | if fout==None: 15 | fout = sys.stdout 16 | if env == None: 17 | env = os.environ 18 | 19 | try: 20 | contLen=int(env['CONTENT_LENGTH']) 21 | data = fin.read(contLen) 22 | except Exception, e: 23 | data = "" 24 | 25 | resultData = ServiceHandler.handleRequest(self, data) 26 | 27 | response = "Content-Type: text/plain\n" 28 | response += "Content-Length: %d\n\n" % len(resultData) 29 | response += resultData 30 | 31 | #on windows all \n are converted to \r\n if stdout is a terminal and is not set to binary mode :( 32 | #this will then cause an incorrect Content-length. 33 | #I have only experienced this problem with apache on Win so far. 34 | if sys.platform == "win32": 35 | try: 36 | import msvcrt 37 | msvcrt.setmode(fout.fileno(), os.O_BINARY) 38 | except: 39 | pass 40 | #put out the response 41 | fout.write(response) 42 | fout.flush() 43 | 44 | def handleCGI(service=None, fin=None, fout=None, env=None): 45 | CGIServiceHandler(service).handleRequest(fin, fout, env) -------------------------------------------------------------------------------- /utilities/jsonrpc/modpywrapper.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | from jsonrpc import ServiceHandler, ServiceException 3 | 4 | 5 | class ServiceImplementaionNotFound(ServiceException): 6 | pass 7 | 8 | 9 | class ModPyServiceHandler(ServiceHandler): 10 | def __init__(self, req): 11 | self.req = req 12 | ServiceHandler.__init__(self, None) 13 | 14 | 15 | def findServiceEndpoint(self, name): 16 | req = self.req 17 | 18 | (modulePath, fileName) = os.path.split(req.filename) 19 | (moduleName, ext) = os.path.splitext(fileName) 20 | 21 | if not os.path.exists(os.path.join(modulePath, moduleName + ".py")): 22 | raise ServiceImplementaionNotFound() 23 | else: 24 | if not modulePath in sys.path: 25 | sys.path.insert(0, modulePath) 26 | 27 | from mod_python import apache 28 | module = apache.import_module(moduleName, log=1) 29 | 30 | if hasattr(module, "service"): 31 | self.service = module.service 32 | elif hasattr(module, "Service"): 33 | self.service = module.Service() 34 | else: 35 | self.service = module 36 | 37 | return ServiceHandler.findServiceEndpoint(self, name) 38 | 39 | 40 | def handleRequest(self, data): 41 | self.req.content_type = "text/plain" 42 | data = self.req.read() 43 | resultData = ServiceHandler.handleRequest(self, data) 44 | self.req.write(resultData) 45 | self.req.flush() 46 | 47 | def handler(req): 48 | from mod_python import apache 49 | ModPyServiceHandler(req).handleRequest(req) 50 | return apache.OK 51 | 52 | 53 | -------------------------------------------------------------------------------- /utilities/mrtg/fvSliceStats2mrtg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### usage: fvSliceStats 4 | 5 | SED=/bin/sed 6 | GREP=/bin/grep 7 | FVCTL=/var/local/bin/fvctl 8 | 9 | slice=$1 10 | dpid=$2 11 | 12 | host=`hostname` 13 | uptime=`uptime | sed -e 's/, .*$//'` 14 | 15 | stats=`$FVCTL --passwd-file=/mrtg/.fvp getSliceStats $slice 2> /dev/null` 16 | 17 | if [ $? -ne 0 ]; then exit 255; fi 18 | 19 | switchstats=`echo $stats | $GREP $dpid | $GREP ,PACKET_IN` 20 | 21 | if [ $? -ne 0 ]; then exit 254; fi 22 | 23 | packetIn=`echo $switchstats | $SED -e 's/^.*PACKET_IN=//' -e 's/,.*$//'` 24 | 25 | outstats=`echo $switchstats | $GREP ,PACKET_OUT` 26 | 27 | if [ $? -eq 0 ]; then 28 | packetOut=`echo $outstats | $SED -e 's/^.*PACKET_OUT=//' -e 's/,.*$//' -e 's/ ---.*$//'` 29 | else 30 | packetOut=0 31 | fi 32 | 33 | echo $packetIn 34 | echo $packetOut 35 | echo $uptime 36 | echo $host 37 | -------------------------------------------------------------------------------- /utilities/mrtg/fvSwitchStats2mrtg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ### usage: fvSwitchStats 4 | 5 | SED=/bin/sed 6 | GREP=/bin/grep 7 | FVCTL=/var/local/bin/fvctl 8 | 9 | dpid=$1 10 | 11 | host=`hostname` 12 | uptime=`uptime | sed -e 's/, .*$//'` 13 | 14 | stats=`$FVCTL --passwd-file=/mrtg/.fvp getSwitchStats $dpid 2> /dev/null` 15 | 16 | if [ $? -ne 0 ]; then exit 255; fi 17 | 18 | totals=`echo $stats | $GREP Total` 19 | 20 | packetIn=`echo $totals | $SED -e 's/^.*PACKET_IN=//' -e 's/,.*$//'` 21 | packetOut=`echo $totals | $SED -e 's/^.*PACKET_OUT=//' -e 's/,.*$//'` 22 | 23 | echo $packetIn 24 | echo $packetOut 25 | echo $uptime 26 | echo $host 27 | -------------------------------------------------------------------------------- /utilities/nload/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=nload 2 | CC=gcc 3 | CFLAGS+=-I/usr/include/pcap 4 | PLIBS+=-lpcap 5 | LIBS+=-lpthread 6 | DIR=$(TARGET) 7 | 8 | CFLAGS+=-g -Wall 9 | 10 | 11 | SRC=$(wildcard *.c) 12 | OBJS=$(subst .c,.o,$(SRC)) 13 | TARBALL=$(patsubst %,$(DIR)/%,$(SRC) Makefile README) 14 | 15 | all: $(TARGET) 16 | 17 | $(TARGET): $(OBJS) 18 | $(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) $(PLIBS) 19 | 20 | install: 21 | cp nload /usr/local/sbin/nload 22 | chmod 755 /usr/local/sbin/nload 23 | 24 | clean: 25 | rm -f $(TARGET) $(OBJS) core $(TARGET).tgz 26 | 27 | %.o: %.c 28 | $(CC) $(CFLAGS) -c $< 29 | 30 | tar: $(TARGET).tgz 31 | $(TARGET).tgz: 32 | (cd .. &&tar cpzf $(DIR)/$(TARGET).tgz $(TARBALL)) 33 | 34 | 35 | -------------------------------------------------------------------------------- /utilities/nload/README: -------------------------------------------------------------------------------- 1 | nload: 2 | 3 | Stupid program; sums up all packets that go by that match 4 | given tcpdump-style filter. 5 | 6 | Compile with gmake (sorry, not makefile independent -- could be changed 7 | trivially). 8 | 9 | Requires libpcap. 10 | 11 | 12 | If pcap.h is not in the standard path, add "CFLAGS+=-I/path/to/pcap.h" to 13 | make on the command line. Ditto for "LDFLAGS+=-L/path/to/libpcap.a", 14 | and LIBS for extra libs. 15 | 16 | I.e. 17 | 18 | gmake CFLAGS+=-I/path/to/pcap.h LDFLAGS+=-L/path/to/libpcap.a LIBS+=-lresolv \ 19 | LIBS+=-lnsl 20 | 21 | is needed to compile for solaris. 22 | 23 | This was writen (and looks like :) as an hour long project. If people 24 | enjoy it, and want new functionality, lemme know, and I will see 25 | what I can do. 26 | 27 | - Rob (cira 2001) 28 | . 29 | --------------------------------------------------------------------------------