From e63291850fd0795c5700e25e67e5dee89ba54c5f Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Tue, 1 Dec 2015 05:49:27 -0800 Subject: [PATCH] onos commit hash c2999f30c69e50df905a9d175ef80b3f23a98514 Change-Id: I2bb8562c4942b6d6a6d60b663db2e17540477b81 Signed-off-by: Ashlee Young --- build.sh | 31 +- framework/src/onos/apps/aaa/features.xml | 1 - .../main/java/org/onosproject/aaa/AaaConfig.java | 239 +++ .../main/java/org/onosproject/aaa/AaaManager.java | 562 +++++++ .../org/onosproject/aaa/AaaIntegrationTest.java | 151 ++ .../java/org/onosproject/aaa/AaaManagerTest.java | 258 +++ .../test/java/org/onosproject/aaa/AaaTestBase.java | 224 +++ framework/src/onos/apps/bgprouter/features.xml | 1 - framework/src/onos/apps/cordvtn/pom.xml | 9 + .../main/java/org/onosproject/cordvtn/CordVtn.java | 287 +++- .../java/org/onosproject/cordvtn/CordVtnNode.java | 133 ++ .../onosproject/cordvtn/CordVtnRuleInstaller.java | 231 +++ .../org/onosproject/cordvtn/DestinationInfo.java | 190 +++ .../cordvtn/cli/CordVtnNodeAddCommand.java | 64 + .../cordvtn/cli/CordVtnNodeDeleteCommand.java | 57 + .../cordvtn/cli/CordVtnNodeInitCommand.java | 57 + .../cordvtn/cli/CordVtnNodeListCommand.java | 74 + framework/src/onos/apps/dhcp/app/features.xml | 1 - .../org/onosproject/dhcp/rest/DhcpWebResource.java | 169 ++ .../main/resources/definitions/DhcpConfigGet.json | 26 + .../definitions/DhcpConfigGetAvailable.json | 16 + .../definitions/DhcpConfigGetMappings.json | 16 + .../main/resources/definitions/DhcpConfigPut.json | 17 + .../org/onosproject/mfwd/impl/McastForwarding.java | 2 +- .../olt/src/main/java/org/onosproject/olt/Olt.java | 359 +++++ .../src/onos/apps/openstackswitching/api/pom.xml | 50 + .../openstackswitching/OpenstackNetwork.java | 5 + .../openstackswitching/OpenstackPort.java | 14 +- .../openstackswitching/OpenstackSubnet.java | 16 +- .../OpenstackSwitchingService.java | 43 +- .../openstackswitching/package-info.java | 0 .../src/onos/apps/openstackswitching/app/app.xml | 24 + .../onos/apps/openstackswitching/app/features.xml | 28 + .../src/onos/apps/openstackswitching/app/pom.xml | 137 ++ .../openstackswitching/OpenstackArpHandler.java | 20 +- .../openstackswitching/OpenstackRestHandler.java | 179 +++ .../OpenstackSwitchingConfig.java | 127 ++ .../OpenstackSwitchingManager.java | 374 +++++ .../OpenstackSwitchingRulePopulator.java | 307 ++++ .../openstackswitching/package-info.java | 20 + .../web/OpenstackNetworkCodec.java | 3 + .../web/OpenstackNetworkWebResource.java | 42 +- .../openstackswitching/web/OpenstackPortCodec.java | 5 +- .../web/OpenstackPortWebResource.java | 46 +- .../web/OpenstackSubnetCodec.java | 19 +- .../web/OpenstackSubnetWebResource.java | 47 +- .../openstackswitching/web/package-info.java | 0 .../{ => app}/src/main/webapp/WEB-INF/web.xml | 0 .../onos/apps/openstackswitching/network-cfg.json | 55 + framework/src/onos/apps/openstackswitching/pom.xml | 97 +- .../OpenstackSwitchingManager.java | 471 ------ .../OpenstackSwitchingRulePopulator.java | 227 --- .../org/onosproject/pim/impl/PIMInterfaces.java | 2 +- .../java/org/onosproject/routing/RouteEntry.java | 10 +- .../org/onosproject/routing/RouteEntryTest.java | 22 +- framework/src/onos/apps/sdnip/features.xml | 1 - .../main/java/org/onosproject/sdnip/SdnIpFib.java | 19 +- .../segmentrouting/DefaultRoutingHandler.java | 11 +- .../segmentrouting/RoutingRulePopulator.java | 174 +- .../segmentrouting/SegmentRoutingManager.java | 18 +- .../onosproject/segmentrouting/TunnelHandler.java | 2 +- .../grouphandler/DefaultEdgeGroupHandler.java | 4 +- .../grouphandler/DefaultGroupHandler.java | 117 +- .../grouphandler/DefaultTransitGroupHandler.java | 4 +- framework/src/onos/apps/virtualbng/features.xml | 1 - framework/src/onos/apps/vtn/app/features.xml | 1 - framework/src/onos/apps/vtn/sfcmgr/pom.xml | 67 + .../sfc/forwarder/ServiceFunctionForwarder.java | 43 + .../onosproject/sfc/forwarder/package-info.java | 20 + .../sfc/installer/FlowClassifierInstaller.java | 46 + .../impl/DefaultFlowClassifierInstaller.java | 45 + .../sfc/installer/impl/package-info.java | 20 + .../onosproject/sfc/installer/package-info.java | 20 + .../org/onosproject/sfc/manager/SfcService.java | 70 + .../onosproject/sfc/manager/impl/SfcManager.java | 125 ++ .../onosproject/sfc/manager/impl/package-info.java | 20 + .../org/onosproject/sfc/manager/package-info.java | 20 + .../org/onosproject/vtn/manager/VTNService.java | 70 + .../onosproject/vtn/manager/impl/VTNManager.java | 585 +++++++ .../onosproject/vtn/manager/impl/package-info.java | 20 + .../org/onosproject/vtn/manager/package-info.java | 20 + .../java/org/onosproject/vtn/table/ArpService.java | 44 + .../onosproject/vtn/table/ClassifierService.java | 105 ++ .../org/onosproject/vtn/table/DnatService.java | 46 + .../onosproject/vtn/table/L2ForwardService.java | 97 ++ .../onosproject/vtn/table/L3ForwardService.java | 47 + .../org/onosproject/vtn/table/SnatService.java | 49 + .../vtn/table/impl/ClassifierServiceImpl.java | 196 +++ .../vtn/table/impl/DnatServiceImpl.java | 88 + .../vtn/table/impl/L2ForwardServiceImpl.java | 211 +++ .../vtn/table/impl/L3ForwardServiceImpl.java | 95 ++ .../vtn/table/impl/SnatServiceImpl.java | 90 ++ .../onosproject/vtn/table/impl/package-info.java | 20 + .../org/onosproject/vtn/table/package-info.java | 20 + .../onosproject/vtn/util/DataPathIdGenerator.java | 64 + .../java/org/onosproject/vtn/util/VtnConfig.java | 123 ++ .../java/org/onosproject/vtn/util/VtnData.java | 97 ++ .../org/onosproject/vtn/util/package-info.java | 20 + .../org/onosproject/vtnrsc/DefaultFloatingIp.java | 140 ++ .../java/org/onosproject/vtnrsc/DefaultRouter.java | 146 ++ .../java/org/onosproject/vtnrsc/FloatingIp.java | 94 ++ .../java/org/onosproject/vtnrsc/FloatingIpId.java | 85 + .../org/onosproject/vtnrsc/RouterInterface.java | 119 ++ .../cli/floatingip/FloatingIpCreateCommand.java | 95 ++ .../cli/floatingip/FloatingIpQueryCommand.java | 92 ++ .../cli/floatingip/FloatingIpRemoveCommand.java | 90 ++ .../cli/floatingip/FloatingIpUpdateCommand.java | 103 ++ .../vtnrsc/cli/floatingip/package-info.java | 20 + .../vtnrsc/cli/router/RouterCreateCommand.java | 97 ++ .../vtnrsc/cli/router/RouterQueryCommand.java | 76 + .../vtnrsc/cli/router/RouterRemoveCommand.java | 71 + .../vtnrsc/cli/router/RouterUpdateCommand.java | 99 ++ .../vtnrsc/cli/router/package-info.java | 20 + .../RouterInterfaceCreateCommand.java | 64 + .../RouterInterfaceQueryCommand.java | 56 + .../RouterInterfaceRemoveCommand.java | 50 + .../vtnrsc/cli/routerinterface/package-info.java | 20 + .../org/onosproject/vtnrsc/event/VtnRscEvent.java | 77 + .../vtnrsc/event/VtnRscEventFeedback.java | 123 ++ .../onosproject/vtnrsc/event/VtnRscListener.java | 26 + .../org/onosproject/vtnrsc/event/package-info.java | 20 + .../vtnrsc/floatingip/FloatingIpEvent.java | 60 + .../vtnrsc/floatingip/FloatingIpListener.java | 25 + .../vtnrsc/floatingip/FloatingIpService.java | 108 ++ .../vtnrsc/floatingip/impl/FloatingIpManager.java | 348 ++++ .../vtnrsc/floatingip/impl/package-info.java | 20 + .../vtnrsc/floatingip/package-info.java | 20 + .../flowclassifier/FlowClassifierService.java | 44 +- .../flowclassifier/impl/FlowClassifierManager.java | 55 +- .../org/onosproject/vtnrsc/router/RouterEvent.java | 59 + .../onosproject/vtnrsc/router/RouterListener.java | 25 + .../onosproject/vtnrsc/router/RouterService.java | 90 ++ .../vtnrsc/router/impl/RouterManager.java | 269 ++++ .../vtnrsc/router/impl/package-info.java | 20 + .../onosproject/vtnrsc/router/package-info.java | 20 + .../routerinterface/RouterInterfaceEvent.java | 62 + .../routerinterface/RouterInterfaceListener.java | 27 + .../routerinterface/RouterInterfaceService.java | 80 + .../impl/RouterInterfaceManager.java | 235 +++ .../vtnrsc/routerinterface/impl/package-info.java | 20 + .../vtnrsc/routerinterface/package-info.java | 20 + .../onosproject/vtnrsc/service/VtnRscService.java | 94 ++ .../vtnrsc/service/impl/VtnRscManager.java | 472 ++++++ .../vtnrsc/service/impl/package-info.java | 20 + .../onosproject/vtnrsc/service/package-info.java | 20 + .../vtnrsc/subnet/impl/SubnetManager.java | 42 +- .../resources/OSGI-INF/blueprint/shell-config.xml | 33 + .../onosproject/vtnrsc/AllowedAddressPairTest.java | 75 + .../vtnrsc/DefaultAllocationPoolTest.java | 66 + .../vtnrsc/DefaultFlowClassifierTest.java | 143 ++ .../onosproject/vtnrsc/DefaultHostRouteTest.java | 66 + .../vtnrsc/DefaultNeutronNetworkTest.java | 77 + .../onosproject/vtnrsc/DefaultPortChainTest.java | 134 ++ .../vtnrsc/DefaultPortPairGroupTest.java | 112 ++ .../onosproject/vtnrsc/DefaultPortPairTest.java | 97 ++ .../onosproject/vtnrsc/DefaultVirtualPortTest.java | 132 ++ .../java/org/onosproject/vtnrsc/FixedIpTest.java | 70 + .../onosproject/vtnrsc/FlowClassifierIdTest.java | 68 + .../onosproject/vtnrsc/PhysicalNetworkTest.java | 64 + .../org/onosproject/vtnrsc/PortChainIdTest.java | 65 + .../onosproject/vtnrsc/PortPairGroupIdTest.java | 66 + .../org/onosproject/vtnrsc/PortPairIdTest.java | 64 + .../org/onosproject/vtnrsc/RouterGatewayTest.java | 79 + .../java/org/onosproject/vtnrsc/RouterIdTest.java | 62 + .../org/onosproject/vtnrsc/SecurityGroupTest.java | 65 + .../org/onosproject/vtnrsc/SegmentationIdTest.java | 63 + .../java/org/onosproject/vtnrsc/SubnetIdTest.java | 63 + .../java/org/onosproject/vtnrsc/TenantIdTest.java | 63 + .../onosproject/vtnrsc/TenantNetworkIdTest.java | 63 + .../org/onosproject/vtnrsc/VirtualPortIdTest.java | 65 + .../vtnrsc/floatingip/DefaultFloatingIpTest.java | 125 ++ .../vtnrsc/floatingip/FloatingIpIdTest.java | 64 + .../impl/FlowClassifierManagerTest.java | 146 ++ .../portchain/impl/PortChainManagerTest.java | 155 ++ .../vtnrsc/portpair/impl/PortPairManagerTest.java | 126 ++ .../impl/PortPairGroupManagerTest.java | 140 ++ .../vtnrsc/router/DefaultRouterTest.java | 114 ++ .../vtnrsc/router/RouterInterfaceTest.java | 97 ++ .../util/VtnEventuallyConsistentMapAdapter.java | 114 ++ .../util/VtnEventuallyConsistentMapTest.java | 242 +++ .../vtnrsc/util/VtnStorageServiceAdapter.java | 65 + .../vtnrsc/util/VtnStorageServiceTest.java | 25 + .../vtnweb/resources/FloatingIpWebResource.java | 285 ++++ .../resources/FlowClassifierWebResource.java | 38 +- .../vtnweb/resources/RouterWebResource.java | 447 ++++++ .../vtnweb/resources/TenantNetworkWebResource.java | 139 +- .../onosproject/vtnweb/web/FloatingIpCodec.java | 98 ++ .../org/onosproject/vtnweb/web/RouterCodec.java | 91 ++ .../vtnweb/web/RouterGatewayInfoCodec.java | 39 + .../vtn/vtnweb/src/main/webapp/WEB-INF/web.xml | 2 + .../resources/FlowClassifierResourceTest.java | 296 ++++ .../vtnweb/resources/PortPairResourceTest.java | 232 +++ .../vtnweb/resources/VtnResourceTest.java | 54 + .../vtnweb/web/FlowClassifierCodecTest.java | 98 ++ .../vtnweb/resources/post-FlowClassifier.json | 14 + .../vtnweb/resources/post-PortPair.json | 9 + .../org/onosproject/vtnweb/web/flowClassifier.json | 11 + .../src/onos/apps/xos-integration/features.xml | 1 - .../xosintegration/OnosXosIntegrationManager.java | 545 +++++++ .../bgp/controller/{BGPCfg.java => BgpCfg.java} | 12 +- .../onosproject/bgp/controller/BgpConnectPeer.java | 28 + .../{BGPController.java => BgpController.java} | 41 +- .../org/onosproject/bgp/controller/BgpDpid.java | 130 ++ .../bgp/controller/{BGPId.java => BgpId.java} | 18 +- .../bgp/controller/BgpLinkListener.java | 35 + .../onosproject/bgp/controller/BgpLocalRib.java | 60 + .../bgp/controller/BgpNodeListener.java | 35 + .../{BGPPacketStats.java => BgpPacketStats.java} | 2 +- .../bgp/controller/{BGPPeer.java => BgpPeer.java} | 22 +- .../{BGPPeerCfg.java => BgpPeerCfg.java} | 2 +- .../onosproject/bgp/controller/BgpPeerManager.java | 8 +- .../onosproject/bgp/controller/BgpSessionInfo.java | 70 + ...PParseException.java => BgpParseException.java} | 12 +- .../{BGPFactories.java => BgpFactories.java} | 32 +- .../protocol/{BGPFactory.java => BgpFactory.java} | 12 +- .../{BGPKeepaliveMsg.java => BgpKeepaliveMsg.java} | 16 +- .../protocol/{BGPLSNlri.java => BgpLSNlri.java} | 10 +- .../onosproject/bgpio/protocol/BgpLinkLsNlri.java | 6 +- .../protocol/{BGPMessage.java => BgpMessage.java} | 20 +- ...BGPMessageReader.java => BgpMessageReader.java} | 10 +- ...BGPMessageWriter.java => BgpMessageWriter.java} | 8 +- .../{BGPNodeLSNlri.java => BgpNodeLSNlri.java} | 6 +- ...otificationMsg.java => BgpNotificationMsg.java} | 8 +- .../protocol/{BGPOpenMsg.java => BgpOpenMsg.java} | 24 +- .../{BGPPrefixLSNlri.java => BgpPrefixLSNlri.java} | 8 +- .../bgpio/protocol/{BGPType.java => BgpType.java} | 4 +- .../onosproject/bgpio/protocol/BgpUpdateMsg.java | 2 +- .../protocol/{BGPVersion.java => BgpVersion.java} | 4 +- .../org/onosproject/bgpio/protocol/Writeable.java | 6 +- ...kLSIdentifier.java => BgpLinkLSIdentifier.java} | 118 +- .../protocol/linkstate/BgpLinkLsNlriVer4.java | 210 +++ ...eLSIdentifier.java => BgpNodeLSIdentifier.java} | 39 +- ...PNodeLSNlriVer4.java => BgpNodeLSNlriVer4.java} | 52 +- ...SNlriVer4.java => BgpPrefixIPv4LSNlriVer4.java} | 52 +- ...SIdentifier.java => BgpPrefixLSIdentifier.java} | 113 +- .../bgpio/protocol/linkstate/NodeDescriptors.java | 77 +- .../protocol/linkstate/PathAttrNlriDetails.java | 135 ++ .../linkstate/PathAttrNlriDetailsLocalRib.java | 122 ++ .../bgpio/protocol/ver4/BGPFactoryVer4.java | 58 - .../bgpio/protocol/ver4/BgpFactoryVer4.java | 58 + ...paliveMsgVer4.java => BgpKeepaliveMsgVer4.java} | 56 +- .../{BGPMessageVer4.java => BgpMessageVer4.java} | 56 +- ...ionMsgVer4.java => BgpNotificationMsgVer4.java} | 76 +- .../{BGPOpenMsgVer4.java => BgpOpenMsgVer4.java} | 130 +- .../bgpio/protocol/ver4/BgpPathAttributes.java | 36 +- .../bgpio/protocol/ver4/BgpUpdateMsgVer4.java | 72 +- .../org/onosproject/bgpio/types/AreaIDTlv.java | 14 +- .../java/org/onosproject/bgpio/types/As4Path.java | 22 +- .../java/org/onosproject/bgpio/types/AsPath.java | 22 +- .../bgpio/types/AutonomousSystemTlv.java | 14 +- .../types/{BGPErrorType.java => BgpErrorType.java} | 4 +- .../bgpio/types/{BGPHeader.java => BgpHeader.java} | 12 +- ...SIdentifierTlv.java => BgpLSIdentifierTlv.java} | 58 +- .../types/{BGPValueType.java => BgpValueType.java} | 10 +- .../bgpio/types/FourOctetAsNumCapabilityTlv.java | 8 +- .../bgpio/types/IPReachabilityInformationTlv.java | 18 +- .../onosproject/bgpio/types/IPv4AddressTlv.java | 27 +- .../onosproject/bgpio/types/IPv6AddressTlv.java | 27 +- .../onosproject/bgpio/types/IsIsNonPseudonode.java | 27 +- .../onosproject/bgpio/types/IsIsPseudonode.java | 72 +- .../bgpio/types/LinkLocalRemoteIdentifiersTlv.java | 19 +- .../bgpio/types/LinkStateAttributes.java | 314 ++++ .../org/onosproject/bgpio/types/LocalPref.java | 18 +- .../main/java/org/onosproject/bgpio/types/Med.java | 18 +- .../org/onosproject/bgpio/types/MpReachNlri.java | 50 +- .../org/onosproject/bgpio/types/MpUnReachNlri.java | 52 +- .../types/MultiProtocolExtnCapabilityTlv.java | 10 +- .../java/org/onosproject/bgpio/types/NextHop.java | 20 +- .../onosproject/bgpio/types/OSPFNonPseudonode.java | 15 +- .../onosproject/bgpio/types/OSPFPseudonode.java | 19 +- .../onosproject/bgpio/types/OSPFRouteTypeTlv.java | 39 +- .../java/org/onosproject/bgpio/types/Origin.java | 20 +- .../bgpio/types/RouteDistinguisher.java | 19 +- .../bgpio/types/attr/BgpAttrNodeFlagBitTlv.java | 22 +- .../bgpio/types/attr/BgpAttrNodeIsIsAreaId.java | 136 ++ .../types/attr/BgpAttrNodeMultiTopologyId.java | 43 +- .../bgpio/types/attr/BgpAttrNodeName.java | 135 ++ .../bgpio/types/attr/BgpAttrOpaqueNode.java | 138 ++ .../bgpio/types/attr/BgpAttrRouterIdV4.java | 22 +- .../bgpio/types/attr/BgpAttrRouterIdV6.java | 22 +- .../bgpio/types/attr/BgpLinkAttrIgpMetric.java | 22 +- .../types/attr/BgpLinkAttrIsIsAdminstGrp.java | 22 +- .../types/attr/BgpLinkAttrMaxLinkBandwidth.java | 22 +- .../types/attr/BgpLinkAttrMplsProtocolMask.java | 22 +- .../bgpio/types/attr/BgpLinkAttrName.java | 22 +- .../bgpio/types/attr/BgpLinkAttrOpaqLnkAttrib.java | 22 +- .../types/attr/BgpLinkAttrProtectionType.java | 22 +- .../bgpio/types/attr/BgpLinkAttrSrlg.java | 136 ++ .../types/attr/BgpLinkAttrTeDefaultMetric.java | 22 +- .../attr/BgpLinkAttrUnRsrvdLinkBandwidth.java | 163 ++ .../bgpio/types/attr/BgpPrefixAttrExtRouteTag.java | 145 ++ .../bgpio/types/attr/BgpPrefixAttrIgpFlags.java | 22 +- .../bgpio/types/attr/BgpPrefixAttrMetric.java | 22 +- .../bgpio/types/attr/BgpPrefixAttrOpaqueData.java | 21 +- .../bgpio/types/attr/BgpPrefixAttrOspfFwdAddr.java | 22 +- .../bgpio/types/attr/BgpPrefixAttrRouteTag.java | 22 +- .../org/onosproject/bgpio/util/Validation.java | 14 +- ...paliveMsgTest.java => BgpKeepaliveMsgTest.java} | 16 +- .../bgpio/protocol/BgpNotificationMsgTest.java | 70 +- .../{BGPOpenMsgTest.java => BgpOpenMsgTest.java} | 94 +- .../org/onosproject/bgpio/types/AreaIdTest.java | 38 - ...dentifierTest.java => BgpLSIdentifierTest.java} | 8 +- .../bgpio/types/IsIsNonPseudonodeTest.java | 39 + .../bgpio/types/IsIsPseudonodeTest.java | 26 +- .../org/onosproject/bgpio/types/LocalPrefTest.java | 8 +- .../java/org/onosproject/bgpio/types/MedTest.java | 8 +- .../attr/BgpLinkAttrMaxLinkBandwidthTest.java | 43 + .../bgpio/types/attr/BgpLinkAttrNameTest.java | 38 + .../types/attr/BgpLinkAttrOpaqLnkAttribTest.java | 41 + .../types/attr/BgpLinkAttrTeDefaultMetricTest.java | 40 + .../attr/BgpLinkAttrUnRsrvdLinkBandwidthTest.java | 56 + .../types/attr/BgpPrefixAttrOpaqueDataTest.java | 41 + .../types/attr/BgpPrefixAttrRouteTagTest.java | 54 + .../onosproject/bgp/controller/impl/AdjRibIn.java | 132 ++ .../bgp/controller/impl/BGPPeerImpl.java | 161 -- ...PChannelHandler.java => BgpChannelHandler.java} | 294 ++-- .../impl/{BGPConfig.java => BgpConfig.java} | 56 +- .../bgp/controller/impl/BgpConnectPeerImpl.java | 133 ++ ...PControllerImpl.java => BgpControllerImpl.java} | 84 +- ...PKeepAliveTimer.java => BgpKeepAliveTimer.java} | 8 +- ...PMessageDecoder.java => BgpMessageDecoder.java} | 20 +- ...PMessageEncoder.java => BgpMessageEncoder.java} | 10 +- ...acketStatsImpl.java => BgpPacketStatsImpl.java} | 6 +- .../{BGPPeerConfig.java => BgpPeerConfig.java} | 6 +- .../bgp/controller/impl/BgpPeerImpl.java | 297 ++++ ...ipelineFactory.java => BgpPipelineFactory.java} | 14 +- .../bgp/controller/impl/BgpSelectionAlgo.java | 242 +++ .../bgp/controller/impl/BgpSessionInfoImpl.java | 93 ++ .../bgp/controller/impl/Controller.java | 35 +- .../bgp/controller/impl/VpnAdjRibIn.java | 209 +++ .../org/onosproject/bgp/BgpControllerImplTest.java | 300 ++++ .../onosproject/bgp/BgpPeerChannelHandlerTest.java | 107 ++ .../onosproject/bgp/BgpPeerFrameDecoderTest.java | 168 ++ .../controller/impl/BgpSelectionAlgoTest.java | 595 +++++++ .../cli/net/ConnectivityIntentCommand.java | 42 +- .../onosproject/cli/net/EncapTypeCompleter.java | 28 + .../resources/OSGI-INF/blueprint/shell-config.xml | 5 + .../org/onosproject/net/EncapsulationType.java | 30 + .../java/org/onosproject/net/TributarySlot.java | 73 + ...solver.java => ExtensionTreatmentResolver.java} | 8 +- .../onosproject/net/behaviour/TunnelConfig.java | 1 + .../java/org/onosproject/net/config/Config.java | 20 + .../net/config/basics/BasicFeatureConfig.java | 54 + .../net/flow/DefaultTrafficSelector.java | 7 +- .../net/flow/DefaultTrafficTreatment.java | 4 +- .../org/onosproject/net/flow/TrafficSelector.java | 8 + .../org/onosproject/net/flow/TrafficTreatment.java | 4 +- .../net/flow/criteria/ArpOpCriterion.java | 78 + .../onosproject/net/flow/criteria/Criteria.java | 32 +- .../onosproject/net/flow/criteria/Criterion.java | 90 +- .../net/flow/criteria/MplsTcCriterion.java | 75 + .../net/flow/criteria/TcpFlagsCriterion.java | 75 + ...uction.java => AbstractExtensionTreatment.java} | 2 +- ...ionInstruction.java => ExtensionTreatment.java} | 4 +- ...ensionType.java => ExtensionTreatmentType.java} | 26 +- .../net/flow/instructions/Instructions.java | 18 +- .../flowobjective/DefaultForwardingObjective.java | 48 + .../net/flowobjective/DefaultNextObjective.java | 65 + .../net/flowobjective/NextObjective.java | 55 +- .../onosproject/net/flowobjective/Objective.java | 25 +- .../org/onosproject/net/group/DefaultGroupKey.java | 17 + .../onosproject/net/intent/HostToHostIntent.java | 2 + .../net/intent/constraint/BandwidthConstraint.java | 12 +- .../intent/constraint/EncapsulationConstraint.java | 83 + .../net/intent/constraint/LambdaConstraint.java | 8 +- .../net/newresource/ResourceAdminService.java | 38 +- .../onosproject/net/newresource/ResourcePath.java | 19 + .../resource/link/DefaultLinkResourceRequest.java | 2 +- .../org/onosproject/net/config/ConfigTest.java | 141 ++ .../net/flow/criteria/CriteriaTest.java | 149 +- .../net/intent/LinkCollectionIntentTest.java | 4 +- .../intent/constraint/ConstraintObjectsTest.java | 30 +- .../org/onosproject/codec/impl/CodecManager.java | 2 + .../codec/impl/DecodeConstraintCodecHelper.java | 6 +- .../codec/impl/DecodeCriterionCodecHelper.java | 23 +- .../codec/impl/EncodeConstraintCodecHelper.java | 4 +- .../codec/impl/EncodeCriterionCodecHelper.java | 10 +- .../org/onosproject/codec/impl/FlowEntryCodec.java | 1 + .../codec/impl/PortStatisticsCodec.java | 51 + .../codec/impl/ConstraintCodecTest.java | 4 +- .../codec/impl/CriterionJsonMatcher.java | 4 +- .../onosproject/codec/impl/IntentCodecTest.java | 6 +- .../onosproject/codec/impl/IntentJsonMatcher.java | 4 +- .../org/onosproject/codec/impl/criteria-flow.json | 2 +- .../onosproject/codec/impl/instructions-flow.json | 2 +- .../onosproject/app/impl/ApplicationManager.java | 16 +- .../flowobjective/impl/FlowObjectiveManager.java | 31 +- .../org/onosproject/net/host/impl/HostMonitor.java | 4 +- .../OpticalConnectivityIntentCompiler.java | 1 + .../newresource/impl/ResourceDeviceListener.java | 64 +- .../net/newresource/impl/ResourceLinkListener.java | 9 +- .../net/newresource/impl/ResourceManager.java | 18 +- .../compiler/PointToPointIntentCompilerTest.java | 11 +- .../messaging/impl/NettyMessagingManager.java | 3 +- .../config/impl/DistributedNetworkConfigStore.java | 4 +- .../store/group/impl/DistributedGroupStore.java | 8 +- .../impl/DistributedMastershipStoreTest.java | 286 ---- .../impl/HazelcastLinkResourceStoreTest.java | 227 --- .../persistence/impl/PersistenceManager.java | 4 +- .../ExtensionInstructionSerializer.java | 12 +- .../store/serializers/KryoNamespaces.java | 7 +- .../store/serializers/KryoSerializerTest.java | 5 +- framework/src/onos/docs/external.xml | 8 +- framework/src/onos/docs/internal.xml | 7 +- framework/src/onos/drivers/features.xml | 1 - ...va => NiciraExtensionTreatmentInterpreter.java} | 48 +- .../driver/extensions/NiciraResubmit.java | 107 ++ .../driver/extensions/NiciraSetNshSpi.java | 104 ++ .../driver/extensions/NiciraSetTunnelDst.java | 10 +- .../driver/handshaker/OFOpticalSwitch13.java | 11 +- .../handshaker/OfOpticalSwitchImplLinc13.java | 95 +- .../driver/netconf/NetconfControllerConfig.java | 89 ++ .../driver/netconf/XmlConfigParser.java | 126 ++ .../onosproject/driver/netconf/package-info.java | 20 + .../driver/ovsdb/OvsdbControllerConfig.java | 3 +- .../driver/ovsdb/OvsdbTunnelConfig.java | 4 +- .../driver/pipeline/CpqdOFDPA2Pipeline.java | 89 ++ .../driver/pipeline/OFDPA2Pipeline.java | 818 +++++++--- .../onosproject/driver/pipeline/OltPipeline.java | 238 +++ .../onosproject/driver/pipeline/SpringOpenTTP.java | 328 ++-- .../drivers/src/main/resources/onos-drivers.xml | 13 +- .../org/onosproject/driver/netconf/controllers.xml | 36 + .../driver/netconf/XmlConfigParserTest.java | 80 + .../org/onosproject/driver/netconf/testConfig.xml | 60 + framework/src/onos/features/features.xml | 3 +- .../incubator/rpc/RemoteServiceContext.java | 40 + .../rpc/RemoteServiceContextProvider.java | 38 + .../rpc/RemoteServiceContextProviderService.java | 28 + .../incubator/rpc/RemoteServiceDirectory.java | 40 + .../rpc/RemoteServiceProviderRegistry.java | 30 + .../onosproject/incubator/rpc/package-info.java | 20 + framework/src/onos/incubator/pom.xml | 1 + framework/src/onos/incubator/rpc-grpc/features.xml | 37 + framework/src/onos/incubator/rpc-grpc/pom.xml | 269 ++++ .../grpc/DeviceProviderRegistryClientProxy.java | 77 + .../rpc/grpc/DeviceProviderServiceClientProxy.java | 295 ++++ .../incubator/rpc/grpc/GrpcDeviceUtils.java | 381 +++++ .../rpc/grpc/GrpcRemoteServiceContext.java | 75 + .../rpc/grpc/GrpcRemoteServiceProvider.java | 119 ++ .../rpc/grpc/GrpcRemoteServiceServer.java | 385 +++++ .../incubator/rpc/grpc/package-info.java | 20 + .../incubator/rpc-grpc/src/main/proto/Device.proto | 131 ++ .../incubator/rpc-grpc/src/main/proto/Port.proto | 40 + .../incubator/rpc/grpc/GrpcRemoteServiceTest.java | 398 +++++ framework/src/onos/incubator/rpc/pom.xml | 135 ++ .../rpc/impl/AbstractProviderRegistry.java | 73 + .../rpc/impl/LocalRemoteServiceProvider.java | 124 ++ .../incubator/rpc/impl/RemoteServiceManager.java | 80 + .../incubator/rpc/impl/package-info.java | 20 + .../rpc/impl/RemoteServiceManagerTest.java | 71 + .../impl/DistributedLabelResourceStore.java | 33 +- .../store/tunnel/impl/DistributedTunnelStore.java | 5 +- framework/src/onos/pom.xml | 40 +- framework/src/onos/protocols/netconf/api/pom.xml | 45 + .../org/onosproject/netconf/NetconfController.java | 84 + .../org/onosproject/netconf/NetconfDevice.java | 51 + .../org/onosproject/netconf/NetconfDeviceInfo.java | 173 ++ .../onosproject/netconf/NetconfDeviceListener.java | 37 + .../org/onosproject/netconf/NetconfSession.java | 129 ++ .../java/org/onosproject/netconf/package-info.java | 20 + framework/src/onos/protocols/netconf/ctl/pom.xml | 91 ++ .../netconf/ctl/NetconfControllerImpl.java | 143 ++ .../onosproject/netconf/ctl/NetconfDeviceImpl.java | 66 + .../netconf/ctl/NetconfSessionImpl.java | 396 +++++ .../org/onosproject/netconf/ctl/package-info.java | 20 + framework/src/onos/protocols/netconf/pom.xml | 83 + framework/src/onos/protocols/netconf/rfc/pom.xml | 30 + .../main/java/org/onosproject/netconf/rfc/Foo.java | 7 + .../org/onosproject/netconf/rfc/package-info.java | 20 + framework/src/onos/protocols/openflow/api/pom.xml | 93 ++ .../controller/DefaultOpenFlowPacketContext.java | 182 +++ .../org/onosproject/openflow/controller/Dpid.java | 132 ++ .../controller/ExtensionTreatmentInterpreter.java | 58 + .../openflow/controller/OpenFlowController.java | 130 ++ .../openflow/controller/OpenFlowEventListener.java | 33 + .../openflow/controller/OpenFlowOpticalSwitch.java | 23 + .../openflow/controller/OpenFlowPacketContext.java | 90 ++ .../openflow/controller/OpenFlowSwitch.java | 160 ++ .../controller/OpenFlowSwitchListener.java | 58 + .../openflow/controller/PacketListener.java | 29 + .../openflow/controller/PortDescPropertyType.java | 39 + .../onosproject/openflow/controller/RoleState.java | 40 + .../openflow/controller/ThirdPartyMessage.java | 74 + .../openflow/controller/WithTypedPorts.java | 45 + .../controller/driver/AbstractOpenFlowSwitch.java | 493 ++++++ .../openflow/controller/driver/OpenFlowAgent.java | 102 ++ .../controller/driver/OpenFlowSwitchDriver.java | 221 +++ .../driver/OpenFlowSwitchDriverFactory.java | 39 + .../openflow/controller/driver/RoleHandler.java | 114 ++ .../openflow/controller/driver/RoleRecvStatus.java | 52 + .../openflow/controller/driver/RoleReplyInfo.java | 48 + .../SwitchDriverSubHandshakeAlreadyStarted.java | 29 + .../driver/SwitchDriverSubHandshakeCompleted.java | 34 + .../driver/SwitchDriverSubHandshakeException.java | 41 + .../driver/SwitchDriverSubHandshakeNotStarted.java | 30 + .../SwitchDriverSubHandshakeStateException.java | 30 + .../controller/driver/SwitchStateException.java | 49 + .../openflow/controller/driver/package-info.java | 20 + .../openflow/controller/package-info.java | 20 + .../controller/OpenflowControllerAdapter.java | 89 ++ framework/src/onos/protocols/openflow/ctl/pom.xml | 65 + .../openflow/controller/impl/Controller.java | 328 ++++ .../controller/impl/HandshakeTimeoutException.java | 28 + .../controller/impl/HandshakeTimeoutHandler.java | 93 ++ .../openflow/controller/impl/OFChannelHandler.java | 1320 +++++++++++++++ .../openflow/controller/impl/OFMessageDecoder.java | 55 + .../openflow/controller/impl/OFMessageEncoder.java | 59 + .../controller/impl/OpenFlowControllerImpl.java | 633 ++++++++ .../controller/impl/OpenflowPipelineFactory.java | 93 ++ .../openflow/controller/impl/RoleManager.java | 406 +++++ .../openflow/controller/impl/package-info.java | 20 + .../org/onosproject/openflow/ChannelAdapter.java | 159 ++ .../openflow/ChannelHandlerContextAdapter.java | 77 + .../org/onosproject/openflow/DriverAdapter.java | 104 ++ .../onosproject/openflow/DriverServiceAdapter.java | 59 + .../openflow/ExecutorServiceAdapter.java | 99 ++ .../onosproject/openflow/MockOfFeaturesReply.java | 81 + .../org/onosproject/openflow/MockOfPacketIn.java | 84 + .../org/onosproject/openflow/MockOfPortStatus.java | 45 + .../openflow/OFDescStatsReplyAdapter.java | 97 ++ .../org/onosproject/openflow/OfMessageAdapter.java | 62 + .../openflow/OpenFlowSwitchListenerAdapter.java | 77 + .../openflow/OpenflowSwitchDriverAdapter.java | 302 ++++ .../openflow/controller/impl/ControllerTest.java | 219 +++ .../controller/impl/OFMessageDecoderTest.java | 84 + .../controller/impl/OFMessageEncoderTest.java | 90 ++ .../impl/OpenFlowControllerImplPacketsTest.java | 167 ++ .../impl/OpenFlowControllerImplTest.java | 283 ++++ .../openflow/controller/impl/RoleManagerTest.java | 130 ++ .../drivers/OFSwitchImplSpringOpenTTPDellOSR.java | 65 + framework/src/onos/protocols/openflow/pom.xml | 86 + .../src/onos/{ => protocols}/ovsdb/api/pom.xml | 0 .../ovsdb/controller/DefaultEventSubject.java | 0 .../onosproject/ovsdb/controller/EventSubject.java | 0 .../onosproject/ovsdb/controller/OvsdbBridge.java | 0 .../ovsdb/controller/OvsdbBridgeName.java | 0 .../ovsdb/controller/OvsdbClientService.java | 1 + .../ovsdb/controller/OvsdbConstant.java | 0 .../ovsdb/controller/OvsdbController.java | 0 .../ovsdb/controller/OvsdbDatapathId.java | 0 .../onosproject/ovsdb/controller/OvsdbEvent.java | 0 .../ovsdb/controller/OvsdbEventListener.java | 0 .../ovsdb/controller/OvsdbEventSubject.java | 0 .../onosproject/ovsdb/controller/OvsdbIfaceId.java | 0 .../onosproject/ovsdb/controller/OvsdbNodeId.java | 0 .../ovsdb/controller/OvsdbNodeListener.java | 0 .../onosproject/ovsdb/controller/OvsdbPort.java | 0 .../ovsdb/controller/OvsdbPortName.java | 0 .../ovsdb/controller/OvsdbPortNumber.java | 0 .../ovsdb/controller/OvsdbPortType.java | 0 .../ovsdb/controller/OvsdbRowStore.java | 0 .../onosproject/ovsdb/controller/OvsdbStore.java | 0 .../ovsdb/controller/OvsdbTableStore.java | 0 .../onosproject/ovsdb/controller/OvsdbTunnel.java | 0 .../ovsdb/controller/OvsdbTunnelName.java | 0 .../controller/driver/DefaultOvsdbClient.java | 7 + .../ovsdb/controller/driver/OvsdbAgent.java | 0 .../controller/driver/OvsdbProviderService.java | 0 .../ovsdb/controller/driver/package-info.java | 0 .../onosproject/ovsdb/controller/package-info.java | 0 .../driver/OvsdbClientServiceAdapter.java | 0 .../controller/driver/OvsdbControllerAdapter.java | 0 .../src/onos/{ => protocols}/ovsdb/ctl/pom.xml | 0 .../controller/impl/ChannelConnectionListener.java | 0 .../ovsdb/controller/impl/Controller.java | 0 .../ovsdb/controller/impl/MessageDecoder.java | 0 .../ovsdb/controller/impl/OvsdbControllerImpl.java | 0 .../ovsdb/controller/impl/OvsdbJsonRpcHandler.java | 0 .../ovsdb/controller/impl/package-info.java | 0 framework/src/onos/{ => protocols}/ovsdb/pom.xml | 0 .../src/onos/{ => protocols}/ovsdb/rfc/pom.xml | 0 .../rfc/exception/AbnormalJsonNodeException.java | 0 .../ovsdb/rfc/exception/BridgeCreateException.java | 53 + .../exception/ColumnSchemaNotFoundException.java | 0 .../exception/TableSchemaNotFoundException.java | 0 .../ovsdb/rfc/exception/UnsupportedException.java | 0 .../rfc/exception/VersionMismatchException.java | 0 .../ovsdb/rfc/exception/package-info.java | 0 .../onosproject/ovsdb/rfc/jsonrpc/Callback.java | 0 .../ovsdb/rfc/jsonrpc/JsonReadContext.java | 0 .../ovsdb/rfc/jsonrpc/JsonRpcRequest.java | 0 .../ovsdb/rfc/jsonrpc/JsonRpcResponse.java | 0 .../onosproject/ovsdb/rfc/jsonrpc/OvsdbRPC.java | 0 .../ovsdb/rfc/jsonrpc/package-info.java | 0 .../ovsdb/rfc/message/MonitorRequest.java | 0 .../ovsdb/rfc/message/MonitorSelect.java | 0 .../ovsdb/rfc/message/OperationResult.java | 0 .../onosproject/ovsdb/rfc/message/RowUpdate.java | 0 .../onosproject/ovsdb/rfc/message/TableUpdate.java | 0 .../ovsdb/rfc/message/TableUpdates.java | 0 .../ovsdb/rfc/message/UpdateNotification.java | 0 .../ovsdb/rfc/message/package-info.java | 0 .../org/onosproject/ovsdb/rfc/notation/Column.java | 0 .../onosproject/ovsdb/rfc/notation/Condition.java | 0 .../onosproject/ovsdb/rfc/notation/Mutation.java | 0 .../onosproject/ovsdb/rfc/notation/OvsdbMap.java | 0 .../onosproject/ovsdb/rfc/notation/OvsdbSet.java | 0 .../ovsdb/rfc/notation/RefTableRow.java | 0 .../org/onosproject/ovsdb/rfc/notation/Row.java | 0 .../org/onosproject/ovsdb/rfc/notation/UUID.java | 0 .../rfc/notation/json/ConditionSerializer.java | 0 .../rfc/notation/json/MutationSerializer.java | 0 .../rfc/notation/json/OvsdbMapSerializer.java | 0 .../rfc/notation/json/OvsdbSetSerializer.java | 0 .../ovsdb/rfc/notation/json/UUIDConverter.java | 0 .../ovsdb/rfc/notation/json/UUIDSerializer.java | 0 .../notation/json/UpdateNotificationConverter.java | 0 .../ovsdb/rfc/notation/json/package-info.java | 0 .../ovsdb/rfc/notation/package-info.java | 0 .../onosproject/ovsdb/rfc/operations/Abort.java | 0 .../onosproject/ovsdb/rfc/operations/Assert.java | 0 .../onosproject/ovsdb/rfc/operations/Comment.java | 0 .../onosproject/ovsdb/rfc/operations/Commit.java | 0 .../onosproject/ovsdb/rfc/operations/Delete.java | 0 .../onosproject/ovsdb/rfc/operations/Insert.java | 0 .../onosproject/ovsdb/rfc/operations/Mutate.java | 0 .../ovsdb/rfc/operations/Operation.java | 0 .../onosproject/ovsdb/rfc/operations/Select.java | 0 .../onosproject/ovsdb/rfc/operations/Update.java | 0 .../ovsdb/rfc/operations/package-info.java | 0 .../onosproject/ovsdb/rfc/schema/ColumnSchema.java | 0 .../ovsdb/rfc/schema/DatabaseSchema.java | 0 .../onosproject/ovsdb/rfc/schema/TableSchema.java | 0 .../onosproject/ovsdb/rfc/schema/package-info.java | 0 .../ovsdb/rfc/schema/type/AtomicColumnType.java | 0 .../ovsdb/rfc/schema/type/BaseType.java | 0 .../ovsdb/rfc/schema/type/BaseTypeFactory.java | 0 .../ovsdb/rfc/schema/type/BooleanBaseType.java | 0 .../ovsdb/rfc/schema/type/ColumnType.java | 0 .../ovsdb/rfc/schema/type/ColumnTypeFactory.java | 0 .../ovsdb/rfc/schema/type/IntegerBaseType.java | 0 .../ovsdb/rfc/schema/type/KeyValuedColumnType.java | 0 .../ovsdb/rfc/schema/type/RealBaseType.java | 0 .../ovsdb/rfc/schema/type/StringBaseType.java | 0 .../ovsdb/rfc/schema/type/UuidBaseType.java | 0 .../ovsdb/rfc/schema/type/package-info.java | 0 .../org/onosproject/ovsdb/rfc/table/Bridge.java | 0 .../onosproject/ovsdb/rfc/table/Controller.java | 0 .../ovsdb/rfc/table/FlowSampleCollectorSet.java | 0 .../org/onosproject/ovsdb/rfc/table/FlowTable.java | 0 .../org/onosproject/ovsdb/rfc/table/Interface.java | 0 .../org/onosproject/ovsdb/rfc/table/Ipfix.java | 0 .../org/onosproject/ovsdb/rfc/table/Manager.java | 0 .../org/onosproject/ovsdb/rfc/table/Mirror.java | 0 .../org/onosproject/ovsdb/rfc/table/Netflow.java | 0 .../onosproject/ovsdb/rfc/table/OpenVSwitch.java | 0 .../onosproject/ovsdb/rfc/table/OvsdbTable.java | 0 .../java/org/onosproject/ovsdb/rfc/table/Port.java | 0 .../java/org/onosproject/ovsdb/rfc/table/Qos.java | 0 .../org/onosproject/ovsdb/rfc/table/Queue.java | 0 .../org/onosproject/ovsdb/rfc/table/Sflow.java | 0 .../java/org/onosproject/ovsdb/rfc/table/Ssl.java | 0 .../ovsdb/rfc/table/TableGenerator.java | 0 .../onosproject/ovsdb/rfc/table/VersionNum.java | 0 .../onosproject/ovsdb/rfc/table/package-info.java | 0 .../tableservice/AbstractOvsdbTableService.java | 0 .../ovsdb/rfc/tableservice/ColumnDescription.java | 0 .../ovsdb/rfc/tableservice/OvsdbTableService.java | 0 .../ovsdb/rfc/tableservice/TableDescription.java | 0 .../ovsdb/rfc/tableservice/package-info.java | 0 .../onosproject/ovsdb/rfc/utils/ConditionUtil.java | 0 .../onosproject/ovsdb/rfc/utils/FromJsonUtil.java | 0 .../ovsdb/rfc/utils/JsonRpcReaderUtil.java | 0 .../ovsdb/rfc/utils/JsonRpcWriterUtil.java | 0 .../onosproject/ovsdb/rfc/utils/MutationUtil.java | 0 .../ovsdb/rfc/utils/ObjectMapperUtil.java | 0 .../org/onosproject/ovsdb/rfc/utils/ParamUtil.java | 0 .../ovsdb/rfc/utils/StringEncoderUtil.java | 0 .../ovsdb/rfc/utils/TransValueUtil.java | 0 .../onosproject/ovsdb/rfc/utils/VersionUtil.java | 0 .../onosproject/ovsdb/rfc/utils/package-info.java | 0 framework/src/onos/protocols/pcep/api/pom.xml | 99 ++ .../org/onosproject/pcep/controller/PccId.java | 120 ++ .../onosproject/pcep/controller/PcepClient.java | 110 ++ .../pcep/controller/PcepClientController.java | 93 ++ .../pcep/controller/PcepClientListener.java | 36 + .../pcep/controller/PcepEventListener.java | 31 + .../pcep/controller/PcepPacketStats.java | 50 + .../pcep/controller/driver/PcepAgent.java | 63 + .../pcep/controller/driver/PcepClientDriver.java | 110 ++ .../controller/driver/PcepClientDriverFactory.java | 38 + .../pcep/controller/driver/package-info.java | 20 + .../onosproject/pcep/controller/package-info.java | 20 + framework/src/onos/protocols/pcep/ctl/pom.xml | 65 + .../pcep/controller/impl/Controller.java | 188 +++ .../pcep/controller/impl/PcepChannelHandler.java | 652 ++++++++ .../controller/impl/PcepClientControllerImpl.java | 222 +++ .../pcep/controller/impl/PcepClientImpl.java | 220 +++ .../pcep/controller/impl/PcepMessageDecoder.java | 68 + .../pcep/controller/impl/PcepMessageEncoder.java | 58 + .../pcep/controller/impl/PcepPacketStatsImpl.java | 105 ++ .../pcep/controller/impl/PcepPipelineFactory.java | 66 + .../pcep/controller/impl/package-info.java | 20 + framework/src/onos/protocols/pcep/pcepio/pom.xml | 77 + .../pcepio/exceptions/PcepParseException.java | 92 ++ .../exceptions/PcepTunnelAttributeException.java | 60 + .../pcepio/exceptions/package-info.java | 20 + .../pcepio/protocol/PcInitiatedLspRequest.java | 185 +++ .../onosproject/pcepio/protocol/PcepAttribute.java | 166 ++ .../pcepio/protocol/PcepBandwidthObject.java | 109 ++ .../onosproject/pcepio/protocol/PcepCloseMsg.java | 143 ++ .../pcepio/protocol/PcepEndPointsObject.java | 139 ++ .../onosproject/pcepio/protocol/PcepEroObject.java | 112 ++ .../org/onosproject/pcepio/protocol/PcepError.java | 136 ++ .../onosproject/pcepio/protocol/PcepErrorInfo.java | 93 ++ .../onosproject/pcepio/protocol/PcepErrorMsg.java | 109 ++ .../pcepio/protocol/PcepErrorObject.java | 169 ++ .../onosproject/pcepio/protocol/PcepFactories.java | 98 ++ .../onosproject/pcepio/protocol/PcepFactory.java | 255 +++ .../onosproject/pcepio/protocol/PcepFecObject.java | 49 + .../pcepio/protocol/PcepFecObjectIPv4.java | 104 ++ .../protocol/PcepFecObjectIPv4Adjacency.java | 133 ++ .../PcepFecObjectIPv4UnnumberedAdjacency.java | 191 +++ .../pcepio/protocol/PcepFecObjectIPv6.java | 104 ++ .../protocol/PcepFecObjectIPv6Adjacency.java | 133 ++ .../pcepio/protocol/PcepInitiateMsg.java | 81 + .../pcepio/protocol/PcepInterLayerObject.java | 137 ++ .../onosproject/pcepio/protocol/PcepIroObject.java | 110 ++ .../pcepio/protocol/PcepKeepaliveMsg.java | 49 + .../pcepio/protocol/PcepLabelObject.java | 171 ++ .../pcepio/protocol/PcepLabelRange.java | 65 + .../pcepio/protocol/PcepLabelRangeObject.java | 182 +++ .../pcepio/protocol/PcepLabelRangeResvMsg.java | 79 + .../pcepio/protocol/PcepLabelUpdate.java | 108 ++ .../pcepio/protocol/PcepLabelUpdateMsg.java | 81 + .../onosproject/pcepio/protocol/PcepLspObject.java | 286 ++++ .../pcepio/protocol/PcepLspaObject.java | 286 ++++ .../onosproject/pcepio/protocol/PcepMessage.java | 67 + .../pcepio/protocol/PcepMessageReader.java | 36 + .../pcepio/protocol/PcepMessageWriter.java | 35 + .../pcepio/protocol/PcepMetricObject.java | 225 +++ .../onosproject/pcepio/protocol/PcepMsgPath.java | 117 ++ .../org/onosproject/pcepio/protocol/PcepNai.java | 40 + .../onosproject/pcepio/protocol/PcepObject.java | 30 + .../onosproject/pcepio/protocol/PcepOpenMsg.java | 73 + .../pcepio/protocol/PcepOpenObject.java | 221 +++ .../onosproject/pcepio/protocol/PcepRPObject.java | 256 +++ .../onosproject/pcepio/protocol/PcepReportMsg.java | 81 + .../onosproject/pcepio/protocol/PcepRroObject.java | 111 ++ .../onosproject/pcepio/protocol/PcepSrpObject.java | 171 ++ .../pcepio/protocol/PcepStateReport.java | 207 +++ .../onosproject/pcepio/protocol/PcepTEObject.java | 241 +++ .../pcepio/protocol/PcepTEReportMsg.java | 81 + .../org/onosproject/pcepio/protocol/PcepType.java | 49 + .../onosproject/pcepio/protocol/PcepUpdateMsg.java | 81 + .../pcepio/protocol/PcepUpdateRequest.java | 126 ++ .../onosproject/pcepio/protocol/PcepVersion.java | 46 + .../org/onosproject/pcepio/protocol/Writeable.java | 35 + .../onosproject/pcepio/protocol/package-info.java | 20 + .../protocol/ver1/PcInitiatedLspRequestVer1.java | 291 ++++ .../pcepio/protocol/ver1/PcepAttributeVer1.java | 431 +++++ .../protocol/ver1/PcepBandwidthObjectVer1.java | 233 +++ .../pcepio/protocol/ver1/PcepCloseMsgVer1.java | 351 ++++ .../protocol/ver1/PcepEndPointsObjectVer1.java | 256 +++ .../pcepio/protocol/ver1/PcepEroObjectVer1.java | 407 +++++ .../pcepio/protocol/ver1/PcepErrorInfoVer1.java | 204 +++ .../pcepio/protocol/ver1/PcepErrorMsgVer1.java | 383 +++++ .../pcepio/protocol/ver1/PcepErrorObjectVer1.java | 341 ++++ .../pcepio/protocol/ver1/PcepErrorVer1.java | 399 +++++ .../pcepio/protocol/ver1/PcepFactoryVer1.java | 226 +++ .../ver1/PcepFecObjectIPv4AdjacencyVer1.java | 253 +++ .../PcepFecObjectIPv4UnnumberedAdjacencyVer1.java | 334 ++++ .../protocol/ver1/PcepFecObjectIPv4Ver1.java | 217 +++ .../ver1/PcepFecObjectIPv6AdjacencyVer1.java | 249 +++ .../protocol/ver1/PcepFecObjectIPv6Ver1.java | 220 +++ .../pcepio/protocol/ver1/PcepInitiateMsgVer1.java | 332 ++++ .../protocol/ver1/PcepInterLayerObjectVer1.java | 263 +++ .../pcepio/protocol/ver1/PcepIroObjectVer1.java | 299 ++++ .../pcepio/protocol/ver1/PcepKeepaliveMsgVer1.java | 154 ++ .../pcepio/protocol/ver1/PcepLabelObjectVer1.java | 370 +++++ .../protocol/ver1/PcepLabelRangeObjectVer1.java | 377 +++++ .../protocol/ver1/PcepLabelRangeResvMsgVer1.java | 198 +++ .../pcepio/protocol/ver1/PcepLabelRangeVer1.java | 168 ++ .../protocol/ver1/PcepLabelUpdateMsgVer1.java | 239 +++ .../pcepio/protocol/ver1/PcepLabelUpdateVer1.java | 356 +++++ .../pcepio/protocol/ver1/PcepLspObjectVer1.java | 575 +++++++ .../pcepio/protocol/ver1/PcepLspaObjectVer1.java | 529 ++++++ .../pcepio/protocol/ver1/PcepMessageVer1.java | 132 ++ .../pcepio/protocol/ver1/PcepMetricObjectVer1.java | 376 +++++ .../pcepio/protocol/ver1/PcepMsgPathVer1.java | 187 +++ .../pcepio/protocol/ver1/PcepOpenMsgVer1.java | 204 +++ .../pcepio/protocol/ver1/PcepOpenObjectVer1.java | 491 ++++++ .../pcepio/protocol/ver1/PcepRPObjectVer1.java | 445 ++++++ .../pcepio/protocol/ver1/PcepReportMsgVer1.java | 309 ++++ .../pcepio/protocol/ver1/PcepRroObjectVer1.java | 345 ++++ .../pcepio/protocol/ver1/PcepSrpObjectVer1.java | 392 +++++ .../pcepio/protocol/ver1/PcepStateReportVer1.java | 421 +++++ .../pcepio/protocol/ver1/PcepTEObjectVer1.java | 506 ++++++ .../pcepio/protocol/ver1/PcepTEReportMsgVer1.java | 225 +++ .../pcepio/protocol/ver1/PcepUpdateMsgVer1.java | 300 ++++ .../protocol/ver1/PcepUpdateRequestVer1.java | 199 +++ .../pcepio/protocol/ver1/package-info.java | 20 + .../pcepio/types/AdministrativeGroupTlv.java | 136 ++ .../pcepio/types/AutonomousSystemTlv.java | 136 ++ .../pcepio/types/BGPLSidentifierTlv.java | 136 ++ .../pcepio/types/ErrorObjListWithOpen.java | 160 ++ .../pcepio/types/GmplsCapabilityTlv.java | 138 ++ .../org/onosproject/pcepio/types/IGPMetricTlv.java | 150 ++ .../pcepio/types/IPv4InterfaceAddressTlv.java | 137 ++ .../pcepio/types/IPv4NeighborAddressTlv.java | 137 ++ .../onosproject/pcepio/types/IPv4SubObject.java | 180 +++ .../pcepio/types/IPv4TERouterIdOfLocalNodeTlv.java | 136 ++ .../types/IPv4TERouterIdOfRemoteNodeTlv.java | 137 ++ .../pcepio/types/IPv6InterfaceAddressTlv.java | 181 +++ .../pcepio/types/IPv6NeighborAddressTlv.java | 179 +++ .../onosproject/pcepio/types/IPv6SubObject.java | 222 +++ .../pcepio/types/IPv6TERouterIdofLocalNodeTlv.java | 179 +++ .../types/IPv6TERouterIdofRemoteNodeTlv.java | 171 ++ .../pcepio/types/ISISAreaIdentifierTlv.java | 155 ++ .../onosproject/pcepio/types/LabelSubObject.java | 171 ++ .../types/LinkLocalRemoteIdentifiersTlv.java | 155 ++ .../org/onosproject/pcepio/types/LinkNameTlv.java | 155 ++ .../pcepio/types/LinkProtectionTypeTlv.java | 142 ++ .../pcepio/types/LocalTENodeDescriptorsTlv.java | 246 +++ .../pcepio/types/MPLSProtocolMaskTlv.java | 200 +++ .../pcepio/types/MaximumLinkBandwidthTlv.java | 137 ++ .../types/MaximumReservableLinkBandwidthTlv.java | 136 ++ .../pcepio/types/NexthopIPv4addressTlv.java | 143 ++ .../pcepio/types/NexthopIPv6addressTlv.java | 190 +++ .../pcepio/types/NexthopUnnumberedIPv4IDTlv.java | 163 ++ .../onosproject/pcepio/types/NodeFlagBitsTlv.java | 233 +++ .../org/onosproject/pcepio/types/NodeNameTlv.java | 154 ++ .../onosproject/pcepio/types/OSPFareaIDsubTlv.java | 135 ++ .../pcepio/types/OpaqueLinkAttributeTlv.java | 155 ++ .../pcepio/types/OpaqueNodeAttributeTlv.java | 154 ++ .../onosproject/pcepio/types/PathKeySubObject.java | 159 ++ .../onosproject/pcepio/types/PathSetupTypeTlv.java | 164 ++ .../pcepio/types/PceccCapabilityTlv.java | 194 +++ .../pcepio/types/PcepErrorDetailInfo.java | 83 + .../pcepio/types/PcepLabelDbVerTlv.java | 137 ++ .../pcepio/types/PcepLabelDownload.java | 105 ++ .../org/onosproject/pcepio/types/PcepLabelMap.java | 103 ++ .../pcepio/types/PcepNaiIpv4Adjacency.java | 107 ++ .../pcepio/types/PcepNaiIpv4NodeId.java | 99 ++ .../pcepio/types/PcepNaiIpv6Adjacency.java | 113 ++ .../pcepio/types/PcepNaiIpv6NodeId.java | 102 ++ .../types/PcepNaiUnnumberedAdjacencyIpv4.java | 131 ++ .../onosproject/pcepio/types/PcepObjectHeader.java | 224 +++ .../pcepio/types/PcepRsvpErrorSpec.java | 46 + .../pcepio/types/PcepRsvpIpv4ErrorSpec.java | 160 ++ .../pcepio/types/PcepRsvpIpv6ErrorSpec.java | 165 ++ .../pcepio/types/PcepRsvpObjectHeader.java | 161 ++ .../pcepio/types/PcepRsvpSpecObjHeader.java | 156 ++ .../pcepio/types/PcepRsvpUserErrorSpec.java | 220 +++ .../onosproject/pcepio/types/PcepValueType.java | 55 + .../pcepio/types/RemoteTENodeDescriptorsTlv.java | 250 +++ .../onosproject/pcepio/types/RouterIDSubTlv.java | 154 ++ .../pcepio/types/RoutingUniverseTlv.java | 147 ++ .../pcepio/types/SharedRiskLinkGroupTlv.java | 167 ++ .../onosproject/pcepio/types/SrEroSubObject.java | 324 ++++ .../types/StatefulIPv4LspIdentidiersTlv.java | 210 +++ .../pcepio/types/StatefulLspDbVerTlv.java | 142 ++ .../pcepio/types/StatefulLspErrorCodeTlv.java | 142 ++ .../pcepio/types/StatefulPceCapabilityTlv.java | 269 ++++ .../pcepio/types/StatefulRsvpErrorSpecTlv.java | 216 +++ .../pcepio/types/SymbolicPathNameTlv.java | 159 ++ .../pcepio/types/TEDefaultMetricTlv.java | 137 ++ .../pcepio/types/TELinkAttributesTlv.java | 292 ++++ .../pcepio/types/TELinkDescriptorsTlv.java | 251 +++ .../pcepio/types/TENodeAttributesTlv.java | 250 +++ .../onosproject/pcepio/types/TedCapabilityTlv.java | 181 +++ .../pcepio/types/UnreservedBandwidthTlv.java | 136 ++ .../org/onosproject/pcepio/types/package-info.java | 20 + .../java/org/onosproject/pcepio/util/HexDump.java | 56 + .../org/onosproject/pcepio/util/package-info.java | 20 + .../pcepio/protocol/PcepCloseMsgTest.java | 56 + .../pcepio/protocol/PcepErrorMsgTest.java | 735 +++++++++ .../pcepio/protocol/PcepInitiateMsgExtTest.java | 1683 ++++++++++++++++++++ .../pcepio/protocol/PcepInitiateMsgTest.java | 1331 ++++++++++++++++ .../pcepio/protocol/PcepKeepaliveMsgTest.java | 59 + .../pcepio/protocol/PcepLabelUpdateMsgTest.java | 402 +++++ .../pcepio/protocol/PcepOpenMsgTest.java | 558 +++++++ .../pcepio/protocol/PcepReportMsgExtTest.java | 218 +++ .../pcepio/protocol/PcepReportMsgTest.java | 1597 +++++++++++++++++++ .../pcepio/protocol/PcepTEReportMsgTest.java | 1596 +++++++++++++++++++ .../pcepio/protocol/PcepUpdateMsgExtTest.java | 1269 +++++++++++++++ .../pcepio/protocol/PcepUpdateMsgTest.java | 1423 +++++++++++++++++ .../pcepio/types/AdministrativeGroupTlvTest.java | 36 + .../pcepio/types/AutonomousSystemTlvTest.java | 36 + .../pcepio/types/BGPLSidentifierTlvTest.java | 36 + .../pcepio/types/GmplsCapabilityTlvTest.java | 36 + .../onosproject/pcepio/types/IGPMetricTlvTest.java | 38 + .../pcepio/types/IPv4InterfaceAddressTlvTest.java | 37 + .../pcepio/types/IPv4NeighborAddressTlvTest.java | 37 + .../pcepio/types/IPv4SubObjectTest.java | 37 + .../types/IPv4TERouterIdOfLocalNodeTlvTest.java | 37 + .../types/IPv4TERouterIdOfRemoteNodeTlvTest.java | 37 + .../pcepio/types/IPv6InterfaceAddressTlvTest.java | 42 + .../pcepio/types/IPv6NeighborAddressTlvTest.java | 42 + .../pcepio/types/IPv6SubObjectTest.java | 39 + .../types/IPv6TERouterIdofLocalNodeTlvTest.java | 42 + .../types/IPv6TERouterIdofRemoteNodeTlvTest.java | 42 + .../pcepio/types/ISISAreaIdentifierTlvTest.java | 40 + .../pcepio/types/LabelSubObjectTest.java | 37 + .../types/LinkLocalRemoteIdentifiersTlvTest.java | 37 + .../onosproject/pcepio/types/LinkNameTlvTest.java | 39 + .../pcepio/types/LinkProtectionTypeTlvTest.java | 39 + .../types/LocalTENodeDescriptorsTlvTest.java | 50 + .../pcepio/types/MPLSProtocolMaskTlvTest.java | 39 + .../pcepio/types/MaximumLinkBandwidthTlvTest.java | 39 + .../MaximumReservableLinkBandwidthTlvTest.java | 39 + .../pcepio/types/NexthopIPv4addressTlvTest.java | 37 + .../pcepio/types/NexthopIPv6addressTlvTest.java | 41 + .../types/NexthopUnnumberedIPv4IDTlvTest.java | 37 + .../pcepio/types/NodeFlagBitsTlvTest.java | 39 + .../onosproject/pcepio/types/NodeNameTlvTest.java | 39 + .../pcepio/types/OSPFareaIDsubTlvTest.java | 36 + .../pcepio/types/OpaqueLinkAttributeTlvTest.java | 39 + .../pcepio/types/PathKeySubObjectTest.java | 37 + .../pcepio/types/PathSetupTypeTlvTest.java | 34 + .../pcepio/types/PceccCapabilityTlvTest.java | 39 + .../pcepio/types/PcepNaiIpv4AdjacencyTest.java | 36 + .../pcepio/types/PcepNaiIpv4NodeIdTest.java | 34 + .../pcepio/types/PcepNaiIpv6AdjacencyTest.java | 37 + .../pcepio/types/PcepNaiIpv6NodeIdTest.java | 43 + .../types/PcepNaiUnnumberedAdjacencyIpv4Test.java | 49 + .../types/RemoteTENodeDescriptorsTlvTest.java | 52 + .../pcepio/types/RouterIDSubTlvTest.java | 42 + .../pcepio/types/RoutingUniverseTlvTest.java | 35 + .../pcepio/types/SharedRiskLinkGroupTlvTest.java | 41 + .../pcepio/types/SrEroSubObjectTest.java | 59 + .../types/StatefulIPv4LspIdentidiersTlvTest.java | 55 + .../pcepio/types/StatefulLspDbVerTlvTest.java | 35 + .../pcepio/types/StatefulLspErrorCodeTlvTest.java | 31 + .../pcepio/types/StatefulPceCapabilityTlvTest.java | 34 + .../pcepio/types/SymbolicPathNameTlvTest.java | 43 + .../pcepio/types/TEDefaultMetricTlvTest.java | 34 + .../pcepio/types/TELinkAttributesTlvTest.java | 54 + .../pcepio/types/TELinkDescriptorsTlvTest.java | 52 + .../pcepio/types/TENodeAttributesTlvTest.java | 54 + .../pcepio/types/TedCapabilityTlvTest.java | 34 + .../pcepio/types/UnreservedBandwidthTlvTest.java | 36 + framework/src/onos/protocols/pcep/pom.xml | 60 + framework/src/onos/protocols/pom.xml | 60 + framework/src/onos/providers/bgp/app/app.xml | 25 + framework/src/onos/providers/bgp/app/features.xml | 26 + framework/src/onos/providers/bgp/app/pom.xml | 52 + framework/src/onos/providers/bgp/pom.xml | 58 + framework/src/onos/providers/bgp/topology/pom.xml | 33 + .../bgp/topology/impl/BgpTopologyProvider.java | 125 ++ .../provider/bgp/topology/impl/package-info.java | 19 + .../bgp/topology/impl/BgpTopologyProviderTest.java | 301 ++++ framework/src/onos/providers/lldp/pom.xml | 4 + .../lldp/impl/LinkDiscoveryFromDevice.java | 31 + .../provider/lldp/impl/LinkDiscoveryFromPort.java | 31 + .../provider/lldp/impl/LldpLinkProvider.java | 760 +++++++++ .../provider/lldp/impl/SuppressionConfig.java | 144 ++ .../provider/lldp/impl/SuppressionRules.java | 43 +- .../provider/lldp/impl/SuppressionRulesStore.java | 174 -- .../provider/lldp/impl/LldpLinkProviderTest.java | 944 +++++++++++ .../provider/lldp/impl/SuppressionConfigTest.java | 71 + .../lldp/impl/SuppressionRulesStoreTest.java | 80 - .../provider/lldp/impl/SuppressionRulesTest.java | 23 +- .../lldp/src/test/resources/lldp_suppression.json | 6 - .../src/onos/providers/netconf/app/features.xml | 1 - .../netconf/device/impl/NetconfProviderConfig.java | 93 ++ .../netconf/flow/impl/NetconfOperation.java | 4 +- framework/src/onos/providers/openflow/base/app.xml | 31 + .../src/onos/providers/openflow/base/features.xml | 31 + framework/src/onos/providers/openflow/base/pom.xml | 71 + .../provider/of/flow/impl/FlowEntryBuilder.java | 18 +- .../provider/of/flow/impl/FlowModBuilder.java | 20 +- .../provider/of/flow/impl/FlowModBuilderVer13.java | 14 +- .../provider/of/group/impl/GroupModBuilder.java | 10 +- .../src/onos/providers/ovsdb/app/features.xml | 1 - framework/src/onos/providers/pcep/app/features.xml | 1 - framework/src/onos/providers/pom.xml | 1 + framework/src/onos/tools/dev/bin/onos-setup-karaf | 2 +- .../config/samples/network-cfg-linkdiscovery.json | 35 + .../tools/package/config/samples/network-cfg.json | 1 + .../org/onosproject/maven/OnosSwaggerMojo.java | 5 +- .../resources/org/onosproject/maven/features.xml | 1 - .../src/onos/tools/test/bin/onos-gen-partitions | 20 +- framework/src/onos/tools/test/cells/jian | 11 + framework/src/onos/tools/test/cells/simon | 11 + .../src/onos/tools/test/configs/netconf-cfg.json | 19 + framework/src/onos/tools/test/topos/metro.py | 217 +++ framework/src/onos/utils/catalyst/pom.xml | 8 +- .../java/org/onlab/catalyst/OnlabCatalyst.java | 7 + .../main/java/org/onlab/catalyst/package-info.java | 4 + .../src/main/java/org/onlab/util/HexString.java | 60 +- .../main/java/org/onlab/netty/DecoderState.java | 1 + .../main/java/org/onlab/netty/MessageDecoder.java | 26 +- .../main/java/org/onlab/netty/MessageEncoder.java | 9 + .../main/java/org/onlab/netty/NettyMessaging.java | 17 +- .../rest/resources/HostsWebResource.java | 24 +- .../rest/resources/IntentsWebResource.java | 6 +- .../rest/resources/StatisticsWebResource.java | 59 + .../main/resources/definitions/Application.json | 80 + .../resources/definitions/ApplicationPost.json | 80 + .../main/resources/definitions/Applications.json | 96 ++ .../src/main/resources/definitions/Cluster.json | 45 + .../main/resources/definitions/ClusterNode.json | 28 + .../main/resources/definitions/ClusterPost.json | 42 + .../src/main/resources/definitions/DeviceGet.json | 77 + .../main/resources/definitions/DeviceGetPorts.json | 132 ++ .../src/main/resources/definitions/DevicesGet.json | 93 ++ .../api/src/main/resources/definitions/Flows.json | 179 +++ .../src/main/resources/definitions/FlowsPost.json | 102 ++ .../api/src/main/resources/definitions/Host.json | 54 + .../src/main/resources/definitions/HostPut.json | 49 + .../api/src/main/resources/definitions/Hosts.json | 70 + .../src/main/resources/definitions/IntentHost.json | 34 + .../main/resources/definitions/IntentPoint.json | 62 + .../src/main/resources/definitions/Intents.json | 60 + .../src/main/resources/definitions/LinksGet.json | 72 + .../src/main/resources/definitions/NetCfgGet.json | 93 ++ .../api/src/main/resources/definitions/Paths.json | 94 ++ .../resources/definitions/StatisticsFlowsLink.json | 54 + .../definitions/StatisticsFlowsTables.json | 76 + .../resources/definitions/StatisticsPorts.json | 107 ++ .../src/main/resources/definitions/Topology.json | 32 + .../resources/definitions/TopologyBroadcast.json | 13 + .../resources/definitions/TopologyCluster.json | 31 + .../resources/definitions/TopologyClusters.json | 48 + .../definitions/TopologyClustersDevices.json | 22 + .../definitions/TopologyInfrastructure.json | 13 + .../resources/org/onosproject/rest/post-flow.json | 2 +- .../java/org/onosproject/ui/impl/UiWebSocket.java | 2 +- framework/src/suricata/ChangeLog | 53 + framework/src/suricata/configure.ac | 2 +- framework/src/suricata/src/Makefile.am | 2 + framework/src/suricata/src/app-layer-dns-common.c | 2 +- framework/src/suricata/src/app-layer-htp.c | 432 ++++- framework/src/suricata/src/app-layer-smtp.c | 7 +- framework/src/suricata/src/app-layer-ssl.c | 101 +- framework/src/suricata/src/app-layer-ssl.h | 6 +- .../src/detect-engine-content-inspection.c | 18 +- .../src/detect-engine-content-inspection.h | 1 + framework/src/suricata/src/detect-engine.c | 441 ++--- framework/src/suricata/src/detect-engine.h | 2 +- framework/src/suricata/src/detect-parse.c | 15 + framework/src/suricata/src/detect.c | 19 +- framework/src/suricata/src/detect.h | 11 + framework/src/suricata/src/log-tlslog.c | 3 + framework/src/suricata/src/output-json-tls.c | 6 + framework/src/suricata/src/output-json.c | 7 +- framework/src/suricata/src/runmode-unittests.c | 1 - framework/src/suricata/src/suricata.c | 19 +- framework/src/suricata/src/suricata.h | 2 +- framework/src/suricata/src/util-base64.c | 19 +- framework/src/suricata/src/util-base64.h | 3 +- framework/src/suricata/src/util-decode-mime.c | 6 +- framework/src/suricata/src/util-error.c | 2 + framework/src/suricata/src/util-error.h | 3 + framework/src/suricata/src/util-logopenfile.c | 4 +- framework/src/suricata/src/util-logopenfile.h | 1 + framework/src/suricata/src/util-lua-tls.c | 41 + framework/src/suricata/src/util-profiling-locks.c | 6 +- framework/src/suricata/src/util-rule-vars.c | 2 +- 1050 files changed, 92621 insertions(+), 4635 deletions(-) create mode 100644 framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaConfig.java create mode 100644 framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaManager.java create mode 100644 framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaIntegrationTest.java create mode 100644 framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaManagerTest.java create mode 100644 framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaTestBase.java create mode 100644 framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnNode.java create mode 100644 framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java create mode 100644 framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DestinationInfo.java create mode 100644 framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeAddCommand.java create mode 100644 framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeDeleteCommand.java create mode 100644 framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeInitCommand.java create mode 100644 framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeListCommand.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGet.json create mode 100644 framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGetAvailable.json create mode 100644 framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGetMappings.json create mode 100644 framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigPut.json create mode 100644 framework/src/onos/apps/olt/src/main/java/org/onosproject/olt/Olt.java create mode 100644 framework/src/onos/apps/openstackswitching/api/pom.xml rename framework/src/onos/apps/openstackswitching/{ => api}/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java (96%) rename framework/src/onos/apps/openstackswitching/{ => api}/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java (94%) rename framework/src/onos/apps/openstackswitching/{ => api}/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java (90%) rename framework/src/onos/apps/openstackswitching/{ => api}/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java (57%) rename framework/src/onos/apps/openstackswitching/{ => api}/src/main/java/org/onosproject/openstackswitching/package-info.java (100%) create mode 100644 framework/src/onos/apps/openstackswitching/app/app.xml create mode 100644 framework/src/onos/apps/openstackswitching/app/features.xml create mode 100644 framework/src/onos/apps/openstackswitching/app/pom.xml rename framework/src/onos/apps/openstackswitching/{ => app}/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java (85%) create mode 100644 framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackRestHandler.java create mode 100644 framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingConfig.java create mode 100644 framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java create mode 100644 framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java create mode 100644 framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/package-info.java rename framework/src/onos/apps/openstackswitching/{ => app}/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java (96%) rename framework/src/onos/apps/openstackswitching/{ => app}/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java (55%) rename framework/src/onos/apps/openstackswitching/{ => app}/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java (97%) rename framework/src/onos/apps/openstackswitching/{ => app}/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java (60%) rename framework/src/onos/apps/openstackswitching/{ => app}/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java (80%) rename framework/src/onos/apps/openstackswitching/{ => app}/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java (54%) rename framework/src/onos/apps/openstackswitching/{ => app}/src/main/java/org/onosproject/openstackswitching/web/package-info.java (100%) rename framework/src/onos/apps/openstackswitching/{ => app}/src/main/webapp/WEB-INF/web.xml (100%) create mode 100644 framework/src/onos/apps/openstackswitching/network-cfg.json delete mode 100644 framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java delete mode 100644 framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java create mode 100644 framework/src/onos/apps/vtn/sfcmgr/pom.xml create mode 100644 framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java create mode 100644 framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/package-info.java create mode 100644 framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/FlowClassifierInstaller.java create mode 100644 framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/DefaultFlowClassifierInstaller.java create mode 100644 framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/package-info.java create mode 100644 framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/package-info.java create mode 100644 framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java create mode 100644 framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java create mode 100644 framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/package-info.java create mode 100644 framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ClassifierService.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/DnatService.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/L2ForwardService.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/L3ForwardService.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/SnatService.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ClassifierServiceImpl.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/DnatServiceImpl.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L2ForwardServiceImpl.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L3ForwardServiceImpl.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/SnatServiceImpl.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/DataPathIdGenerator.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnConfig.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java create mode 100644 framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFloatingIp.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultRouter.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FloatingIp.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FloatingIpId.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterInterface.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpCreateCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpQueryCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpRemoveCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpUpdateCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterCreateCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterQueryCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterRemoveCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterUpdateCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceCreateCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceQueryCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceRemoveCommand.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscListener.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpEvent.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpListener.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpService.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterEvent.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterListener.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterService.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/impl/RouterManager.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/impl/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceEvent.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceListener.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceService.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/impl/RouterInterfaceManager.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/impl/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/AllowedAddressPairTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultAllocationPoolTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultFlowClassifierTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultHostRouteTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultNeutronNetworkTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortChainTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortPairGroupTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortPairTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultVirtualPortTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/FixedIpTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/FlowClassifierIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PhysicalNetworkTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortChainIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortPairGroupIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortPairIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/RouterGatewayTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/RouterIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SecurityGroupTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SegmentationIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SubnetIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/TenantIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/TenantNetworkIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/VirtualPortIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/floatingip/DefaultFloatingIpTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/floatingip/FloatingIpIdTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManagerTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portchain/impl/PortChainManagerTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpair/impl/PortPairManagerTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManagerTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/DefaultRouterTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterInterfaceTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnEventuallyConsistentMapAdapter.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnEventuallyConsistentMapTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnStorageServiceAdapter.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnStorageServiceTest.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FloatingIpWebResource.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/RouterWebResource.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/FloatingIpCodec.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/RouterCodec.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/RouterGatewayInfoCodec.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/VtnResourceTest.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/FlowClassifierCodecTest.java create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-FlowClassifier.json create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPair.json create mode 100644 framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/flowClassifier.json create mode 100644 framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/OnosXosIntegrationManager.java rename framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/{BGPCfg.java => BgpCfg.java} (96%) create mode 100755 framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpConnectPeer.java rename framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/{BGPController.java => BgpController.java} (73%) create mode 100755 framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpDpid.java rename framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/{BGPId.java => BgpId.java} (87%) create mode 100755 framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpLinkListener.java create mode 100755 framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpLocalRib.java create mode 100755 framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpNodeListener.java rename framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/{BGPPacketStats.java => BgpPacketStats.java} (97%) rename framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/{BGPPeer.java => BgpPeer.java} (79%) mode change 100755 => 100644 rename framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/{BGPPeerCfg.java => BgpPeerCfg.java} (99%) create mode 100755 framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpSessionInfo.java rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/exceptions/{BGPParseException.java => BgpParseException.java} (88%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPFactories.java => BgpFactories.java} (65%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPFactory.java => BgpFactory.java} (83%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPKeepaliveMsg.java => BgpKeepaliveMsg.java} (76%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPLSNlri.java => BgpLSNlri.java} (81%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPMessage.java => BgpMessage.java} (76%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPMessageReader.java => BgpMessageReader.java} (78%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPMessageWriter.java => BgpMessageWriter.java} (83%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPNodeLSNlri.java => BgpNodeLSNlri.java} (83%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPNotificationMsg.java => BgpNotificationMsg.java} (90%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPOpenMsg.java => BgpOpenMsg.java} (84%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPPrefixLSNlri.java => BgpPrefixLSNlri.java} (85%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPType.java => BgpType.java} (96%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/{BGPVersion.java => BgpVersion.java} (94%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/{BGPLinkLSIdentifier.java => BgpLinkLSIdentifier.java} (62%) mode change 100755 => 100644 create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLsNlriVer4.java rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/{BGPNodeLSIdentifier.java => BgpNodeLSIdentifier.java} (69%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/{BGPNodeLSNlriVer4.java => BgpNodeLSNlriVer4.java} (78%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/{BGPPrefixIPv4LSNlriVer4.java => BgpPrefixIPv4LSNlriVer4.java} (78%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/{BGPPrefixLSIdentifier.java => BgpPrefixLSIdentifier.java} (60%) create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/PathAttrNlriDetails.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/PathAttrNlriDetailsLocalRib.java delete mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPFactoryVer4.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpFactoryVer4.java rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/{BGPKeepaliveMsgVer4.java => BgpKeepaliveMsgVer4.java} (73%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/{BGPMessageVer4.java => BgpMessageVer4.java} (61%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/{BGPNotificationMsgVer4.java => BgpNotificationMsgVer4.java} (74%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/{BGPOpenMsgVer4.java => BgpOpenMsgVer4.java} (79%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/{BGPErrorType.java => BgpErrorType.java} (97%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/{BGPHeader.java => BgpHeader.java} (94%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/{BGPLSIdentifierTlv.java => BgpLSIdentifierTlv.java} (64%) rename framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/{BGPValueType.java => BgpValueType.java} (85%) mode change 100755 => 100644 mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/FourOctetAsNumCapabilityTlv.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeIsIsAreaId.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeName.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrOpaqueNode.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV4.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV6.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIgpMetric.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMplsProtocolMask.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrName.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrOpaqLnkAttrib.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrProtectionType.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrSrlg.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetric.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrUnRsrvdLinkBandwidth.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrExtRouteTag.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIgpFlags.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrMetric.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueData.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOspfFwdAddr.java mode change 100755 => 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTag.java rename framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/{BGPKeepaliveMsgTest.java => BgpKeepaliveMsgTest.java} (83%) rename framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/{BGPOpenMsgTest.java => BgpOpenMsgTest.java} (81%) rename framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/{BGPLSIdentifierTest.java => BgpLSIdentifierTest.java} (82%) create mode 100644 framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IsIsNonPseudonodeTest.java create mode 100644 framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidthTest.java create mode 100644 framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrNameTest.java create mode 100644 framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrOpaqLnkAttribTest.java create mode 100644 framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetricTest.java create mode 100644 framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrUnRsrvdLinkBandwidthTest.java create mode 100644 framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueDataTest.java create mode 100644 framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTagTest.java create mode 100644 framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/AdjRibIn.java delete mode 100755 framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java rename framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/{BGPChannelHandler.java => BgpChannelHandler.java} (71%) rename framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/{BGPConfig.java => BgpConfig.java} (83%) create mode 100755 framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConnectPeerImpl.java rename framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/{BGPControllerImpl.java => BgpControllerImpl.java} (68%) rename framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/{BGPKeepAliveTimer.java => BgpKeepAliveTimer.java} (89%) rename framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/{BGPMessageDecoder.java => BgpMessageDecoder.java} (75%) rename framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/{BGPMessageEncoder.java => BgpMessageEncoder.java} (87%) rename framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/{BGPPacketStatsImpl.java => BgpPacketStatsImpl.java} (94%) rename framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/{BGPPeerConfig.java => BgpPeerConfig.java} (95%) create mode 100644 framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java rename framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/{BGPPipelineFactory.java => BgpPipelineFactory.java} (85%) create mode 100644 framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java create mode 100755 framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java create mode 100644 framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/VpnAdjRibIn.java create mode 100755 framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java create mode 100755 framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerChannelHandlerTest.java create mode 100755 framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerFrameDecoderTest.java create mode 100644 framework/src/onos/bgp/ctl/src/test/java/org/onosproject/controller/impl/BgpSelectionAlgoTest.java create mode 100644 framework/src/onos/cli/src/main/java/org/onosproject/cli/net/EncapTypeCompleter.java create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/EncapsulationType.java create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/TributarySlot.java rename framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/{ExtensionResolver.java => ExtensionTreatmentResolver.java} (80%) create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicFeatureConfig.java create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpOpCriterion.java create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsTcCriterion.java create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpFlagsCriterion.java rename framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/{AbstractExtensionInstruction.java => AbstractExtensionTreatment.java} (96%) rename framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/{ExtensionInstruction.java => ExtensionTreatment.java} (96%) rename framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/{ExtensionType.java => ExtensionTreatmentType.java} (73%) create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/EncapsulationConstraint.java create mode 100644 framework/src/onos/core/api/src/test/java/org/onosproject/net/config/ConfigTest.java create mode 100644 framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/PortStatisticsCodec.java delete mode 100644 framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/mastership/impl/DistributedMastershipStoreTest.java delete mode 100644 framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/resource/impl/HazelcastLinkResourceStoreTest.java rename framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/{NiciraExtensionInterpreter.java => NiciraExtensionTreatmentInterpreter.java} (56%) create mode 100644 framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmit.java create mode 100644 framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSpi.java create mode 100644 framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/NetconfControllerConfig.java create mode 100644 framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/XmlConfigParser.java create mode 100644 framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/package-info.java create mode 100644 framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java create mode 100644 framework/src/onos/drivers/src/main/resources/org/onosproject/driver/netconf/controllers.xml create mode 100644 framework/src/onos/drivers/src/test/java/org/onosproject/driver/netconf/XmlConfigParserTest.java create mode 100644 framework/src/onos/drivers/src/test/resources/org/onosproject/driver/netconf/testConfig.xml create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContext.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContextProvider.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContextProviderService.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceDirectory.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceProviderRegistry.java create mode 100644 framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/package-info.java create mode 100644 framework/src/onos/incubator/rpc-grpc/features.xml create mode 100644 framework/src/onos/incubator/rpc-grpc/pom.xml create mode 100644 framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderRegistryClientProxy.java create mode 100644 framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderServiceClientProxy.java create mode 100644 framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcDeviceUtils.java create mode 100644 framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceContext.java create mode 100644 framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceProvider.java create mode 100644 framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceServer.java create mode 100644 framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/package-info.java create mode 100644 framework/src/onos/incubator/rpc-grpc/src/main/proto/Device.proto create mode 100644 framework/src/onos/incubator/rpc-grpc/src/main/proto/Port.proto create mode 100644 framework/src/onos/incubator/rpc-grpc/src/test/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceTest.java create mode 100644 framework/src/onos/incubator/rpc/pom.xml create mode 100644 framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/AbstractProviderRegistry.java create mode 100644 framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/LocalRemoteServiceProvider.java create mode 100644 framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/RemoteServiceManager.java create mode 100644 framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/package-info.java create mode 100644 framework/src/onos/incubator/rpc/src/test/java/org/onosproject/incubator/rpc/impl/RemoteServiceManagerTest.java create mode 100644 framework/src/onos/protocols/netconf/api/pom.xml create mode 100644 framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfController.java create mode 100644 framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDevice.java create mode 100644 framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceInfo.java create mode 100644 framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceListener.java create mode 100644 framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java create mode 100644 framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/package-info.java create mode 100644 framework/src/onos/protocols/netconf/ctl/pom.xml create mode 100644 framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java create mode 100644 framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java create mode 100644 framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java create mode 100644 framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/package-info.java create mode 100644 framework/src/onos/protocols/netconf/pom.xml create mode 100644 framework/src/onos/protocols/netconf/rfc/pom.xml create mode 100644 framework/src/onos/protocols/netconf/rfc/src/main/java/org/onosproject/netconf/rfc/Foo.java create mode 100644 framework/src/onos/protocols/netconf/rfc/src/main/java/org/onosproject/netconf/rfc/package-info.java create mode 100644 framework/src/onos/protocols/openflow/api/pom.xml create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/DefaultOpenFlowPacketContext.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/Dpid.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ExtensionTreatmentInterpreter.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowController.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowEventListener.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowOpticalSwitch.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowPacketContext.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitchListener.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/PacketListener.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/PortDescPropertyType.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/RoleState.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ThirdPartyMessage.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/WithTypedPorts.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowAgent.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriverFactory.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleHandler.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleRecvStatus.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleReplyInfo.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeAlreadyStarted.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeCompleted.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeException.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeNotStarted.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeStateException.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchStateException.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/package-info.java create mode 100644 framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/package-info.java create mode 100644 framework/src/onos/protocols/openflow/api/src/test/java/org/onosproject/openflow/controller/OpenflowControllerAdapter.java create mode 100644 framework/src/onos/protocols/openflow/ctl/pom.xml create mode 100644 framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/HandshakeTimeoutException.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/HandshakeTimeoutHandler.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFMessageDecoder.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFMessageEncoder.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenflowPipelineFactory.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/package-info.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelAdapter.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelHandlerContextAdapter.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/DriverAdapter.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/DriverServiceAdapter.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ExecutorServiceAdapter.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfFeaturesReply.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfPacketIn.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfPortStatus.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OFDescStatsReplyAdapter.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OfMessageAdapter.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenFlowSwitchListenerAdapter.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/ControllerTest.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageDecoderTest.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageEncoderTest.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplPacketsTest.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplTest.java create mode 100644 framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java create mode 100644 framework/src/onos/protocols/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplSpringOpenTTPDellOSR.java create mode 100644 framework/src/onos/protocols/openflow/pom.xml rename framework/src/onos/{ => protocols}/ovsdb/api/pom.xml (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/DefaultEventSubject.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/EventSubject.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridge.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridgeName.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java (99%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbDatapathId.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEvent.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventListener.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventSubject.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbIfaceId.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeId.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeListener.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPort.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortName.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortNumber.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortType.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnel.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnelName.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java (99%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbAgent.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbClientServiceAdapter.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbControllerAdapter.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/ctl/pom.xml (100%) rename framework/src/onos/{ => protocols}/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/ChannelConnectionListener.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/MessageDecoder.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbJsonRpcHandler.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/pom.xml (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/pom.xml (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/AbnormalJsonNodeException.java (100%) create mode 100644 framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/BridgeCreateException.java rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/ColumnSchemaNotFoundException.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/TableSchemaNotFoundException.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/UnsupportedException.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/VersionMismatchException.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/Callback.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonReadContext.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcRequest.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcResponse.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/OvsdbRPC.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/MonitorRequest.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/MonitorSelect.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/OperationResult.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/RowUpdate.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/TableUpdate.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/TableUpdates.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/UpdateNotification.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Column.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Condition.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Mutation.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/OvsdbMap.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/OvsdbSet.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/RefTableRow.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Row.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/UUID.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/ConditionSerializer.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/MutationSerializer.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/OvsdbMapSerializer.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/OvsdbSetSerializer.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDConverter.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDSerializer.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UpdateNotificationConverter.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Abort.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Assert.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Comment.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Commit.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Delete.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Insert.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Mutate.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Operation.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Select.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Update.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/ColumnSchema.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/DatabaseSchema.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/TableSchema.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/AtomicColumnType.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseType.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseTypeFactory.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BooleanBaseType.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnType.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnTypeFactory.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/IntegerBaseType.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/KeyValuedColumnType.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/RealBaseType.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/StringBaseType.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/UuidBaseType.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Bridge.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Controller.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/FlowSampleCollectorSet.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/FlowTable.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Ipfix.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Manager.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Mirror.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Netflow.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OpenVSwitch.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Port.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Qos.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Queue.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Sflow.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Ssl.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/TableGenerator.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/ColumnDescription.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/TableDescription.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/package-info.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ConditionUtil.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcWriterUtil.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ObjectMapperUtil.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/StringEncoderUtil.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/TransValueUtil.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/VersionUtil.java (100%) rename framework/src/onos/{ => protocols}/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/package-info.java (100%) create mode 100644 framework/src/onos/protocols/pcep/api/pom.xml create mode 100755 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PccId.java create mode 100755 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java create mode 100644 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientController.java create mode 100755 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientListener.java create mode 100644 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepEventListener.java create mode 100644 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepPacketStats.java create mode 100755 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepAgent.java create mode 100755 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepClientDriver.java create mode 100755 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepClientDriverFactory.java create mode 100644 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/package-info.java create mode 100644 framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/package-info.java create mode 100644 framework/src/onos/protocols/pcep/ctl/pom.xml create mode 100644 framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/Controller.java create mode 100644 framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java create mode 100644 framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java create mode 100644 framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java create mode 100644 framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepMessageDecoder.java create mode 100644 framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepMessageEncoder.java create mode 100644 framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepPacketStatsImpl.java create mode 100644 framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepPipelineFactory.java create mode 100644 framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/package-info.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/pom.xml create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/PcepParseException.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/PcepTunnelAttributeException.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/package-info.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcInitiatedLspRequest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepAttribute.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepCloseMsg.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepEndPointsObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepEroObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepError.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorInfo.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorMsg.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorObject.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFactories.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFactory.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4Adjacency.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4UnnumberedAdjacency.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv6.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv6Adjacency.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepInitiateMsg.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepInterLayerObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepIroObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepKeepaliveMsg.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRange.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRangeObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRangeResvMsg.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelUpdate.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelUpdateMsg.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLspObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLspaObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessage.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessageReader.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessageWriter.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMetricObject.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMsgPath.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepNai.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepObject.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepOpenMsg.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepOpenObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepRPObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepReportMsg.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepRroObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepSrpObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepStateReport.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepTEObject.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepTEReportMsg.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepType.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepUpdateMsg.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepUpdateRequest.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepVersion.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/Writeable.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/package-info.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcInitiatedLspRequestVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepAttributeVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepCloseMsgVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEndPointsObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFactoryVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4AdjacencyVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4UnnumberedAdjacencyVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4Ver1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6AdjacencyVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6Ver1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInitiateMsgVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepIroObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepKeepaliveMsgVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeResvMsgVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelUpdateMsgVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelUpdateVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLspObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLspaObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMessageVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMetricObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMsgPathVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepOpenMsgVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepOpenObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRPObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepReportMsgVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRroObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepSrpObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepStateReportVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEObjectVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEReportMsgVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepUpdateMsgVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepUpdateRequestVer1.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/package-info.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/AdministrativeGroupTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/AutonomousSystemTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/BGPLSidentifierTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/ErrorObjListWithOpen.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/GmplsCapabilityTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IGPMetricTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4InterfaceAddressTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4NeighborAddressTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4SubObject.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4TERouterIdOfLocalNodeTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4TERouterIdOfRemoteNodeTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6InterfaceAddressTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6NeighborAddressTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6SubObject.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6TERouterIdofLocalNodeTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6TERouterIdofRemoteNodeTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/ISISAreaIdentifierTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LabelSubObject.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkLocalRemoteIdentifiersTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkNameTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkProtectionTypeTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LocalTENodeDescriptorsTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MPLSProtocolMaskTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MaximumLinkBandwidthTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MaximumReservableLinkBandwidthTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopIPv4addressTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopIPv6addressTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopUnnumberedIPv4IDTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NodeFlagBitsTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NodeNameTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OSPFareaIDsubTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OpaqueLinkAttributeTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OpaqueNodeAttributeTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathKeySubObject.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathSetupTypeTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PceccCapabilityTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepErrorDetailInfo.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepLabelDbVerTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepLabelDownload.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepLabelMap.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv4Adjacency.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv4NodeId.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv6Adjacency.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv6NodeId.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiUnnumberedAdjacencyIpv4.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepObjectHeader.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpErrorSpec.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpIpv4ErrorSpec.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpIpv6ErrorSpec.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpObjectHeader.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpSpecObjHeader.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpUserErrorSpec.java create mode 100755 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepValueType.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RemoteTENodeDescriptorsTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RouterIDSubTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RoutingUniverseTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SharedRiskLinkGroupTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SrEroSubObject.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulIPv4LspIdentidiersTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulLspDbVerTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulLspErrorCodeTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulPceCapabilityTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulRsvpErrorSpecTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SymbolicPathNameTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TEDefaultMetricTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TELinkAttributesTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TELinkDescriptorsTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TENodeAttributesTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TedCapabilityTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/UnreservedBandwidthTlv.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/package-info.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/util/HexDump.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/util/package-info.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepCloseMsgTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepErrorMsgTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepInitiateMsgExtTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepInitiateMsgTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepKeepaliveMsgTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepLabelUpdateMsgTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepOpenMsgTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepReportMsgExtTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepReportMsgTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepTEReportMsgTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepUpdateMsgExtTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/protocol/PcepUpdateMsgTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/AdministrativeGroupTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/AutonomousSystemTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/BGPLSidentifierTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/GmplsCapabilityTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IGPMetricTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IPv4InterfaceAddressTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IPv4NeighborAddressTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IPv4SubObjectTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IPv4TERouterIdOfLocalNodeTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IPv4TERouterIdOfRemoteNodeTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IPv6InterfaceAddressTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IPv6NeighborAddressTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IPv6SubObjectTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IPv6TERouterIdofLocalNodeTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/IPv6TERouterIdofRemoteNodeTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/ISISAreaIdentifierTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/LabelSubObjectTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/LinkLocalRemoteIdentifiersTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/LinkNameTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/LinkProtectionTypeTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/LocalTENodeDescriptorsTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/MPLSProtocolMaskTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/MaximumLinkBandwidthTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/MaximumReservableLinkBandwidthTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/NexthopIPv4addressTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/NexthopIPv6addressTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/NexthopUnnumberedIPv4IDTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/NodeFlagBitsTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/NodeNameTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/OSPFareaIDsubTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/OpaqueLinkAttributeTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/PathKeySubObjectTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/PathSetupTypeTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/PceccCapabilityTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/PcepNaiIpv4AdjacencyTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/PcepNaiIpv4NodeIdTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/PcepNaiIpv6AdjacencyTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/PcepNaiIpv6NodeIdTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/PcepNaiUnnumberedAdjacencyIpv4Test.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/RemoteTENodeDescriptorsTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/RouterIDSubTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/RoutingUniverseTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/SharedRiskLinkGroupTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/SrEroSubObjectTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/StatefulIPv4LspIdentidiersTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/StatefulLspDbVerTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/StatefulLspErrorCodeTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/StatefulPceCapabilityTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/SymbolicPathNameTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/TEDefaultMetricTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/TELinkAttributesTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/TELinkDescriptorsTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/TENodeAttributesTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/TedCapabilityTlvTest.java create mode 100644 framework/src/onos/protocols/pcep/pcepio/src/test/java/org/onosproject/pcepio/types/UnreservedBandwidthTlvTest.java create mode 100755 framework/src/onos/protocols/pcep/pom.xml create mode 100644 framework/src/onos/protocols/pom.xml create mode 100755 framework/src/onos/providers/bgp/app/app.xml create mode 100755 framework/src/onos/providers/bgp/app/features.xml create mode 100755 framework/src/onos/providers/bgp/app/pom.xml create mode 100755 framework/src/onos/providers/bgp/pom.xml create mode 100755 framework/src/onos/providers/bgp/topology/pom.xml create mode 100755 framework/src/onos/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java create mode 100755 framework/src/onos/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/package-info.java create mode 100755 framework/src/onos/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java create mode 100644 framework/src/onos/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LinkDiscoveryFromDevice.java create mode 100644 framework/src/onos/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LinkDiscoveryFromPort.java create mode 100644 framework/src/onos/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java create mode 100644 framework/src/onos/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionConfig.java delete mode 100644 framework/src/onos/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/SuppressionRulesStore.java create mode 100644 framework/src/onos/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/LldpLinkProviderTest.java create mode 100644 framework/src/onos/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/SuppressionConfigTest.java delete mode 100644 framework/src/onos/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/SuppressionRulesStoreTest.java delete mode 100644 framework/src/onos/providers/lldp/src/test/resources/lldp_suppression.json create mode 100644 framework/src/onos/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfProviderConfig.java create mode 100644 framework/src/onos/providers/openflow/base/app.xml create mode 100644 framework/src/onos/providers/openflow/base/features.xml create mode 100644 framework/src/onos/providers/openflow/base/pom.xml create mode 100644 framework/src/onos/tools/package/config/samples/network-cfg-linkdiscovery.json create mode 100644 framework/src/onos/tools/test/cells/jian create mode 100644 framework/src/onos/tools/test/cells/simon create mode 100644 framework/src/onos/tools/test/configs/netconf-cfg.json create mode 100755 framework/src/onos/tools/test/topos/metro.py create mode 100644 framework/src/onos/utils/catalyst/src/main/java/org/onlab/catalyst/OnlabCatalyst.java create mode 100644 framework/src/onos/utils/catalyst/src/main/java/org/onlab/catalyst/package-info.java create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/Application.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/ApplicationPost.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/Applications.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/Cluster.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/ClusterNode.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/ClusterPost.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/DeviceGet.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/DeviceGetPorts.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/DevicesGet.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/Flows.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/FlowsPost.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/Host.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/HostPut.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/Hosts.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/IntentHost.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/IntentPoint.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/Intents.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/LinksGet.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/NetCfgGet.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/Paths.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/StatisticsFlowsLink.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/StatisticsFlowsTables.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/StatisticsPorts.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/Topology.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/TopologyBroadcast.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/TopologyCluster.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/TopologyClusters.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/TopologyClustersDevices.json create mode 100644 framework/src/onos/web/api/src/main/resources/definitions/TopologyInfrastructure.json diff --git a/build.sh b/build.sh index fc234b5e..42c6940a 100755 --- a/build.sh +++ b/build.sh @@ -20,7 +20,7 @@ ##### Settings ##### VERSION=1.0.7 AUTHOR="Ashlee Young" -MODIFIED="November 23, 2015" +MODIFIED="November 30, 2015" GERRITURL="git clone ssh://im2bz2pee@gerrit.opnfv.org:29418/onosfw" ONOSURL="https://github.com/opennetworkinglab/onos" SURICATAURL="https://github.com/inliniac/suricata" @@ -29,6 +29,7 @@ JAVA_VERSION=1.8 ANT_VERSION=1.9.6 MAVEN_VERSION=3.3.3 KARAF_VERSION=4.0.2 +LIBCAP-NG_VERSION=0.7.7 MODE=$1 ##### End Settings ##### @@ -447,6 +448,32 @@ checkforlibpcap() # Checks whether RPMBUILD is installed } ##### End Check for libpcap ##### +##### Check for libhtp ##### +checkforlibhtp() # Checks whether RPMBUILD is installed +{ + if [ ! -f "$SURICATAROOT/libhtp" ]; then + cd $SURICATAROOT + git clone https://github.com/ironbee/libhtp + fi +} +##### End Check for libhtp ##### + +##### Check for libcap-ng ##### +checkforlibcap-ng() # Checks whether RPMBUILD is installed +{ + if [ ! -f "$SURICATAROOT/libcap-ng-$LIBCAP-NG_VERSION" ]; then + cd $SURICATAROOT + wget http://people.redhat.com/sgrubb/libcap-ng/libcap-ng-$LIBCAP-NG_VERSION.tar.gz + tar xzvf libcap-ng-$LIBCAP-NG_VERSION.tar.gz + rm libcap-ng-$LIBCAP-NG_VERSION.tar.gz + cd libcap-ng-$LIBCAP-NG_VERSION + ./autogen.sh + ./configure --without-python3 + make + fi +} +##### End Check for libcap-ng ##### + ##### Build Suricata ##### buildSuricata() { @@ -477,6 +504,7 @@ buildSuricata() fi fi cd $SURICATAROOT + checkforlibhtp ./autogen.sh ./configure make @@ -501,6 +529,7 @@ buildSuricata() fi fi cd $SURICATAROOT + checkforlibhtp ./autogen.sh ./configure make diff --git a/framework/src/onos/apps/aaa/features.xml b/framework/src/onos/apps/aaa/features.xml index 3825ec5c..e965d41a 100644 --- a/framework/src/onos/apps/aaa/features.xml +++ b/framework/src/onos/apps/aaa/features.xml @@ -15,7 +15,6 @@ ~ limitations under the License. --> - mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features onos-api diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaConfig.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaConfig.java new file mode 100644 index 00000000..db821ca2 --- /dev/null +++ b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaConfig.java @@ -0,0 +1,239 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.aaa; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.config.Config; +import org.onosproject.net.config.basics.BasicElementConfig; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Network config for the AAA app. + */ +public class AaaConfig extends Config { + + private static final String RADIUS_IP = "radiusIp"; + private static final String RADIUS_SERVER_PORT = "1812"; + private static final String RADIUS_MAC = "radiusMac"; + private static final String NAS_IP = "nasIp"; + private static final String NAS_MAC = "nasMac"; + private static final String RADIUS_SECRET = "radiusSecret"; + private static final String RADIUS_SWITCH = "radiusSwitch"; + private static final String RADIUS_PORT = "radiusPort"; + + // RADIUS server IP address + protected static final String DEFAULT_RADIUS_IP = "10.128.10.4"; + + // RADIUS MAC address + protected static final String DEFAULT_RADIUS_MAC = "00:00:00:00:01:10"; + + // NAS IP address + protected static final String DEFAULT_NAS_IP = "10.128.9.244"; + + // NAS MAC address + protected static final String DEFAULT_NAS_MAC = "00:00:00:00:10:01"; + + // RADIUS server shared secret + protected static final String DEFAULT_RADIUS_SECRET = "ONOSecret"; + + // Radius Switch Id + protected static final String DEFAULT_RADIUS_SWITCH = "of:90e2ba82f97791e9"; + + // Radius Port Number + protected static final String DEFAULT_RADIUS_PORT = "129"; + + // Radius Server UDP Port Number + protected static final String DEFAULT_RADIUS_SERVER_PORT = "1812"; + + /** + * Gets the value of a string property, protecting for an empty + * JSON object. + * + * @param name name of the property + * @param defaultValue default value if none has been specified + * @return String value if one os found, default value otherwise + */ + private String getStringProperty(String name, String defaultValue) { + if (object == null) { + return defaultValue; + } + return get(name, defaultValue); + } + + /** + * Returns the NAS ip. + * + * @return ip address or null if not set + */ + public InetAddress nasIp() { + try { + return InetAddress.getByName(getStringProperty(NAS_IP, DEFAULT_NAS_IP)); + } catch (UnknownHostException e) { + return null; + } + } + + /** + * Sets the NAS ip. + * + * @param ip new ip address; null to clear + * @return self + */ + public BasicElementConfig nasIp(String ip) { + return (BasicElementConfig) setOrClear(NAS_IP, ip); + } + + /** + * Returns the RADIUS server ip. + * + * @return ip address or null if not set + */ + public InetAddress radiusIp() { + try { + return InetAddress.getByName(getStringProperty(RADIUS_IP, DEFAULT_RADIUS_IP)); + } catch (UnknownHostException e) { + return null; + } + } + + /** + * Sets the RADIUS server ip. + * + * @param ip new ip address; null to clear + * @return self + */ + public BasicElementConfig radiusIp(String ip) { + return (BasicElementConfig) setOrClear(RADIUS_IP, ip); + } + + /** + * Returns the RADIUS MAC address. + * + * @return mac address or null if not set + */ + public String radiusMac() { + return getStringProperty(RADIUS_MAC, DEFAULT_RADIUS_MAC); + } + + /** + * Sets the RADIUS MAC address. + * + * @param mac new MAC address; null to clear + * @return self + */ + public BasicElementConfig radiusMac(String mac) { + return (BasicElementConfig) setOrClear(RADIUS_MAC, mac); + } + + /** + * Returns the RADIUS MAC address. + * + * @return mac address or null if not set + */ + public String nasMac() { + return getStringProperty(NAS_MAC, DEFAULT_NAS_MAC); + } + + /** + * Sets the RADIUS MAC address. + * + * @param mac new MAC address; null to clear + * @return self + */ + public BasicElementConfig nasMac(String mac) { + return (BasicElementConfig) setOrClear(NAS_MAC, mac); + } + + /** + * Returns the RADIUS secret. + * + * @return radius secret or null if not set + */ + public String radiusSecret() { + return getStringProperty(RADIUS_SECRET, DEFAULT_RADIUS_SECRET); + } + + /** + * Sets the RADIUS secret. + * + * @param secret new MAC address; null to clear + * @return self + */ + public BasicElementConfig radiusSecret(String secret) { + return (BasicElementConfig) setOrClear(RADIUS_SECRET, secret); + } + + /** + * Returns the ID of the RADIUS switch. + * + * @return radius switch ID or null if not set + */ + public String radiusSwitch() { + return getStringProperty(RADIUS_SWITCH, DEFAULT_RADIUS_SWITCH); + } + + /** + * Sets the ID of the RADIUS switch. + * + * @param switchId new RADIUS switch ID; null to clear + * @return self + */ + public BasicElementConfig radiusSwitch(String switchId) { + return (BasicElementConfig) setOrClear(RADIUS_SWITCH, switchId); + } + + /** + * Returns the RADIUS port. + * + * @return radius port or null if not set + */ + public long radiusPort() { + return Integer.parseInt(getStringProperty(RADIUS_PORT, DEFAULT_RADIUS_PORT)); + } + + /** + * Sets the RADIUS port. + * + * @param port new RADIUS port; null to clear + * @return self + */ + public BasicElementConfig radiusPort(long port) { + return (BasicElementConfig) setOrClear(RADIUS_PORT, port); + } + + /** + * Returns the RADIUS server UDP port. + * + * @return radius server UDP port. + */ + public short radiusServerUdpPort() { + return Short.parseShort(getStringProperty(RADIUS_SERVER_PORT, + DEFAULT_RADIUS_SERVER_PORT)); + } + + /** + * Sets the RADIUS port. + * + * @param port new RADIUS UDP port; -1 to clear + * @return self + */ + public BasicElementConfig radiusServerUdpPort(short port) { + return (BasicElementConfig) setOrClear(RADIUS_SERVER_PORT, (long) port); + } + +} diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaManager.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaManager.java new file mode 100644 index 00000000..dd324eee --- /dev/null +++ b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AaaManager.java @@ -0,0 +1,562 @@ +/* + * Copyright 2015 AT&T Foundry + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.aaa; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onlab.packet.DeserializationException; +import org.onlab.packet.EAP; +import org.onlab.packet.EAPOL; +import org.onlab.packet.EthType; +import org.onlab.packet.Ethernet; +import org.onlab.packet.MacAddress; +import org.onlab.packet.RADIUS; +import org.onlab.packet.RADIUSAttribute; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.config.ConfigFactory; +import org.onosproject.net.config.NetworkConfigEvent; +import org.onosproject.net.config.NetworkConfigListener; +import org.onosproject.net.config.NetworkConfigRegistry; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.packet.DefaultOutboundPacket; +import org.onosproject.net.packet.InboundPacket; +import org.onosproject.net.packet.OutboundPacket; +import org.onosproject.net.packet.PacketContext; +import org.onosproject.net.packet.PacketProcessor; +import org.onosproject.net.packet.PacketService; +import org.onosproject.xosintegration.VoltTenantService; +import org.slf4j.Logger; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.nio.ByteBuffer; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; +import static org.onosproject.net.packet.PacketPriority.CONTROL; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * AAA application for ONOS. + */ +@Component(immediate = true) +public class AaaManager { + + // for verbose output + private final Logger log = getLogger(getClass()); + + // a list of our dependencies : + // to register with ONOS as an application - described next + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + // to receive Packet-in events that we'll respond to + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PacketService packetService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VoltTenantService voltTenantService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected NetworkConfigRegistry netCfgService; + + // Parsed RADIUS server addresses + protected InetAddress radiusIpAddress; + protected String radiusMacAddress; + + // NAS IP address + protected InetAddress nasIpAddress; + protected String nasMacAddress; + + // RADIUS server secret + protected String radiusSecret; + + // ID of RADIUS switch + protected String radiusSwitch; + + // RADIUS port number + protected long radiusPort; + + // RADIUS server TCP port number + protected short radiusServerPort; + + // our application-specific event handler + private ReactivePacketProcessor processor = new ReactivePacketProcessor(); + + // our unique identifier + private ApplicationId appId; + + // Socket used for UDP communications with RADIUS server + private DatagramSocket radiusSocket; + + // Executor for RADIUS communication thread + private ExecutorService executor; + + // Configuration properties factory + private final ConfigFactory factory = + new ConfigFactory(APP_SUBJECT_FACTORY, + AaaConfig.class, + "AAA") { + @Override + public AaaConfig createConfig() { + return new AaaConfig(); + } + }; + + // Listener for config changes + private final InternalConfigListener cfgListener = new InternalConfigListener(); + + /** + * Builds an EAPOL packet based on the given parameters. + * + * @param dstMac destination MAC address + * @param srcMac source MAC address + * @param vlan vlan identifier + * @param eapolType EAPOL type + * @param eap EAP payload + * @return Ethernet frame + */ + private static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac, + short vlan, byte eapolType, EAP eap) { + + Ethernet eth = new Ethernet(); + eth.setDestinationMACAddress(dstMac.toBytes()); + eth.setSourceMACAddress(srcMac.toBytes()); + eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort()); + if (vlan != Ethernet.VLAN_UNTAGGED) { + eth.setVlanID(vlan); + } + //eapol header + EAPOL eapol = new EAPOL(); + eapol.setEapolType(eapolType); + eapol.setPacketLength(eap.getLength()); + + //eap part + eapol.setPayload(eap); + + eth.setPayload(eapol); + eth.setPad(true); + return eth; + } + + @Activate + public void activate() { + netCfgService.addListener(cfgListener); + netCfgService.registerConfigFactory(factory); + + // "org.onosproject.aaa" is the FQDN of our app + appId = coreService.registerApplication("org.onosproject.aaa"); + + cfgListener.reconfigureNetwork(netCfgService.getConfig(appId, AaaConfig.class)); + + // register our event handler + packetService.addProcessor(processor, PacketProcessor.director(2)); + requestIntercepts(); + + StateMachine.initializeMaps(); + + try { + radiusSocket = new DatagramSocket(radiusServerPort); + } catch (Exception ex) { + log.error("Can't open RADIUS socket", ex); + } + + executor = Executors.newSingleThreadExecutor( + new ThreadFactoryBuilder() + .setNameFormat("AAA-radius-%d").build()); + executor.execute(radiusListener); + } + + @Deactivate + public void deactivate() { + appId = coreService.registerApplication("org.onosproject.aaa"); + withdrawIntercepts(); + // de-register and null our handler + packetService.removeProcessor(processor); + processor = null; + StateMachine.destroyMaps(); + radiusSocket.close(); + executor.shutdownNow(); + } + + protected void sendRadiusPacket(RADIUS radiusPacket) { + + try { + final byte[] data = radiusPacket.serialize(); + final DatagramSocket socket = radiusSocket; + + DatagramPacket packet = + new DatagramPacket(data, data.length, + radiusIpAddress, radiusServerPort); + + socket.send(packet); + } catch (IOException e) { + log.info("Cannot send packet to RADIUS server", e); + } + } + + /** + * Request packet in via PacketService. + */ + private void requestIntercepts() { + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); + selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort()); + packetService.requestPackets(selector.build(), + CONTROL, appId); + } + + /** + * Cancel request for packet in via PacketService. + */ + private void withdrawIntercepts() { + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); + selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort()); + packetService.cancelPackets(selector.build(), CONTROL, appId); + } + + /** + * Send the ethernet packet to the supplicant. + * + * @param ethernetPkt the ethernet packet + * @param connectPoint the connect point to send out + */ + private void sendPacketToSupplicant(Ethernet ethernetPkt, ConnectPoint connectPoint) { + TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(connectPoint.port()).build(); + OutboundPacket packet = new DefaultOutboundPacket(connectPoint.deviceId(), + treatment, ByteBuffer.wrap(ethernetPkt.serialize())); + packetService.emit(packet); + } + + // our handler defined as a private inner class + + /** + * Packet processor responsible for forwarding packets along their paths. + */ + private class ReactivePacketProcessor implements PacketProcessor { + @Override + public void process(PacketContext context) { + + // Extract the original Ethernet frame from the packet information + InboundPacket pkt = context.inPacket(); + Ethernet ethPkt = pkt.parsed(); + if (ethPkt == null) { + return; + } + try { + // identify if incoming packet comes from supplicant (EAP) or RADIUS + switch (EthType.EtherType.lookup(ethPkt.getEtherType())) { + case EAPOL: + handleSupplicantPacket(context.inPacket()); + break; + default: + log.trace("Skipping Ethernet packet type {}", + EthType.EtherType.lookup(ethPkt.getEtherType())); + } + } catch (StateMachineException e) { + log.warn("Unable to process RADIUS packet:", e); + } + } + + /** + * Creates and initializes common fields of a RADIUS packet. + * + * @param stateMachine state machine for the request + * @param eapPacket EAP packet + * @return RADIUS packet + */ + private RADIUS getRadiusPayload(StateMachine stateMachine, byte identifier, EAP eapPacket) { + RADIUS radiusPayload = + new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST, + eapPacket.getIdentifier()); + + // set Request Authenticator in StateMachine + stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode()); + + radiusPayload.setIdentifier(identifier); + radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME, + stateMachine.username()); + + radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP, + AaaManager.this.nasIpAddress.getAddress()); + + radiusPayload.encapsulateMessage(eapPacket); + + return radiusPayload; + } + + /** + * Handles PAE packets (supplicant). + * + * @param inPacket Ethernet packet coming from the supplicant + */ + private void handleSupplicantPacket(InboundPacket inPacket) throws StateMachineException { + Ethernet ethPkt = inPacket.parsed(); + // Where does it come from? + MacAddress srcMac = ethPkt.getSourceMAC(); + + DeviceId deviceId = inPacket.receivedFrom().deviceId(); + PortNumber portNumber = inPacket.receivedFrom().port(); + String sessionId = deviceId.toString() + portNumber.toString(); + StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(sessionId); + if (stateMachine == null) { + stateMachine = new StateMachine(sessionId, voltTenantService); + } + + + EAPOL eapol = (EAPOL) ethPkt.getPayload(); + + switch (eapol.getEapolType()) { + case EAPOL.EAPOL_START: + stateMachine.start(); + stateMachine.setSupplicantConnectpoint(inPacket.receivedFrom()); + + //send an EAP Request/Identify to the supplicant + EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.identifier(), EAP.ATTR_IDENTITY, null); + Ethernet eth = buildEapolResponse(srcMac, MacAddress.valueOf(nasMacAddress), + ethPkt.getVlanID(), EAPOL.EAPOL_PACKET, + eapPayload); + stateMachine.setSupplicantAddress(srcMac); + stateMachine.setVlanId(ethPkt.getVlanID()); + + sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint()); + + break; + case EAPOL.EAPOL_PACKET: + RADIUS radiusPayload; + // check if this is a Response/Identify or a Response/TLS + EAP eapPacket = (EAP) eapol.getPayload(); + + byte dataType = eapPacket.getDataType(); + switch (dataType) { + + case EAP.ATTR_IDENTITY: + // request id access to RADIUS + stateMachine.setUsername(eapPacket.getData()); + + radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket); + radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret); + + sendRadiusPacket(radiusPayload); + + // change the state to "PENDING" + stateMachine.requestAccess(); + break; + case EAP.ATTR_MD5: + // verify if the EAP identifier corresponds to the + // challenge identifier from the client state + // machine. + if (eapPacket.getIdentifier() == stateMachine.challengeIdentifier()) { + //send the RADIUS challenge response + radiusPayload = + getRadiusPayload(stateMachine, + stateMachine.identifier(), + eapPacket); + + radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE, + stateMachine.challengeState()); + radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret); + sendRadiusPacket(radiusPayload); + } + break; + case EAP.ATTR_TLS: + // request id access to RADIUS + radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket); + + radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE, + stateMachine.challengeState()); + stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode()); + + radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret); + sendRadiusPacket(radiusPayload); + + if (stateMachine.state() != StateMachine.STATE_PENDING) { + stateMachine.requestAccess(); + } + + break; + default: + return; + } + break; + default: + log.trace("Skipping EAPOL message {}", eapol.getEapolType()); + } + + } + } + + class RadiusListener implements Runnable { + + /** + * Handles RADIUS packets. + * + * @param radiusPacket RADIUS packet coming from the RADIUS server. + * @throws StateMachineException if an illegal state transition is triggered + */ + protected void handleRadiusPacket(RADIUS radiusPacket) throws StateMachineException { + StateMachine stateMachine = StateMachine.lookupStateMachineById(radiusPacket.getIdentifier()); + if (stateMachine == null) { + log.error("Invalid session identifier, exiting..."); + return; + } + + EAP eapPayload; + Ethernet eth; + switch (radiusPacket.getCode()) { + case RADIUS.RADIUS_CODE_ACCESS_CHALLENGE: + byte[] challengeState = + radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE).getValue(); + eapPayload = radiusPacket.decapsulateMessage(); + stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState); + eth = buildEapolResponse(stateMachine.supplicantAddress(), + MacAddress.valueOf(nasMacAddress), + stateMachine.vlanId(), + EAPOL.EAPOL_PACKET, + eapPayload); + sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint()); + break; + case RADIUS.RADIUS_CODE_ACCESS_ACCEPT: + //send an EAPOL - Success to the supplicant. + byte[] eapMessage = + radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue(); + eapPayload = new EAP(); + eapPayload = (EAP) eapPayload.deserialize(eapMessage, 0, eapMessage.length); + eth = buildEapolResponse(stateMachine.supplicantAddress(), + MacAddress.valueOf(nasMacAddress), + stateMachine.vlanId(), + EAPOL.EAPOL_PACKET, + eapPayload); + sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint()); + + stateMachine.authorizeAccess(); + break; + case RADIUS.RADIUS_CODE_ACCESS_REJECT: + stateMachine.denyAccess(); + break; + default: + log.warn("Unknown RADIUS message received with code: {}", radiusPacket.getCode()); + } + } + + + @Override + public void run() { + boolean done = false; + int packetNumber = 1; + + log.info("UDP listener thread starting up"); + RADIUS inboundRadiusPacket; + while (!done) { + try { + byte[] packetBuffer = new byte[RADIUS.RADIUS_MAX_LENGTH]; + DatagramPacket inboundBasePacket = + new DatagramPacket(packetBuffer, packetBuffer.length); + DatagramSocket socket = radiusSocket; + socket.receive(inboundBasePacket); + log.info("Packet #{} received", packetNumber++); + try { + inboundRadiusPacket = + RADIUS.deserializer() + .deserialize(inboundBasePacket.getData(), + 0, + inboundBasePacket.getLength()); + handleRadiusPacket(inboundRadiusPacket); + } catch (DeserializationException dex) { + log.error("Cannot deserialize packet", dex); + } catch (StateMachineException sme) { + log.error("Illegal state machine operation", sme); + } + + } catch (IOException e) { + log.info("Socket was closed, exiting listener thread"); + done = true; + } + } + } + } + + RadiusListener radiusListener = new RadiusListener(); + + private class InternalConfigListener implements NetworkConfigListener { + + /** + * Reconfigures the DHCP Server according to the configuration parameters passed. + * + * @param cfg configuration object + */ + private void reconfigureNetwork(AaaConfig cfg) { + AaaConfig newCfg; + if (cfg == null) { + newCfg = new AaaConfig(); + } else { + newCfg = cfg; + } + if (newCfg.nasIp() != null) { + nasIpAddress = newCfg.nasIp(); + } + if (newCfg.radiusIp() != null) { + radiusIpAddress = newCfg.radiusIp(); + } + if (newCfg.radiusMac() != null) { + radiusMacAddress = newCfg.radiusMac(); + } + if (newCfg.nasMac() != null) { + nasMacAddress = newCfg.nasMac(); + } + if (newCfg.radiusSecret() != null) { + radiusSecret = newCfg.radiusSecret(); + } + if (newCfg.radiusSwitch() != null) { + radiusSwitch = newCfg.radiusSwitch(); + } + if (newCfg.radiusPort() != -1) { + radiusPort = newCfg.radiusPort(); + } + if (newCfg.radiusServerUdpPort() != -1) { + radiusServerPort = newCfg.radiusServerUdpPort(); + } + } + + @Override + public void event(NetworkConfigEvent event) { + + if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || + event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) && + event.configClass().equals(AaaConfig.class)) { + + AaaConfig cfg = netCfgService.getConfig(appId, AaaConfig.class); + reconfigureNetwork(cfg); + log.info("Reconfigured"); + } + } + } + + +} diff --git a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaIntegrationTest.java b/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaIntegrationTest.java new file mode 100644 index 00000000..6d708fef --- /dev/null +++ b/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaIntegrationTest.java @@ -0,0 +1,151 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.aaa; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.onlab.packet.EAP; +import org.onlab.packet.EAPOL; +import org.onlab.packet.Ethernet; +import org.onosproject.core.CoreServiceAdapter; +import org.onosproject.net.config.Config; +import org.onosproject.net.config.NetworkConfigRegistryAdapter; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; + +/** + * Set of tests of the ONOS application component. These use an existing RADIUS + * server and sends live packets over the network to it. + */ +@Ignore ("This should not be run as part of the standard build") +public class AaaIntegrationTest extends AaaTestBase { + + private AaaManager aaa; + + /** + * Mocks the network config registry. + */ + @SuppressWarnings("unchecked") + static final class TestNetworkConfigRegistry + extends NetworkConfigRegistryAdapter { + @Override + public > C getConfig(S subject, Class configClass) { + return (C) new AaaConfig(); + } + } + + /** + * Sets up the services required by the AAA application. + */ + @Before + public void setUp() { + aaa = new AaaManager(); + aaa.netCfgService = new TestNetworkConfigRegistry(); + aaa.coreService = new CoreServiceAdapter(); + aaa.packetService = new MockPacketService(); + aaa.activate(); + } + + /** + * Fetches the sent packet at the given index. The requested packet + * must be the last packet on the list. + * + * @param index index into sent packets array + * @return packet + */ + private Ethernet fetchPacket(int index) { + for (int iteration = 0; iteration < 20; iteration++) { + if (savedPackets.size() > index) { + return (Ethernet) savedPackets.get(index); + } else { + try { + Thread.sleep(250); + } catch (Exception ex) { + return null; + } + } + } + return null; + } + + /** + * Tests the authentication path through the AAA application by sending + * packets to the RADIUS server and checking the state machine + * transitions. + * + * @throws Exception when an unhandled error occurs + */ + @Test + public void testAuthentication() throws Exception { + + // (1) Supplicant start up + + Ethernet startPacket = constructSupplicantStartPacket(); + sendPacket(startPacket); + + Ethernet responsePacket = fetchPacket(0); + assertThat(responsePacket, notNullValue()); + checkRadiusPacket(aaa, responsePacket, EAP.REQUEST); + + // (2) Supplicant identify + + Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null); + sendPacket(identifyPacket); + + // State machine should have been created by now + + StateMachine stateMachine = + StateMachine.lookupStateMachineBySessionId(SESSION_ID); + assertThat(stateMachine, notNullValue()); + assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING)); + + // (3) RADIUS MD5 challenge + + Ethernet radiusChallengeMD5Packet = fetchPacket(1); + assertThat(radiusChallengeMD5Packet, notNullValue()); + checkRadiusPacket(aaa, radiusChallengeMD5Packet, EAP.REQUEST); + + + // (4) Supplicant MD5 response + + Ethernet md5RadiusPacket = + constructSupplicantIdentifyPacket(stateMachine, + EAP.ATTR_MD5, + stateMachine.challengeIdentifier(), + radiusChallengeMD5Packet); + sendPacket(md5RadiusPacket); + + + // (5) RADIUS Success + + Ethernet successRadiusPacket = fetchPacket(2); + assertThat(successRadiusPacket, notNullValue()); + EAPOL successEapol = (EAPOL) successRadiusPacket.getPayload(); + EAP successEap = (EAP) successEapol.getPayload(); + assertThat(successEap.getCode(), is(EAP.SUCCESS)); + + // State machine should be in authorized state + + assertThat(stateMachine, notNullValue()); + assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED)); + + } + +} + diff --git a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaManagerTest.java b/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaManagerTest.java new file mode 100644 index 00000000..e3bcd9e4 --- /dev/null +++ b/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaManagerTest.java @@ -0,0 +1,258 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.aaa; + +import com.google.common.base.Charsets; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.packet.BasePacket; +import org.onlab.packet.DeserializationException; +import org.onlab.packet.EAP; +import org.onlab.packet.Ethernet; +import org.onlab.packet.IpAddress; +import org.onlab.packet.RADIUS; +import org.onlab.packet.RADIUSAttribute; +import org.onosproject.core.CoreServiceAdapter; +import org.onosproject.net.config.Config; +import org.onosproject.net.config.NetworkConfigRegistryAdapter; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; + +/** + * Set of tests of the ONOS application component. + */ +public class AaaManagerTest extends AaaTestBase { + + static final String BAD_IP_ADDRESS = "198.51.100.0"; + + private AaaManager aaaManager; + + class AaaManagerWithoutRadiusServer extends AaaManager { + protected void sendRadiusPacket(RADIUS radiusPacket) { + savePacket(radiusPacket); + } + } + + /** + * Mocks the AAAConfig class to force usage of an unroutable address for the + * RADIUS server. + */ + static class MockAaaConfig extends AaaConfig { + @Override + public InetAddress radiusIp() { + try { + return InetAddress.getByName(BAD_IP_ADDRESS); + } catch (UnknownHostException ex) { + // can't happen + throw new IllegalStateException(ex); + } + } + } + + /** + * Mocks the network config registry. + */ + @SuppressWarnings("unchecked") + private static final class TestNetworkConfigRegistry + extends NetworkConfigRegistryAdapter { + @Override + public > C getConfig(S subject, Class configClass) { + AaaConfig aaaConfig = new MockAaaConfig(); + return (C) aaaConfig; + } + } + + /** + * Constructs an Ethernet packet containing a RADIUS challenge + * packet. + * + * @param challengeCode code to use in challenge packet + * @param challengeType type to use in challenge packet + * @return Ethernet packet + */ + private RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType) { + + String challenge = "12345678901234567"; + + EAP eap = new EAP(challengeType, (byte) 1, challengeType, + challenge.getBytes(Charsets.US_ASCII)); + eap.setIdentifier((byte) 1); + + RADIUS radius = new RADIUS(); + radius.setCode(challengeCode); + + radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE, + challenge.getBytes(Charsets.US_ASCII)); + + radius.setPayload(eap); + radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE, + eap.serialize()); + + return radius; + } + + /** + * Sets up the services required by the AAA application. + */ + @Before + public void setUp() { + aaaManager = new AaaManagerWithoutRadiusServer(); + aaaManager.netCfgService = new TestNetworkConfigRegistry(); + aaaManager.coreService = new CoreServiceAdapter(); + aaaManager.packetService = new MockPacketService(); + aaaManager.activate(); + } + + /** + * Tears down the AAA application. + */ + @After + public void tearDown() { + aaaManager.deactivate(); + } + + /** + * Extracts the RADIUS packet from a packet sent by the supplicant. + * + * @param radius RADIUS packet sent by the supplicant + * @throws DeserializationException if deserialization of the packet contents + * fails. + */ + private void checkRadiusPacketFromSupplicant(RADIUS radius) + throws DeserializationException { + assertThat(radius, notNullValue()); + + EAP eap = radius.decapsulateMessage(); + assertThat(eap, notNullValue()); + } + + /** + * Fetches the sent packet at the given index. The requested packet + * must be the last packet on the list. + * + * @param index index into sent packets array + * @return packet + */ + private BasePacket fetchPacket(int index) { + BasePacket packet = savedPackets.get(index); + assertThat(packet, notNullValue()); + return packet; + } + + /** + * Tests the authentication path through the AAA application. + * + * @throws DeserializationException if packed deserialization fails. + */ + @Test + public void testAuthentication() throws Exception { + + // (1) Supplicant start up + + Ethernet startPacket = constructSupplicantStartPacket(); + sendPacket(startPacket); + + Ethernet responsePacket = (Ethernet) fetchPacket(0); + checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY); + + // (2) Supplicant identify + + Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null); + sendPacket(identifyPacket); + + RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1); + + checkRadiusPacketFromSupplicant(radiusIdentifyPacket); + + assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST)); + assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()), + is("testuser")); + + IpAddress nasIp = + IpAddress.valueOf(IpAddress.Version.INET, + radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP) + .getValue()); + assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress())); + + // State machine should have been created by now + + StateMachine stateMachine = + StateMachine.lookupStateMachineBySessionId(SESSION_ID); + assertThat(stateMachine, notNullValue()); + assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING)); + + // (3) RADIUS MD5 challenge + + RADIUS radiusCodeAccessChallengePacket = + constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5); + aaaManager.radiusListener.handleRadiusPacket(radiusCodeAccessChallengePacket); + + Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2); + checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5); + + // (4) Supplicant MD5 response + + Ethernet md5RadiusPacket = + constructSupplicantIdentifyPacket(stateMachine, + EAP.ATTR_MD5, + stateMachine.challengeIdentifier(), + radiusChallengeMD5Packet); + sendPacket(md5RadiusPacket); + + RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3); + + checkRadiusPacketFromSupplicant(responseMd5RadiusPacket); + assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 0)); + assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST)); + + // State machine should be in pending state + + assertThat(stateMachine, notNullValue()); + assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING)); + + // (5) RADIUS Success + + RADIUS successPacket = + constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS); + aaaManager.radiusListener.handleRadiusPacket((successPacket)); + Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4); + + checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS); + + // State machine should be in authorized state + + assertThat(stateMachine, notNullValue()); + assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED)); + + } + + /** + * Tests the default configuration. + */ + @Test + public void testConfig() { + assertThat(aaaManager.nasIpAddress.getHostAddress(), is(AaaConfig.DEFAULT_NAS_IP)); + assertThat(aaaManager.nasMacAddress, is(AaaConfig.DEFAULT_NAS_MAC)); + assertThat(aaaManager.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS)); + assertThat(aaaManager.radiusMacAddress, is(AaaConfig.DEFAULT_RADIUS_MAC)); + } +} diff --git a/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaTestBase.java b/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaTestBase.java new file mode 100644 index 00000000..b076a2e3 --- /dev/null +++ b/framework/src/onos/apps/aaa/src/test/java/org/onosproject/aaa/AaaTestBase.java @@ -0,0 +1,224 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.aaa; + +import org.onlab.packet.BasePacket; +import org.onlab.packet.EAP; +import org.onlab.packet.EAPOL; +import org.onlab.packet.EthType; +import org.onlab.packet.Ethernet; +import org.onlab.packet.MacAddress; +import org.onosproject.net.packet.DefaultInboundPacket; +import org.onosproject.net.packet.DefaultPacketContext; +import org.onosproject.net.packet.InboundPacket; +import org.onosproject.net.packet.OutboundPacket; +import org.onosproject.net.packet.PacketContext; +import org.onosproject.net.packet.PacketProcessor; +import org.onosproject.net.packet.PacketServiceAdapter; + +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.util.LinkedList; +import java.util.List; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.onosproject.net.NetTestTools.connectPoint; + +/** + * Common methods for AAA app testing. + */ +public class AaaTestBase { + + MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a"); + MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a"); + + // Our session id will be the device ID ("of:1") with the port ("1") concatenated + static final String SESSION_ID = "of:11"; + + List savedPackets = new LinkedList<>(); + PacketProcessor packetProcessor; + + /** + * Saves the given packet onto the saved packets list. + * + * @param packet packet to save + */ + void savePacket(BasePacket packet) { + savedPackets.add(packet); + } + + /** + * Keeps a reference to the PacketProcessor and saves the OutboundPackets. + */ + class MockPacketService extends PacketServiceAdapter { + + @Override + public void addProcessor(PacketProcessor processor, int priority) { + packetProcessor = processor; + } + + @Override + public void emit(OutboundPacket packet) { + try { + Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(), + 0, packet.data().array().length); + savePacket(eth); + } catch (Exception e) { + fail(e.getMessage()); + } + } + } + + /** + * Mocks the DefaultPacketContext. + */ + final class TestPacketContext extends DefaultPacketContext { + + private TestPacketContext(long time, InboundPacket inPkt, + OutboundPacket outPkt, boolean block) { + super(time, inPkt, outPkt, block); + } + + @Override + public void send() { + // We don't send anything out. + } + } + + /** + * Sends an Ethernet packet to the process method of the Packet Processor. + * + * @param reply Ethernet packet + */ + void sendPacket(Ethernet reply) { + final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize()); + InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1), + reply, + byteBuffer); + + PacketContext context = new TestPacketContext(127L, inPacket, null, false); + packetProcessor.process(context); + } + + /** + * Constructs an Ethernet packet containing identification payload. + * + * @return Ethernet packet + */ + Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine, + byte type, + byte id, + Ethernet radiusChallenge) + throws Exception { + Ethernet eth = new Ethernet(); + eth.setDestinationMACAddress(clientMac.toBytes()); + eth.setSourceMACAddress(serverMac.toBytes()); + eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort()); + eth.setVlanID((short) 2); + + String username = "testuser"; + byte[] data = username.getBytes(); + + + if (type == EAP.ATTR_MD5) { + String password = "testpassword"; + EAPOL eapol = (EAPOL) radiusChallenge.getPayload(); + EAP eap = (EAP) eapol.getPayload(); + + byte[] identifier = new byte[password.length() + eap.getData().length]; + + identifier[0] = stateMachine.challengeIdentifier(); + System.arraycopy(password.getBytes(), 0, identifier, 1, password.length()); + System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16); + + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] hash = md.digest(identifier); + data = new byte[17]; + data[0] = (byte) 16; + System.arraycopy(hash, 0, data, 1, 16); + } + EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type, + data); + eap.setIdentifier(id); + + // eapol header + EAPOL eapol = new EAPOL(); + eapol.setEapolType(EAPOL.EAPOL_PACKET); + eapol.setPacketLength(eap.getLength()); + + // eap part + eapol.setPayload(eap); + + eth.setPayload(eapol); + eth.setPad(true); + return eth; + } + + /** + * Constructs an Ethernet packet containing a EAPOL_START Payload. + * + * @return Ethernet packet + */ + Ethernet constructSupplicantStartPacket() { + Ethernet eth = new Ethernet(); + eth.setDestinationMACAddress(clientMac.toBytes()); + eth.setSourceMACAddress(serverMac.toBytes()); + eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort()); + eth.setVlanID((short) 2); + + EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 2, EAPOL.EAPOL_START, null); + + // eapol header + EAPOL eapol = new EAPOL(); + eapol.setEapolType(EAPOL.EAPOL_START); + eapol.setPacketLength(eap.getLength()); + + // eap part + eapol.setPayload(eap); + + eth.setPayload(eapol); + eth.setPad(true); + return eth; + } + + /** + * Checks the contents of a RADIUS packet being sent to the RADIUS server. + * + * @param radiusPacket packet to check + * @param code expected code + */ + void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) { + + assertThat(radiusPacket.getSourceMAC(), + is(MacAddress.valueOf(aaaManager.nasMacAddress))); + assertThat(radiusPacket.getDestinationMAC(), is(serverMac)); + + assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class)); + EAPOL eapol = (EAPOL) radiusPacket.getPayload(); + assertThat(eapol, notNullValue()); + + assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET)); + assertThat(eapol.getPayload(), instanceOf(EAP.class)); + EAP eap = (EAP) eapol.getPayload(); + assertThat(eap, notNullValue()); + + assertThat(eap.getCode(), is(code)); + } +} diff --git a/framework/src/onos/apps/bgprouter/features.xml b/framework/src/onos/apps/bgprouter/features.xml index c91a7f10..7153ac91 100644 --- a/framework/src/onos/apps/bgprouter/features.xml +++ b/framework/src/onos/apps/bgprouter/features.xml @@ -15,7 +15,6 @@ ~ limitations under the License. --> - mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features onos-api diff --git a/framework/src/onos/apps/cordvtn/pom.xml b/framework/src/onos/apps/cordvtn/pom.xml index 1d96108b..3f3ec23b 100644 --- a/framework/src/onos/apps/cordvtn/pom.xml +++ b/framework/src/onos/apps/cordvtn/pom.xml @@ -33,6 +33,10 @@ org.onosproject.cordvtn + + org.onosproject.ovsdb, + org.onosproject.openstackswitching + @@ -64,6 +68,11 @@ org.apache.karaf.shell.console 3.0.3 + + org.onosproject + onos-app-openstackswitching-api + ${project.version} + diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java index c3bf77c5..67297741 100644 --- a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java @@ -15,6 +15,8 @@ */ package org.onosproject.cordvtn; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; @@ -23,6 +25,7 @@ import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.Service; import org.onlab.util.ItemNotFoundException; +import org.onlab.packet.IpAddress; import org.onlab.util.KryoNamespace; import org.onosproject.cluster.ClusterService; import org.onosproject.core.ApplicationId; @@ -31,9 +34,11 @@ import org.onosproject.net.DefaultAnnotations; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Host; +import org.onosproject.net.HostId; import org.onosproject.net.Port; import org.onosproject.net.behaviour.BridgeConfig; import org.onosproject.net.behaviour.BridgeName; +import org.onosproject.net.ConnectPoint; import org.onosproject.net.behaviour.ControllerInfo; import org.onosproject.net.behaviour.DefaultTunnelDescription; import org.onosproject.net.behaviour.TunnelConfig; @@ -45,9 +50,13 @@ import org.onosproject.net.device.DeviceListener; import org.onosproject.net.device.DeviceService; import org.onosproject.net.driver.DriverHandler; import org.onosproject.net.driver.DriverService; +import org.onosproject.net.flowobjective.FlowObjectiveService; import org.onosproject.net.host.HostEvent; import org.onosproject.net.host.HostListener; import org.onosproject.net.host.HostService; +import org.onosproject.openstackswitching.OpenstackNetwork; +import org.onosproject.openstackswitching.OpenstackPort; +import org.onosproject.openstackswitching.OpenstackSwitchingService; import org.onosproject.ovsdb.controller.OvsdbClientService; import org.onosproject.ovsdb.controller.OvsdbController; import org.onosproject.ovsdb.controller.OvsdbNodeId; @@ -62,8 +71,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; +import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkNotNull; import static org.onlab.util.Tools.groupedThreads; @@ -72,8 +83,8 @@ import static org.onosproject.net.behaviour.TunnelDescription.Type.VXLAN; import static org.slf4j.LoggerFactory.getLogger; /** - * Provides initial setup or cleanup for provisioning virtual tenant networks - * on ovsdb, integration bridge and vm when they are added or deleted. + * Provisions virtual tenant networks with service chaining capability + * in OpenStack environment. */ @Component(immediate = true) @Service @@ -86,7 +97,8 @@ public class CordVtn implements CordVtnService { .register(KryoNamespaces.API) .register(CordVtnNode.class) .register(NodeState.class); - private static final String DEFAULT_BRIDGE_NAME = "br-int"; + private static final String DEFAULT_BRIDGE = "br-int"; + private static final String VPORT_PREFIX = "tap"; private static final String DEFAULT_TUNNEL = "vxlan"; private static final Map DEFAULT_TUNNEL_OPTIONS = new HashMap() { { @@ -115,12 +127,18 @@ public class CordVtn implements CordVtnService { @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected DeviceAdminService adminService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FlowObjectiveService flowObjectiveService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected OvsdbController controller; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected ClusterService clusterService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected OpenstackSwitchingService openstackService; + private final ExecutorService eventExecutor = Executors .newFixedThreadPool(NUM_THREADS, groupedThreads("onos/cordvtn", "event-handler")); @@ -132,6 +150,8 @@ public class CordVtn implements CordVtnService { private final VmHandler vmHandler = new VmHandler(); private ConsistentMap nodeStore; + private Map hostNetworkMap = Maps.newHashMap(); + private CordVtnRuleInstaller ruleInstaller; private enum NodeState { @@ -185,6 +205,8 @@ public class CordVtn implements CordVtnService { .withApplicationId(appId) .build(); + ruleInstaller = new CordVtnRuleInstaller(appId, flowObjectiveService, + driverService, DEFAULT_TUNNEL); deviceService.addListener(deviceListener); hostService.addListener(hostListener); @@ -314,11 +336,27 @@ public class CordVtn implements CordVtnService { /** * Performs tasks after node initialization. + * First disconnect unnecessary OVSDB connection and then installs flow rules + * for existing VMs if there are any. * * @param node cordvtn node */ private void postInit(CordVtnNode node) { disconnect(node); + + Set vNets = Sets.newHashSet(); + hostService.getConnectedHosts(node.intBrId()) + .stream() + .forEach(host -> { + OpenstackNetwork vNet = getOpenstackNetworkByHost(host); + if (vNet != null) { + log.info("VM {} is detected", host.id()); + + hostNetworkMap.put(host.id(), vNet.id()); + vNets.add(vNet); + } + }); + vNets.stream().forEach(this::installFlowRules); } /** @@ -443,7 +481,7 @@ public class CordVtn implements CordVtnService { } List controllers = new ArrayList<>(); - Sets.newHashSet(clusterService.getNodes()) + Sets.newHashSet(clusterService.getNodes()).stream() .forEach(controller -> { ControllerInfo ctrlInfo = new ControllerInfo(controller.ip(), OFPORT, "tcp"); controllers.add(ctrlInfo); @@ -453,7 +491,7 @@ public class CordVtn implements CordVtnService { try { DriverHandler handler = driverService.createHandler(node.ovsdbId()); BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class); - bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), dpid, controllers); + bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE), dpid, controllers); } catch (ItemNotFoundException e) { log.warn("Failed to create integration bridge on {}", node.ovsdbId()); } @@ -474,13 +512,12 @@ public class CordVtn implements CordVtnService { optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key)); } TunnelDescription description = - new DefaultTunnelDescription(null, null, VXLAN, - TunnelName.tunnelName(DEFAULT_TUNNEL), + new DefaultTunnelDescription(null, null, VXLAN, TunnelName.tunnelName(DEFAULT_TUNNEL), optionBuilder.build()); try { DriverHandler handler = driverService.createHandler(node.ovsdbId()); TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class); - tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), description); + tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE), description); } catch (ItemNotFoundException e) { log.warn("Failed to create tunnel interface on {}", node.ovsdbId()); } @@ -516,6 +553,212 @@ public class CordVtn implements CordVtnService { } } + /** + * Returns tunnel port of the device. + * + * @param bridgeId device id + * @return port, null if no tunnel port exists on a given device + */ + private Port getTunnelPort(DeviceId bridgeId) { + try { + return deviceService.getPorts(bridgeId).stream() + .filter(p -> p.annotations().value("portName").contains(DEFAULT_TUNNEL) + && p.isEnabled()) + .findFirst().get(); + } catch (NoSuchElementException e) { + return null; + } + } + + /** + * Returns remote ip address for tunneling. + * + * @param bridgeId device id + * @return ip address, null if no such device exists + */ + private IpAddress getRemoteIp(DeviceId bridgeId) { + CordVtnNode node = getNodeByBridgeId(bridgeId); + if (node != null) { + // TODO get data plane IP for tunneling + return node.ovsdbIp(); + } else { + return null; + } + } + + /** + * Returns destination information of all ports associated with a given + * OpenStack network. Output of the destination information is set to local + * port or tunnel port according to a given device id. + * + * @param deviceId device id to install flow rules + * @param vNet OpenStack network + * @return list of flow information, empty list if no flow information exists + */ + private List getSameNetworkPortsInfo(DeviceId deviceId, OpenstackNetwork vNet) { + List dstInfos = Lists.newArrayList(); + long tunnelId = Long.valueOf(vNet.segmentId()); + + for (OpenstackPort vPort : openstackService.ports(vNet.id())) { + ConnectPoint cp = getConnectPoint(vPort); + if (cp == null) { + log.debug("Couldn't find connection point for OpenStack port {}", vPort.id()); + continue; + } + + DestinationInfo.Builder dBuilder = cp.deviceId().equals(deviceId) ? + DestinationInfo.builder(deviceService.getPort(cp.deviceId(), cp.port())) : + DestinationInfo.builder(getTunnelPort(deviceId)) + .setRemoteIp(getRemoteIp(cp.deviceId())); + + dBuilder.setMac(vPort.macAddress()) + .setTunnelId(tunnelId); + dstInfos.add(dBuilder.build()); + } + return dstInfos; + } + + /** + * Returns local ports associated with a given OpenStack network. + * + * @param bridgeId device id + * @param vNet OpenStack network + * @return port list, empty list if no port exists + */ + private List getLocalSameNetworkPorts(DeviceId bridgeId, OpenstackNetwork vNet) { + List ports = new ArrayList<>(); + openstackService.ports(vNet.id()).stream().forEach(port -> { + ConnectPoint cp = getConnectPoint(port); + if (cp != null && cp.deviceId().equals(bridgeId)) { + ports.add(deviceService.getPort(cp.deviceId(), cp.port())); + } + }); + return ports; + } + + /** + * Returns OpenStack port associated with a given host. + * + * @param host host + * @return OpenStack port, or null if no port has been found + */ + private OpenstackPort getOpenstackPortByHost(Host host) { + Port port = deviceService.getPort(host.location().deviceId(), + host.location().port()); + return openstackService.port(port); + } + + /** + * Returns OpenStack network associated with a given host. + * + * @param host host + * @return OpenStack network, or null if no network has been found + */ + private OpenstackNetwork getOpenstackNetworkByHost(Host host) { + OpenstackPort vPort = getOpenstackPortByHost(host); + if (vPort != null) { + return openstackService.network(vPort.networkId()); + } else { + return null; + } + } + + /** + * Returns port name with OpenStack port information. + * + * @param vPort OpenStack port + * @return port name + */ + private String getPortName(OpenstackPort vPort) { + checkNotNull(vPort); + return VPORT_PREFIX + vPort.id().substring(0, 10); + } + + /** + * Returns connect point of a given OpenStack port. + * It assumes there's only one physical port associated with an OpenStack port. + * + * @param vPort openstack port + * @return connect point, null if no such port exists + */ + private ConnectPoint getConnectPoint(OpenstackPort vPort) { + try { + Host host = hostService.getHostsByMac(vPort.macAddress()) + .stream() + .findFirst() + .get(); + return new ConnectPoint(host.location().deviceId(), host.location().port()); + } catch (NoSuchElementException e) { + log.debug("Not a valid host with {}", vPort.macAddress()); + return null; + } + } + + /** + * Installs flow rules for a given OpenStack network. + * + * @param vNet OpenStack network + */ + private void installFlowRules(OpenstackNetwork vNet) { + checkNotNull(vNet, "Tenant network should not be null"); + + for (Device device : deviceService.getAvailableDevices(SWITCH)) { + List dstInfos = getSameNetworkPortsInfo(device.id(), vNet); + + for (Port inPort : getLocalSameNetworkPorts(device.id(), vNet)) { + List localInInfos = dstInfos.stream() + .filter(info -> !info.output().equals(inPort)) + .collect(Collectors.toList()); + ruleInstaller.installFlowRulesLocalIn(device.id(), inPort, localInInfos); + } + + Port tunPort = getTunnelPort(device.id()); + List tunnelInInfos = dstInfos.stream() + .filter(info -> !info.output().equals(tunPort)) + .collect(Collectors.toList()); + ruleInstaller.installFlowRulesTunnelIn(device.id(), tunPort, tunnelInInfos); + } + } + + /** + * Uninstalls flow rules associated with a given host for a given OpenStack network. + * + * @param vNet OpenStack network + * @param host removed host + */ + private void uninstallFlowRules(OpenstackNetwork vNet, Host host) { + checkNotNull(vNet, "Tenant network should not be null"); + + Port removedPort = deviceService.getPort(host.location().deviceId(), + host.location().port()); + + for (Device device : deviceService.getAvailableDevices(SWITCH)) { + List dstInfos = getSameNetworkPortsInfo(device.id(), vNet); + + for (Port inPort : getLocalSameNetworkPorts(device.id(), vNet)) { + List localInInfos = Lists.newArrayList( + DestinationInfo.builder(getTunnelPort(device.id())) + .setTunnelId(Long.valueOf(vNet.segmentId())) + .setMac(host.mac()) + .setRemoteIp(getRemoteIp(host.location().deviceId())) + .build()); + ruleInstaller.uninstallFlowRules(device.id(), inPort, localInInfos); + } + + if (device.id().equals(host.location().deviceId())) { + Port tunPort = getTunnelPort(device.id()); + List tunnelInInfo = Lists.newArrayList( + DestinationInfo.builder(removedPort) + .setTunnelId(Long.valueOf(vNet.segmentId())) + .setMac(host.mac()) + .build()); + + ruleInstaller.uninstallFlowRules(device.id(), tunPort, tunnelInInfo); + ruleInstaller.uninstallFlowRules(device.id(), removedPort, dstInfos); + } + } + } + private class InternalDeviceListener implements DeviceListener { @Override @@ -644,12 +887,40 @@ public class CordVtn implements CordVtnService { @Override public void connected(Host host) { + CordVtnNode node = getNodeByBridgeId(host.location().deviceId()); + if (node == null || !getNodeState(node).equals(NodeState.COMPLETE)) { + // do nothing for the host on unregistered or unprepared device + return; + } + + OpenstackNetwork vNet = getOpenstackNetworkByHost(host); + if (vNet == null) { + return; + } + log.info("VM {} is detected", host.id()); + + hostNetworkMap.put(host.id(), vNet.id()); + installFlowRules(vNet); } @Override public void disconnected(Host host) { + CordVtnNode node = getNodeByBridgeId(host.location().deviceId()); + if (node == null || !getNodeState(node).equals(NodeState.COMPLETE)) { + // do nothing for the host on unregistered or unprepared device + return; + } + + OpenstackNetwork vNet = openstackService.network(hostNetworkMap.get(host.id())); + if (vNet == null) { + return; + } + log.info("VM {} is vanished", host.id()); + + uninstallFlowRules(vNet, host); + hostNetworkMap.remove(host.id()); } } } diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnNode.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnNode.java new file mode 100644 index 00000000..439d16e1 --- /dev/null +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnNode.java @@ -0,0 +1,133 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.cordvtn; + +import com.google.common.base.MoreObjects; +import org.onlab.packet.IpAddress; +import org.onlab.packet.TpPort; +import org.onosproject.net.DeviceId; + +import java.util.Comparator; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Representation of a compute infrastructure node for CORD VTN service. + */ +public final class CordVtnNode { + + private final String hostname; + private final IpAddress ovsdbIp; + private final TpPort ovsdbPort; + private final DeviceId bridgeId; + + public static final Comparator CORDVTN_NODE_COMPARATOR = + (node1, node2) -> node1.hostname().compareTo(node2.hostname()); + + /** + * Creates a new node. + * + * @param hostname hostname + * @param ovsdbIp OVSDB server IP address + * @param ovsdbPort OVSDB server port number + * @param bridgeId integration bridge identifier + */ + public CordVtnNode(String hostname, IpAddress ovsdbIp, TpPort ovsdbPort, DeviceId bridgeId) { + this.hostname = checkNotNull(hostname); + this.ovsdbIp = checkNotNull(ovsdbIp); + this.ovsdbPort = checkNotNull(ovsdbPort); + this.bridgeId = checkNotNull(bridgeId); + } + + /** + * Returns the OVSDB server IP address. + * + * @return ip address + */ + public IpAddress ovsdbIp() { + return this.ovsdbIp; + } + + /** + * Returns the OVSDB server port number. + * + * @return port number + */ + public TpPort ovsdbPort() { + return this.ovsdbPort; + } + + /** + * Returns the hostname. + * + * @return hostname + */ + public String hostname() { + return this.hostname; + } + + /** + * Returns the identifier of the integration bridge. + * + * @return device id + */ + public DeviceId intBrId() { + return this.bridgeId; + } + + /** + * Returns the identifier of the OVSDB device. + * + * @return device id + */ + public DeviceId ovsdbId() { + return DeviceId.deviceId("ovsdb:" + this.ovsdbIp.toString()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof CordVtnNode) { + CordVtnNode that = (CordVtnNode) obj; + if (Objects.equals(hostname, that.hostname) && + Objects.equals(ovsdbIp, that.ovsdbIp) && + Objects.equals(ovsdbPort, that.ovsdbPort) && + Objects.equals(bridgeId, that.bridgeId)) { + return true; + } + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(hostname, ovsdbIp, ovsdbPort); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("host", hostname) + .add("ip", ovsdbIp) + .add("port", ovsdbPort) + .add("bridgeId", bridgeId) + .toString(); + } +} diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java new file mode 100644 index 00000000..9e22997c --- /dev/null +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java @@ -0,0 +1,231 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.cordvtn; + +import org.onlab.packet.Ip4Address; +import org.onlab.util.ItemNotFoundException; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.behaviour.ExtensionTreatmentResolver; +import org.onosproject.net.driver.DefaultDriverData; +import org.onosproject.net.driver.DefaultDriverHandler; +import org.onosproject.net.driver.Driver; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.net.driver.DriverService; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.instructions.ExtensionPropertyException; +import org.onosproject.net.flow.instructions.ExtensionTreatment; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.slf4j.Logger; + +import java.util.List; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Populates rules for virtual tenant network. + */ +public final class CordVtnRuleInstaller { + protected final Logger log = getLogger(getClass()); + + private static final int DEFAULT_PRIORITY = 5000; + + private final ApplicationId appId; + private final FlowObjectiveService flowObjectiveService; + private final DriverService driverService; + private final String tunnelType; + + /** + * Creates a new rule installer. + * + * @param appId application id + * @param flowObjectiveService flow objective service + * @param driverService driver service + * @param tunnelType tunnel type + */ + public CordVtnRuleInstaller(ApplicationId appId, + FlowObjectiveService flowObjectiveService, + DriverService driverService, + String tunnelType) { + this.appId = appId; + this.flowObjectiveService = flowObjectiveService; + this.driverService = driverService; + this.tunnelType = checkNotNull(tunnelType); + } + + /** + * Installs flow rules for tunnel in traffic. + * + * @param deviceId device id to install flow rules + * @param inPort in port + * @param dstInfos list of destination info + */ + public void installFlowRulesTunnelIn(DeviceId deviceId, Port inPort, List dstInfos) { + dstInfos.stream().forEach(dstInfo -> { + ForwardingObjective.Builder fBuilder = vtnRulesSameNode(inPort, dstInfo); + if (fBuilder != null) { + flowObjectiveService.forward(deviceId, fBuilder.add()); + } + }); + } + + /** + * Installs flow rules for local in traffic. + * + * @param deviceId device id to install flow rules + * @param inPort in port + * @param dstInfos list of destination info + */ + public void installFlowRulesLocalIn(DeviceId deviceId, Port inPort, List dstInfos) { + dstInfos.stream().forEach(dstInfo -> { + ForwardingObjective.Builder fBuilder = isTunnelPort(dstInfo.output()) ? + vtnRulesRemoteNode(deviceId, inPort, dstInfo) : vtnRulesSameNode(inPort, dstInfo); + + if (fBuilder != null) { + flowObjectiveService.forward(deviceId, fBuilder.add()); + } + }); + } + + /** + * Uninstalls flow rules associated with a given port from a given device. + * + * @param deviceId device id + * @param inPort port associated with removed host + * @param dstInfos list of destination info + */ + public void uninstallFlowRules(DeviceId deviceId, Port inPort, List dstInfos) { + dstInfos.stream().forEach(dstInfo -> { + ForwardingObjective.Builder fBuilder = isTunnelPort(dstInfo.output()) ? + vtnRulesRemoteNode(deviceId, inPort, dstInfo) : vtnRulesSameNode(inPort, dstInfo); + + if (fBuilder != null) { + flowObjectiveService.forward(deviceId, fBuilder.remove()); + } + }); + } + + /** + * Returns forwarding objective builder to provision basic virtual tenant network. + * This method cares for the traffics whose source and destination device is the same. + * + * @param inPort in port + * @param dstInfo destination information + * @return forwarding objective builder + */ + private ForwardingObjective.Builder vtnRulesSameNode(Port inPort, DestinationInfo dstInfo) { + checkArgument(inPort.element().id().equals(dstInfo.output().element().id())); + + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); + + sBuilder.matchInPort(inPort.number()) + .matchEthDst(dstInfo.mac()); + if (isTunnelPort(inPort)) { + sBuilder.matchTunnelId(dstInfo.tunnelId()); + } + + tBuilder.setOutput(dstInfo.output().number()); + + return DefaultForwardingObjective.builder() + .withSelector(sBuilder.build()) + .withTreatment(tBuilder.build()) + .withPriority(DEFAULT_PRIORITY) + .withFlag(ForwardingObjective.Flag.VERSATILE) + .fromApp(appId) + .makePermanent(); + } + + /** + * Returns forwarding objective builder to provision basic virtual tenant network. + * This method cares for the traffics whose source and destination is not the same. + * + * @param deviceId device id to install flow rules + * @param inPort in port + * @param dstInfo destination information + * @return forwarding objective, or null if it fails to build it + */ + private ForwardingObjective.Builder vtnRulesRemoteNode(DeviceId deviceId, Port inPort, DestinationInfo dstInfo) { + checkArgument(isTunnelPort(dstInfo.output())); + + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); + + ExtensionTreatment extTreatment = + getTunnelDstInstruction(deviceId, dstInfo.remoteIp().getIp4Address()); + if (extTreatment == null) { + return null; + } + + sBuilder.matchInPort(inPort.number()) + .matchEthDst(dstInfo.mac()); + + tBuilder.extension(extTreatment, deviceId) + .setTunnelId(dstInfo.tunnelId()) + .setOutput(dstInfo.output().number()); + + return DefaultForwardingObjective.builder() + .withSelector(sBuilder.build()) + .withTreatment(tBuilder.build()) + .withPriority(DEFAULT_PRIORITY) + .withFlag(ForwardingObjective.Flag.VERSATILE) + .fromApp(appId) + .makePermanent(); + } + + /** + * Checks if a given port is tunnel interface or not. + * It assumes the tunnel interface contains tunnelType string in its name. + * + * @param port port + * @return true if the port is tunnel interface, false otherwise. + */ + private boolean isTunnelPort(Port port) { + return port.annotations().value("portName").contains(tunnelType); + } + + /** + * Returns extension instruction to set tunnel destination. + * + * @param deviceId device id + * @param remoteIp tunnel destination address + * @return extension treatment or null if it fails to get instruction + */ + private ExtensionTreatment getTunnelDstInstruction(DeviceId deviceId, Ip4Address remoteIp) { + try { + Driver driver = driverService.getDriver(deviceId); + DriverHandler handler = new DefaultDriverHandler(new DefaultDriverData(driver, deviceId)); + ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class); + + ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type()); + treatment.setPropertyValue("tunnelDst", remoteIp); + + return treatment; + } catch (ItemNotFoundException | UnsupportedOperationException | ExtensionPropertyException e) { + log.error("Failed to get extension instruction to set tunnel dst {}", deviceId); + return null; + } + } +} diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DestinationInfo.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DestinationInfo.java new file mode 100644 index 00000000..290cc170 --- /dev/null +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DestinationInfo.java @@ -0,0 +1,190 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.cordvtn; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.net.Port; + +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Contains destination information. + */ +public final class DestinationInfo { + + private final Port output; + private final List ip; + private final MacAddress mac; + private final IpAddress remoteIp; + private final long tunnelId; + + /** + * Creates a new destination information. + * + * @param output output port + * @param ip destination ip address + * @param mac destination mac address + * @param remoteIp tunnel remote ip address + * @param tunnelId segment id + */ + public DestinationInfo(Port output, List ip, MacAddress mac, + IpAddress remoteIp, long tunnelId) { + this.output = checkNotNull(output); + this.ip = ip; + this.mac = mac; + this.remoteIp = remoteIp; + this.tunnelId = tunnelId; + } + + /** + * Returns output port. + * + * @return port + */ + public Port output() { + return output; + } + + /** + * Returns destination ip addresses. + * + * @return list of ip address + */ + public List ip() { + return ip; + } + + /** + * Returns destination mac address. + * + * @return mac address + */ + public MacAddress mac() { + return mac; + } + + /** + * Returns tunnel remote ip address. + * + * @return ip address + */ + public IpAddress remoteIp() { + return remoteIp; + } + + /** + * Returns tunnel id. + * + * @return tunnel id + */ + public long tunnelId() { + return tunnelId; + } + + /** + * Returns a new destination info builder. + * + * @return destination info builder + */ + public static DestinationInfo.Builder builder(Port output) { + return new Builder(output); + } + + /** + * DestinationInfo builder class. + */ + public static final class Builder { + + private final Port output; + private List ip; + private MacAddress mac; + private IpAddress remoteIp; + private long tunnelId; + + /** + * Creates a new destination information builder. + * + * @param output output port + */ + public Builder(Port output) { + this.output = checkNotNull(output, "Output port cannot be null"); + } + + /** + * Sets the destination ip address. + * + * @param ip ip address + * @return destination info builder + */ + public Builder setIp(List ip) { + this.ip = checkNotNull(ip, "IP cannot be null"); + return this; + } + + /** + * Sets the destination mac address. + * + * @param mac mac address + * @return destination info builder + */ + public Builder setMac(MacAddress mac) { + this.mac = checkNotNull(mac, "MAC address cannot be null"); + return this; + } + + /** + * Sets the tunnel remote ip address. + * + * @param remoteIp ip address + * @return destination info builder + */ + public Builder setRemoteIp(IpAddress remoteIp) { + this.remoteIp = checkNotNull(remoteIp, "Remote IP address cannot be null"); + return this; + } + + /** + * Sets the tunnel id. + * + * @param tunnelId tunnel id + * @return destination info builder + */ + public Builder setTunnelId(long tunnelId) { + this.tunnelId = checkNotNull(tunnelId, "Tunnel ID cannot be null"); + return this; + } + + /** + * Build a destination information. + * + * @return destination info object + */ + public DestinationInfo build() { + return new DestinationInfo(this); + } + } + + private DestinationInfo(Builder builder) { + output = builder.output; + ip = builder.ip; + mac = builder.mac; + remoteIp = builder.remoteIp; + tunnelId = builder.tunnelId; + } +} diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeAddCommand.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeAddCommand.java new file mode 100644 index 00000000..1b7d9866 --- /dev/null +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeAddCommand.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.cordvtn.cli; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.onlab.packet.IpAddress; +import org.onlab.packet.TpPort; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.cordvtn.CordVtnService; +import org.onosproject.cordvtn.CordVtnNode; +import org.onosproject.net.DeviceId; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Adds a new node to the service. + */ +@Command(scope = "onos", name = "cordvtn-node-add", + description = "Adds a new node to CORD VTN service") +public class CordVtnNodeAddCommand extends AbstractShellCommand { + + @Argument(index = 0, name = "hostname", description = "Hostname", + required = true, multiValued = false) + private String hostname = null; + + @Argument(index = 1, name = "ovsdb", + description = "OVSDB server listening address (ip:port)", + required = true, multiValued = false) + private String ovsdb = null; + + @Argument(index = 2, name = "bridgeId", + description = "Device ID of integration bridge", + required = true, multiValued = false) + private String bridgeId = null; + + @Override + protected void execute() { + checkArgument(ovsdb.contains(":"), "OVSDB address should be ip:port format"); + checkArgument(bridgeId.startsWith("of:"), "bridgeId should be of:dpid format"); + + CordVtnService service = AbstractShellCommand.get(CordVtnService.class); + String[] ipPort = ovsdb.split(":"); + CordVtnNode node = new CordVtnNode(hostname, + IpAddress.valueOf(ipPort[0]), + TpPort.tpPort(Integer.parseInt(ipPort[1])), + DeviceId.deviceId(bridgeId)); + service.addNode(node); + } +} diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeDeleteCommand.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeDeleteCommand.java new file mode 100644 index 00000000..0446fc6a --- /dev/null +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeDeleteCommand.java @@ -0,0 +1,57 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.cordvtn.cli; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.cordvtn.CordVtnService; +import org.onosproject.cordvtn.CordVtnNode; + +import java.util.NoSuchElementException; + +/** + * Deletes nodes from the service. + */ +@Command(scope = "onos", name = "cordvtn-node-delete", + description = "Deletes nodes from CORD VTN service") +public class CordVtnNodeDeleteCommand extends AbstractShellCommand { + + @Argument(index = 0, name = "hostnames", description = "Hostname(s)", + required = true, multiValued = true) + private String[] hostnames = null; + + @Override + protected void execute() { + CordVtnService service = AbstractShellCommand.get(CordVtnService.class); + + for (String hostname : hostnames) { + CordVtnNode node; + try { + node = service.getNodes() + .stream() + .filter(n -> n.hostname().equals(hostname)) + .findFirst().get(); + } catch (NoSuchElementException e) { + print("Unable to find %s", hostname); + continue; + } + + service.deleteNode(node); + } + } +} diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeInitCommand.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeInitCommand.java new file mode 100644 index 00000000..dd77a9c3 --- /dev/null +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeInitCommand.java @@ -0,0 +1,57 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.cordvtn.cli; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.cordvtn.CordVtnService; +import org.onosproject.cordvtn.CordVtnNode; + +import java.util.NoSuchElementException; + +/** + * Initializes nodes for CordVtn service. + */ +@Command(scope = "onos", name = "cordvtn-node-init", + description = "Initializes nodes for CORD VTN service") +public class CordVtnNodeInitCommand extends AbstractShellCommand { + + @Argument(index = 0, name = "hostnames", description = "Hostname(s)", + required = true, multiValued = true) + private String[] hostnames = null; + + @Override + protected void execute() { + CordVtnService service = AbstractShellCommand.get(CordVtnService.class); + + for (String hostname : hostnames) { + CordVtnNode node; + try { + node = service.getNodes() + .stream() + .filter(n -> n.hostname().equals(hostname)) + .findFirst().get(); + } catch (NoSuchElementException e) { + print("Unable to find %s", hostname); + continue; + } + + service.initNode(node); + } + } +} diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeListCommand.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeListCommand.java new file mode 100644 index 00000000..83e58598 --- /dev/null +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeListCommand.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.cordvtn.cli; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.cordvtn.CordVtnService; +import org.onosproject.cordvtn.CordVtnNode; + +import java.util.Collections; +import java.util.List; + +/** + * Lists all nodes registered to the service. + */ +@Command(scope = "onos", name = "cordvtn-nodes", + description = "Lists all nodes registered in CORD VTN service") +public class CordVtnNodeListCommand extends AbstractShellCommand { + + @Override + protected void execute() { + CordVtnService service = AbstractShellCommand.get(CordVtnService.class); + List nodes = service.getNodes(); + Collections.sort(nodes, CordVtnNode.CORDVTN_NODE_COMPARATOR); + + if (outputJson()) { + print("%s", json(service, nodes)); + } else { + for (CordVtnNode node : nodes) { + print("hostname=%s, ovsdb=%s, br-int=%s, init=%s", + node.hostname(), + node.ovsdbIp().toString() + ":" + node.ovsdbPort().toString(), + node.intBrId().toString(), + getState(service, node)); + } + print("Total %s nodes", service.getNodeCount()); + } + } + + private JsonNode json(CordVtnService service, List nodes) { + ObjectMapper mapper = new ObjectMapper(); + ArrayNode result = mapper.createArrayNode(); + for (CordVtnNode node : nodes) { + String ipPort = node.ovsdbIp().toString() + ":" + node.ovsdbPort().toString(); + result.add(mapper.createObjectNode() + .put("hostname", node.hostname()) + .put("ovsdb", ipPort) + .put("brInt", node.intBrId().toString()) + .put("init", getState(service, node))); + } + return result; + } + + private String getState(CordVtnService service, CordVtnNode node) { + return service.getNodeInitState(node) ? "COMPLETE" : "INCOMPLETE"; + } +} diff --git a/framework/src/onos/apps/dhcp/app/features.xml b/framework/src/onos/apps/dhcp/app/features.xml index 0b277dea..496cf80f 100644 --- a/framework/src/onos/apps/dhcp/app/features.xml +++ b/framework/src/onos/apps/dhcp/app/features.xml @@ -15,7 +15,6 @@ ~ limitations under the License. --> - mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features onos-api diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java new file mode 100644 index 00000000..cd8149ea --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java @@ -0,0 +1,169 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.dhcp.rest; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Lists; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.MacAddress; +import org.onosproject.dhcp.DhcpService; +import org.onosproject.dhcp.IpAssignment; +import org.onosproject.net.HostId; +import org.onosproject.rest.AbstractWebResource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +/** + * Manage DHCP address assignments. + */ +@Path("dhcp") +public class DhcpWebResource extends AbstractWebResource { + + final DhcpService service = get(DhcpService.class); + + /** + * Get DHCP server configuration data. + * Shows lease, renewal and rebinding times in seconds. + * + * @return 200 OK + * @rsModel DhcpConfigGet + */ + @GET + @Path("config") + public Response getConfigs() { + DhcpService service = get(DhcpService.class); + ObjectNode node = mapper().createObjectNode() + .put("leaseTime", service.getLeaseTime()) + .put("renewalTime", service.getRenewalTime()) + .put("rebindingTime", service.getRebindingTime()); + return ok(node.toString()).build(); + } + + /** + * Get all MAC/IP mappings. + * Shows all MAC/IP mappings held by the DHCP server. + * + * @rsModel DhcpConfigGetMappings + * @return 200 OK + */ + @GET + @Path("mappings") + public Response listMappings() { + ObjectNode root = mapper().createObjectNode(); + + final Map intents = service.listMapping(); + ArrayNode arrayNode = root.putArray("mappings"); + intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() + .put("host", i.getKey().toString()) + .put("ip", i.getValue().ipAddress().toString()))); + + return ok(root.toString()).build(); + } + + + /** + * Get all available IPs. + * Shows all the IPs in the free pool of the DHCP Server. + * + * @rsModel DhcpConfigGetAvailable + * @return 200 OK + */ + @GET + @Path("available") + public Response listAvailableIPs() { + final Iterable availableIPList = service.getAvailableIPs(); + + final ObjectNode root = mapper().createObjectNode(); + ArrayNode arrayNode = root.putArray("availableIP"); + availableIPList.forEach(i -> arrayNode.add(i.toString())); + return ok(root.toString()).build(); + } + + /** + * Post a new static MAC/IP binding. + * Registers a static binding to the DHCP server, and displays the current set of bindings. + * + * @rsModel DhcpConfigPut + * @param stream JSON stream + * @return 200 OK + */ + @POST + @Path("mappings") + @Consumes(MediaType.APPLICATION_JSON) + public Response setMapping(InputStream stream) { + ObjectNode root = mapper().createObjectNode(); + try { + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); + JsonNode macID = jsonTree.get("mac"); + JsonNode ip = jsonTree.get("ip"); + if (macID != null && ip != null) { + + if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()), + Ip4Address.valueOf(ip.asText()), + false, Lists.newArrayList())) { + throw new IllegalArgumentException("Static Mapping Failed. " + + "The IP maybe unavailable."); + } + } + + final Map intents = service.listMapping(); + ArrayNode arrayNode = root.putArray("mappings"); + intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() + .put("host", i.getKey().toString()) + .put("ip", i.getValue().ipAddress().toString()))); + } catch (IOException e) { + throw new IllegalArgumentException(e.getMessage()); + } + return ok(root.toString()).build(); + } + + /** + * Delete a static MAC/IP binding. + * Removes a static binding from the DHCP Server, and displays the current set of bindings. + * + * @param macID mac address identifier + * @return 200 OK + */ + @DELETE + @Path("mappings/{macID}") + public Response deleteMapping(@PathParam("macID") String macID) { + + ObjectNode root = mapper().createObjectNode(); + + if (!service.removeStaticMapping(MacAddress.valueOf(macID))) { + throw new IllegalArgumentException("Static Mapping Removal Failed."); + } + final Map intents = service.listMapping(); + ArrayNode arrayNode = root.putArray("mappings"); + intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() + .put("host", i.getKey().toString()) + .put("ip", i.getValue().ipAddress().toString()))); + + return ok(root.toString()).build(); + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGet.json b/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGet.json new file mode 100644 index 00000000..9e451b30 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGet.json @@ -0,0 +1,26 @@ +{ + "type": "object", + "required": [ + "leaseTime", + "renewalTime", + "rebindingTime" + ], + "properties": { + "leaseTime": { + "type": "integer", + "format": "int64", + "example": "250" + }, + "renewalTime": { + "type": "integer", + "format": "int64", + "example": "250" + }, + "rebindingTime": { + "type": "integer", + "format": "int64", + "example": "250" + } + } +} + diff --git a/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGetAvailable.json b/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGetAvailable.json new file mode 100644 index 00000000..2dcb91d5 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGetAvailable.json @@ -0,0 +1,16 @@ +{ + "type": "object", + "required": [ + "availableIp" + ], + "properties": { + "availableIp": { + "type": "array", + "items": { + "type": "string" + }, + "example": "[127.0.0.1]" + } + } +} + diff --git a/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGetMappings.json b/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGetMappings.json new file mode 100644 index 00000000..c4d17f66 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigGetMappings.json @@ -0,0 +1,16 @@ +{ + "type": "object", + "required": [ + "mappings" + ], + "properties": { + "mappings": { + "type": "array", + "items": { + "type": "string" + }, + "example": "[]" + } + } +} + diff --git a/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigPut.json b/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigPut.json new file mode 100644 index 00000000..a8eb5378 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/definitions/DhcpConfigPut.json @@ -0,0 +1,17 @@ +{ + "type": "object", + "required": [ + "mac", + "ip"], + "properties": { + "mac": { + "type": "String", + "example": "be:48:89:d5:75:59" + }, + "ip": { + "type": "String", + "example": "10.128.12.4" + } + } +} + diff --git a/framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java b/framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java index f5bd1e01..2b9a2a54 100644 --- a/framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java +++ b/framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java @@ -168,7 +168,7 @@ public class McastForwarding { * ingress port would be a specific device. */ McastRoute entry = mrib.findBestMatch(spfx, gpfx); - if (entry == null || entry.getSaddr().equals(IPv4.fromIPv4Address(0))) { + if (entry == null || entry.getSaddr().address().isZero()) { /* * Create an entry that we can fast drop. diff --git a/framework/src/onos/apps/olt/src/main/java/org/onosproject/olt/Olt.java b/framework/src/onos/apps/olt/src/main/java/org/onosproject/olt/Olt.java new file mode 100644 index 00000000..ffc4705a --- /dev/null +++ b/framework/src/onos/apps/olt/src/main/java/org/onosproject/olt/Olt.java @@ -0,0 +1,359 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.olt; + +import com.google.common.base.Strings; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Modified; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.VlanId; +import org.onlab.util.Tools; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.net.config.ConfigFactory; +import org.onosproject.net.config.NetworkConfigEvent; +import org.onosproject.net.config.NetworkConfigListener; +import org.onosproject.net.config.NetworkConfigRegistry; +import org.onosproject.net.config.basics.SubjectFactories; +import org.onosproject.net.device.DeviceEvent; +import org.onosproject.net.device.DeviceListener; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; + +import java.util.Dictionary; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Provisions rules on access devices. + */ +@Service +@Component(immediate = true) +public class Olt implements AccessDeviceService { + private final Logger log = getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FlowObjectiveService flowObjectiveService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected NetworkConfigRegistry networkConfig; + + private final DeviceListener deviceListener = new InternalDeviceListener(); + + private ApplicationId appId; + + private static final VlanId DEFAULT_VLAN = VlanId.vlanId((short) 0); + public static final int OFFSET = 200; + + public static final int UPLINK_PORT = 129; + public static final int GFAST_UPLINK_PORT = 100; + + public static final String OLT_DEVICE = "of:90e2ba82f97791e9"; + public static final String GFAST_DEVICE = "of:0011223344551357"; + + @Property(name = "uplinkPort", intValue = UPLINK_PORT, + label = "The OLT's uplink port number") + private int uplinkPort = UPLINK_PORT; + + @Property(name = "gfastUplink", intValue = GFAST_UPLINK_PORT, + label = "The OLT's uplink port number") + private int gfastUplink = GFAST_UPLINK_PORT; + + //TODO: replace this with an annotation lookup + @Property(name = "oltDevice", value = OLT_DEVICE, + label = "The OLT device id") + private String oltDevice = OLT_DEVICE; + + @Property(name = "gfastDevice", value = GFAST_DEVICE, + label = "The gfast device id") + private String gfastDevice = GFAST_DEVICE; + + private Map oltData = new ConcurrentHashMap<>(); + + private InternalNetworkConfigListener configListener = + new InternalNetworkConfigListener(); + private static final Class CONFIG_CLASS = + AccessDeviceConfig.class; + + private ConfigFactory configFactory = + new ConfigFactory( + SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessDevice") { + @Override + public AccessDeviceConfig createConfig() { + return new AccessDeviceConfig(); + } + }; + + @Activate + public void activate() { + appId = coreService.registerApplication("org.onosproject.olt"); + + networkConfig.registerConfigFactory(configFactory); + networkConfig.addListener(configListener); + + networkConfig.getSubjects(DeviceId.class, AccessDeviceConfig.class).forEach( + subject -> { + AccessDeviceConfig config = networkConfig.getConfig(subject, AccessDeviceConfig.class); + if (config != null) { + AccessDeviceData data = config.getOlt(); + oltData.put(data.deviceId(), data); + } + } + ); + + /*deviceService.addListener(deviceListener); + + deviceService.getPorts(DeviceId.deviceId(oltDevice)).stream().forEach( + port -> { + if (!port.number().isLogical() && port.isEnabled()) { + short vlanId = fetchVlanId(port.number()); + if (vlanId > 0) { + provisionVlanOnPort(oltDevice, uplinkPort, port.number(), (short) 7); + provisionVlanOnPort(oltDevice, uplinkPort, port.number(), vlanId); + } + } + } + );*/ + + + deviceService.getPorts(DeviceId.deviceId(gfastDevice)).stream() + .filter(port -> !port.number().isLogical()) + .filter(Port::isEnabled) + .forEach(port -> { + short vlanId = (short) (fetchVlanId(port.number()) + OFFSET); + if (vlanId > 0) { + provisionVlanOnPort(gfastDevice, gfastUplink, port.number(), vlanId); + } + } + ); + log.info("Started with Application ID {}", appId.id()); + } + + @Deactivate + public void deactivate() { + networkConfig.removeListener(configListener); + networkConfig.unregisterConfigFactory(configFactory); + log.info("Stopped"); + } + + @Modified + public void modified(ComponentContext context) { + Dictionary properties = context.getProperties(); + + String s = Tools.get(properties, "uplinkPort"); + uplinkPort = Strings.isNullOrEmpty(s) ? UPLINK_PORT : Integer.parseInt(s); + + s = Tools.get(properties, "oltDevice"); + oltDevice = Strings.isNullOrEmpty(s) ? OLT_DEVICE : s; + } + + private short fetchVlanId(PortNumber port) { + long p = port.toLong() + OFFSET; + if (p > 4095) { + log.warn("Port Number {} exceeds vlan max", port); + return -1; + } + return (short) p; + } + + private void provisionVlanOnPort(String deviceId, int uplinkPort, PortNumber p, short vlanId) { + DeviceId did = DeviceId.deviceId(deviceId); + + TrafficSelector upstream = DefaultTrafficSelector.builder() + .matchVlanId(VlanId.vlanId(vlanId)) + .matchInPort(p) + .build(); + + TrafficSelector downStream = DefaultTrafficSelector.builder() + .matchVlanId(VlanId.vlanId(vlanId)) + .matchInPort(PortNumber.portNumber(uplinkPort)) + .build(); + + TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(uplinkPort)) + .build(); + + TrafficTreatment downStreamTreatment = DefaultTrafficTreatment.builder() + .setOutput(p) + .build(); + + + ForwardingObjective upFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(upstream) + .fromApp(appId) + .withTreatment(upstreamTreatment) + .add(); + + ForwardingObjective downFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(downStream) + .fromApp(appId) + .withTreatment(downStreamTreatment) + .add(); + + flowObjectiveService.forward(did, upFwd); + flowObjectiveService.forward(did, downFwd); + } + + @Override + public void provisionSubscriber(ConnectPoint port, VlanId vlan) { + AccessDeviceData olt = oltData.get(port.deviceId()); + + if (olt == null) { + log.warn("No data found for OLT device {}", port.deviceId()); + return; + } + + provisionVlans(olt.deviceId(), olt.uplink(), port.port(), vlan, olt.vlan(), + olt.defaultVlan()); + } + + private void provisionVlans(DeviceId deviceId, PortNumber uplinkPort, + PortNumber subscriberPort, + VlanId subscriberVlan, VlanId deviceVlan, + Optional defaultVlan) { + + TrafficSelector upstream = DefaultTrafficSelector.builder() + .matchVlanId((defaultVlan.isPresent()) ? defaultVlan.get() : DEFAULT_VLAN) + .matchInPort(subscriberPort) + .build(); + + TrafficSelector downstream = DefaultTrafficSelector.builder() + .matchVlanId(deviceVlan) + .matchInPort(uplinkPort) + .build(); + + TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder() + .setVlanId(subscriberVlan) + .pushVlan() + .setVlanId(deviceVlan) + .setOutput(uplinkPort) + .build(); + + TrafficTreatment downstreamTreatment = DefaultTrafficTreatment.builder() + .popVlan() + .setVlanId((defaultVlan.isPresent()) ? defaultVlan.get() : DEFAULT_VLAN) + .setOutput(subscriberPort) + .build(); + + + ForwardingObjective upFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(upstream) + .fromApp(appId) + .withTreatment(upstreamTreatment) + .add(); + + ForwardingObjective downFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(downstream) + .fromApp(appId) + .withTreatment(downstreamTreatment) + .add(); + + flowObjectiveService.forward(deviceId, upFwd); + flowObjectiveService.forward(deviceId, downFwd); + } + + @Override + public void removeSubscriber(ConnectPoint port) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + private class InternalDeviceListener implements DeviceListener { + @Override + public void event(DeviceEvent event) { + DeviceId devId = DeviceId.deviceId(oltDevice); + switch (event.type()) { + case PORT_ADDED: + case PORT_UPDATED: + if (devId.equals(event.subject().id()) && event.port().isEnabled()) { + short vlanId = fetchVlanId(event.port().number()); + provisionVlanOnPort(gfastDevice, uplinkPort, event.port().number(), vlanId); + } + break; + case DEVICE_ADDED: + case DEVICE_UPDATED: + case DEVICE_REMOVED: + case DEVICE_SUSPENDED: + case DEVICE_AVAILABILITY_CHANGED: + case PORT_REMOVED: + case PORT_STATS_UPDATED: + default: + return; + } + } + } + + private class InternalNetworkConfigListener implements NetworkConfigListener { + @Override + public void event(NetworkConfigEvent event) { + switch (event.type()) { + + case CONFIG_ADDED: + case CONFIG_UPDATED: + if (event.configClass().equals(CONFIG_CLASS)) { + AccessDeviceConfig config = + networkConfig.getConfig((DeviceId) event.subject(), CONFIG_CLASS); + if (config != null) { + oltData.put(config.getOlt().deviceId(), config.getOlt()); + } + } + break; + case CONFIG_UNREGISTERED: + case CONFIG_REMOVED: + default: + break; + } + } + } + +} diff --git a/framework/src/onos/apps/openstackswitching/api/pom.xml b/framework/src/onos/apps/openstackswitching/api/pom.xml new file mode 100644 index 00000000..f5e6f94f --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/api/pom.xml @@ -0,0 +1,50 @@ + + + + 4.0.0 + + + org.onosproject + onos-openstackswitching + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-app-openstackswitching-api + bundle + + SONA Openstack Switching application API + + + + org.onosproject + onos-api + ${project.version} + + + org.osgi + org.osgi.compendium + + + org.osgi + org.osgi.core + + + + diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java b/framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java similarity index 96% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java rename to framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java index 7bfdf290..1b28d0c4 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java +++ b/framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java @@ -77,6 +77,11 @@ public final class OpenstackNetwork { return this.networkType; } + @Override + protected Object clone() throws CloneNotSupportedException { + return super.clone(); + } + public static final class Builder { private String name; private String tenantId; diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java b/framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java similarity index 94% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java rename to framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java index 4326b4fc..1613b597 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java +++ b/framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java @@ -19,6 +19,7 @@ import com.google.common.collect.Lists; import org.onlab.packet.Ip4Address; import org.onlab.packet.MacAddress; +import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -31,7 +32,8 @@ public final class OpenstackPort { public enum PortStatus { UP, - DOWN + DOWN, + ACTIVE } private PortStatus status; @@ -179,6 +181,16 @@ public final class OpenstackPort { // //} + @Override + public Object clone() { + OpenstackPort op = new OpenstackPort(this.status, this.name, this.adminStateUp, + this.networkId, this.tenantId, this.deviceOwner, this.macAddress, + (HashMap) this.fixedIps.clone(), this.id, + Collections.unmodifiableList(this.securityGroups), this.deviceId); + + return op; + } + /** * OpenstackPort Builder class. */ diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java b/framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java similarity index 90% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java rename to framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java index 39d783e3..bc536e88 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java +++ b/framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java @@ -15,6 +15,10 @@ */ package org.onosproject.openstackswitching; +import org.onlab.packet.Ip4Address; + +import java.util.List; + import static com.google.common.base.Preconditions.checkNotNull; /** @@ -26,13 +30,13 @@ public final class OpenstackSubnet { private boolean enableHhcp; private String networkId; private String tenantId; - private String dnsNameservers; + private List dnsNameservers; private String gatewayIp; private String cidr; private String id; private OpenstackSubnet(String name, boolean enableHhcp, String networkId, - String tenantId, String dnsNameservers, String gatewayIp, + String tenantId, List dnsNameservers, String gatewayIp, String cidr, String id) { this.name = name; this.enableHhcp = enableHhcp; @@ -69,7 +73,7 @@ public final class OpenstackSubnet { return tenantId; } - public String dnsNameservers() { + public List dnsNameservers() { return dnsNameservers; } @@ -85,8 +89,6 @@ public final class OpenstackSubnet { return id; } - // TODO : Implement the following functions when necessary - /** * OpenstackSubnet Builder class. * @@ -96,7 +98,7 @@ public final class OpenstackSubnet { private boolean enableDhcp; private String networkId; private String tenantId; - private String dnsNameservers; + private List dnsNameservers; private String gatewayIp; private String cidr; private String id; @@ -127,7 +129,7 @@ public final class OpenstackSubnet { return this; } - public Builder setDnsNameservers(String dnsNameservers) { + public Builder setDnsNameservers(List dnsNameservers) { this.dnsNameservers = dnsNameservers; return this; diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java b/framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java similarity index 57% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java rename to framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java index 3d40d51d..59b8db0c 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java +++ b/framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java @@ -15,8 +15,12 @@ */ package org.onosproject.openstackswitching; +import org.onosproject.net.Port; + +import java.util.Collection; + /** - * It handles port management REST API from Openstack for VMs. + * Handles port management REST API from Openstack for VMs. */ public interface OpenstackSwitchingService { @@ -40,16 +44,49 @@ public interface OpenstackSwitchingService { void updatePorts(); /** - * Store the network information created by openstack. + * Stores the network information created by openstack. * * @param openstackNetwork network information */ void createNetwork(OpenstackNetwork openstackNetwork); /** - * Store the subnet information created by openstack. + * Stores the subnet information created by openstack. * * @param openstackSubnet subnet information */ void createSubnet(OpenstackSubnet openstackSubnet); + + /** + * Returns port information list for the network ID given. + * + * @param networkId Network ID of the ports + * @return port information list + */ + Collection ports(String networkId); + + /** + * Returns port information for the port given. + * + * @param port port reference + * @return port information + */ + OpenstackPort port(Port port); + + /** + * Returns port information for the port ID given. + * + * @param portId Port ID + * @return port information + */ + OpenstackPort port(String portId); + + /** + * Returns network information list for the network ID given. + * + * @param networkId Network ID + * @return network information list + */ + OpenstackNetwork network(String networkId); + } diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/package-info.java b/framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/package-info.java similarity index 100% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/package-info.java rename to framework/src/onos/apps/openstackswitching/api/src/main/java/org/onosproject/openstackswitching/package-info.java diff --git a/framework/src/onos/apps/openstackswitching/app/app.xml b/framework/src/onos/apps/openstackswitching/app/app.xml new file mode 100644 index 00000000..e982b90d --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/app/app.xml @@ -0,0 +1,24 @@ + + + + ${project.description} + mvn:${project.groupId}/onos-app-openstackswitching/${project.version} + mvn:${project.groupId}/onos-app-dhcp-api/${project.version} + mvn:${project.groupId}/onos-app-dhcp/${project.version} + diff --git a/framework/src/onos/apps/openstackswitching/app/features.xml b/framework/src/onos/apps/openstackswitching/app/features.xml new file mode 100644 index 00000000..acb07b62 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/app/features.xml @@ -0,0 +1,28 @@ + + + + mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features + + onos-api + mvn:${project.groupId}/onos-app-openstackswitching/${project.version} + mvn:${project.groupId}/onos-app-dhcp-api/${project.version} + mvn:${project.groupId}/onos-app-dhcp/${project.version} + mvn:com.sun.jersey/jersey-client/1.19 + mvn:${project.groupId}/${project.artifactId}/${project.version} + + diff --git a/framework/src/onos/apps/openstackswitching/app/pom.xml b/framework/src/onos/apps/openstackswitching/app/pom.xml new file mode 100644 index 00000000..5460faef --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/app/pom.xml @@ -0,0 +1,137 @@ + + + + 4.0.0 + + + org.onosproject + onos-openstackswitching + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-app-openstackswitching + bundle + + SONA Openstack Switching applications + + 1.4.0-SNAPSHOT + org.onosproject.openstackswitching + /onos/openstackswitching + 1.0.0 + ONOS OpenStack Switching REST API + + APIs for receiving Neutron information. + + org.onosproject.openstackswitching.web + SKT, Inc. + + + + + + org.onosproject + onos-app-openstackswitching-api + ${project.version} + + + org.onosproject + onos-rest + ${project.version} + + + org.onosproject + onlab-rest + ${project.version} + + + javax.ws.rs + jsr311-api + 1.1.1 + + + com.sun.jersey + jersey-servlet + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-annotations + + + org.osgi + org.osgi.compendium + + + org.osgi + org.osgi.core + + + org.onosproject + onos-app-dhcp-api + ${project.version} + + + com.sun.jersey + jersey-client + 1.19 + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + <_wab>src/main/webapp/ + + ${project.groupId}.${project.artifactId} + + + org.slf4j, + org.osgi.framework, + javax.ws.rs, + javax.ws.rs.core, + com.sun.jersey.api.core, + com.sun.jersey.api.client, + com.sun.jersey.spi.container.servlet, + com.sun.jersey.server.impl.container.servlet, + com.fasterxml.jackson.databind, + com.fasterxml.jackson.databind.node, + com.fasterxml.jackson.core, + org.apache.karaf.shell.commands, + com.google.common.*, + org.onlab.packet.*, + org.onosproject.* + + ${web.context} + + + + + + + + diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java similarity index 85% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java rename to framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java index 0c139d8d..944d12a1 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java @@ -28,26 +28,27 @@ import org.onosproject.net.packet.PacketService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; -import java.util.Map; + +import static com.google.common.base.Preconditions.checkNotNull; /** - * It handles ARP packet from VMs. + * Handles ARP packet from VMs. */ public class OpenstackArpHandler { private static Logger log = LoggerFactory .getLogger(OpenstackArpHandler.class); private PacketService packetService; - private Map openstackPortMap; + private OpenstackRestHandler restHandler; /** * Returns OpenstackArpHandler reference. * - * @param openstackPortMap - * @param packetService + * @param restHandler rest API handler reference + * @param packetService PacketService reference */ - public OpenstackArpHandler(Map openstackPortMap, PacketService packetService) { - this.openstackPortMap = openstackPortMap; + public OpenstackArpHandler(OpenstackRestHandler restHandler, PacketService packetService) { + this.restHandler = checkNotNull(restHandler); this.packetService = packetService; } @@ -68,8 +69,9 @@ public class OpenstackArpHandler { //Searches the Dst MAC Address based on openstackPortMap MacAddress macAddress = null; - OpenstackPort openstackPort = openstackPortMap.values().stream().filter(e -> e.fixedIps(). - containsValue(Ip4Address.valueOf(dstIPAddress))).findAny().orElse(null); + OpenstackPort openstackPort = restHandler.getPorts().stream(). + filter(e -> e.fixedIps().containsValue(Ip4Address.valueOf( + dstIPAddress))).findAny().orElse(null); if (openstackPort != null) { macAddress = openstackPort.macAddress(); diff --git a/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackRestHandler.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackRestHandler.java new file mode 100644 index 00000000..9065bc52 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackRestHandler.java @@ -0,0 +1,179 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openstackswitching; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Lists; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.WebResource; +import org.onosproject.openstackswitching.web.OpenstackNetworkCodec; +import org.onosproject.openstackswitching.web.OpenstackPortCodec; +import org.onosproject.openstackswitching.web.OpenstackSubnetCodec; +import org.slf4j.Logger; +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.net.MediaType.JSON_UTF_8; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Handles REST Calls to Openstack Neutron. + * + */ +public class OpenstackRestHandler { + + private final Logger log = getLogger(getClass()); + private String neutronUrl; + private String keystoneUrl; + private String tokenId; + private String userName; + private String pass; + + /** + * Creates OpenstackRestHandler instance. + * + * @param cfg OpenstackSwitchingConfig reference + */ + public OpenstackRestHandler(OpenstackSwitchingConfig cfg) { + this.neutronUrl = checkNotNull(cfg.neutronServer()); + this.keystoneUrl = checkNotNull(cfg.keystoneServer()); + this.userName = checkNotNull(cfg.userName()); + this.pass = checkNotNull(cfg.password()); + } + + /** + * Returns network information stored in Neutron. + * + * @return List of OpenstackNetwork + */ + public Collection getNetworks() { + + WebResource.Builder builder = getClientBuilder(neutronUrl + "networks"); + String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). + header("X-Auth-Token", getToken()).get(String.class); + + ObjectMapper mapper = new ObjectMapper(); + List openstackNetworks = Lists.newArrayList(); + try { + ObjectNode node = (ObjectNode) mapper.readTree(response); + ArrayNode networkList = (ArrayNode) node.path("networks"); + OpenstackNetworkCodec networkCodec = new OpenstackNetworkCodec(); + networkList.forEach(n -> openstackNetworks.add(networkCodec.decode((ObjectNode) n, null))); + } catch (IOException e) { + e.printStackTrace(); + } + + log.debug("networks response:" + response); + openstackNetworks.forEach(n -> log.debug("network ID: {}", n.id())); + + return openstackNetworks; + } + + /** + * Returns port information stored in Neutron. + * + * @return List of OpenstackPort + */ + public Collection getPorts() { + + WebResource.Builder builder = getClientBuilder(neutronUrl + "ports"); + String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). + header("X-Auth-Token", getToken()).get(String.class); + + ObjectMapper mapper = new ObjectMapper(); + List openstackPorts = Lists.newArrayList(); + try { + ObjectNode node = (ObjectNode) mapper.readTree(response); + ArrayNode portList = (ArrayNode) node.path("ports"); + OpenstackPortCodec portCodec = new OpenstackPortCodec(); + portList.forEach(p -> openstackPorts.add(portCodec.decode((ObjectNode) p, null))); + } catch (IOException e) { + e.printStackTrace(); + } + + log.debug("port response:" + response); + openstackPorts.forEach(n -> log.debug("port ID: {}", n.id())); + + return openstackPorts; + } + + /** + * Returns Subnet information in Neutron. + * + * @return List of OpenstackSubnet + */ + public Collection getSubnets() { + + WebResource.Builder builder = getClientBuilder(neutronUrl + "subnets"); + String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). + header("X-Auth-Token", getToken()).get(String.class); + + ObjectMapper mapper = new ObjectMapper(); + List subnets = Lists.newArrayList(); + try { + ObjectNode node = (ObjectNode) mapper.readTree(response); + ArrayNode subnetList = (ArrayNode) node.path("subnets"); + OpenstackSubnetCodec subnetCodec = new OpenstackSubnetCodec(); + subnetList.forEach(s -> subnets.add(subnetCodec.decode((ObjectNode) s, null))); + } catch (IOException e) { + e.printStackTrace(); + } + + log.debug("subnets response:" + response); + subnets.forEach(s -> log.debug("subnet ID: {}", s.id())); + + return subnets; + } + + private WebResource.Builder getClientBuilder(String uri) { + Client client = Client.create(); + WebResource resource = client.resource(uri); + return resource.accept(JSON_UTF_8.toString()) + .type(JSON_UTF_8.toString()); + } + + private String getToken() { + if (isTokenInvalid()) { + String request = "{\"auth\": {\"tenantName\": \"admin\", " + + "\"passwordCredentials\": {\"username\": \"" + + userName + "\",\"password\": \"" + pass + "\"}}}"; + WebResource.Builder builder = getClientBuilder(keystoneUrl + "tokens"); + String response = builder.accept(MediaType.APPLICATION_JSON).post(String.class, request); + + ObjectMapper mapper = new ObjectMapper(); + try { + ObjectNode node = (ObjectNode) mapper.readTree(response); + tokenId = node.path("access").path("token").path("id").asText(); + } catch (IOException e) { + e.printStackTrace(); + } + log.debug("token response:" + response); + } + + return tokenId; + } + + private boolean isTokenInvalid() { + //TODO: validation check for the existing token + return true; + } + +} diff --git a/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingConfig.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingConfig.java new file mode 100644 index 00000000..ba39ff66 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingConfig.java @@ -0,0 +1,127 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openstackswitching; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.config.Config; +import org.onosproject.net.config.basics.BasicElementConfig; + +/** + * Handles configuration for OpenstackSwitching app. + */ +public class OpenstackSwitchingConfig extends Config { + public static final String DONOTPUSH = "do_not_push_flows"; + public static final String NEUTRON_SERVER = "neutron_server"; + public static final String KEYSTONE_SERVER = "keystone_server"; + public static final String USER_NAME = "user_name"; + public static final String PASSWORD = "password"; + + /** + * Returns the flag whether the app pushes flows or not. + * + * @return the flag or false if not set + */ + public boolean doNotPushFlows() { + String flag = get(DONOTPUSH, "false"); + return Boolean.valueOf(flag); + } + + /** + * Returns the Neutron server IP address. + * + * @return Neutron server IP + */ + public String neutronServer() { + return get(NEUTRON_SERVER, ""); + } + + /** + * Returns the Keystone server IP address. + * + * @return Keystone server IP + */ + public String keystoneServer() { + return get(KEYSTONE_SERVER, ""); + } + + /** + * Returns the username for openstack. + * + * @return username for openstack + */ + public String userName() { + return get(USER_NAME, ""); + } + + /** + * Returns the password for openstack. + * + * @return password for openstack + */ + public String password() { + return get(PASSWORD, ""); + } + + /** + * Sets the flag whether the app pushes flows or not. + * + * @param flag the flag whether the app pushes flows or not + * @return self + */ + public BasicElementConfig doNotPushFlows(boolean flag) { + return (BasicElementConfig) setOrClear(DONOTPUSH, flag); + } + + /** + * Sets the neutron server IP address. + * + * @param url neutron server IP address + * @return itself + */ + public BasicElementConfig neutronServer(String url) { + return (BasicElementConfig) setOrClear(NEUTRON_SERVER, url); + } + + /** + * Sets the keystone server IP address. + * + * @param url keystone server IP address + * @return itself + */ + public BasicElementConfig keystoneServer(String url) { + return (BasicElementConfig) setOrClear(KEYSTONE_SERVER, url); + } + + /** + * Sets the username for openstack. + * + * @param username user name for openstack + * @return itself + */ + public BasicElementConfig userName(String username) { + return (BasicElementConfig) setOrClear(USER_NAME, username); + } + + /** + * Sets the password for openstack. + * + * @param password password for openstack + * @return itself + */ + public BasicElementConfig password(String password) { + return (BasicElementConfig) setOrClear(PASSWORD, password); + } +} diff --git a/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java new file mode 100644 index 00000000..d881d81c --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java @@ -0,0 +1,374 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openstackswitching; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.Ethernet; +import org.onlab.packet.Ip4Address; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.dhcp.DhcpService; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.config.ConfigFactory; +import org.onosproject.net.config.NetworkConfigEvent; +import org.onosproject.net.config.NetworkConfigListener; +import org.onosproject.net.config.NetworkConfigRegistry; +import org.onosproject.net.device.DeviceEvent; +import org.onosproject.net.device.DeviceListener; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.driver.DriverService; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.packet.InboundPacket; +import org.onosproject.net.packet.PacketContext; +import org.onosproject.net.packet.PacketProcessor; +import org.onosproject.net.packet.PacketService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.List; +import java.util.Collection; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + +import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; + +@SuppressWarnings("ALL") +@Service +@Component(immediate = true) +/** + * Populates forwarding rules for VMs created by Openstack. + */ +public class OpenstackSwitchingManager implements OpenstackSwitchingService { + + private static Logger log = LoggerFactory + .getLogger(OpenstackSwitchingManager.class); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PacketService packetService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FlowObjectiveService flowObjectiveService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DhcpService dhcpService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected NetworkConfigRegistry cfgService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DriverService driverService; + + private ApplicationId appId; + private boolean doNotPushFlows; + private Ip4Address neutronServer; + private Ip4Address keystoneServer; + private String userName; + private String password; + private OpenstackArpHandler arpHandler; + private OpenstackRestHandler restHandler; + + private ExecutorService deviceEventExcutorService = Executors.newFixedThreadPool(10); + + private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor(); + private InternalDeviceListener internalDeviceListener = new InternalDeviceListener(); + private InternalConfigListener internalConfigListener = new InternalConfigListener(); + private final Set factories = ImmutableSet.of( + new ConfigFactory(APP_SUBJECT_FACTORY, + OpenstackSwitchingConfig.class, + "openstackswitching") { + @Override + public OpenstackSwitchingConfig createConfig() { + return new OpenstackSwitchingConfig(); + } + } + ); + + @Activate + protected void activate() { + appId = coreService + .registerApplication("org.onosproject.openstackswitching"); + + factories.forEach(cfgService::registerConfigFactory); + packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1)); + deviceService.addListener(internalDeviceListener); + cfgService.addListener(internalConfigListener); + + internalConfigListener.configureNetwork(); + + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + packetService.removeProcessor(internalPacketProcessor); + deviceService.removeListener(internalDeviceListener); + cfgService.removeListener(internalConfigListener); + + deviceEventExcutorService.shutdown(); + + log.info("Stopped"); + } + + @Override + public void createPorts(OpenstackPort openstackPort) { + registerDhcpInfo(openstackPort); + } + + @Override + public void deletePorts() { + + } + + @Override + public void updatePorts() { + + } + + @Override + public void createNetwork(OpenstackNetwork openstackNetwork) { + } + + @Override + public void createSubnet(OpenstackSubnet openstackSubnet) { + } + + @Override + public Collection ports(String networkId) { + Collection ports = restHandler.getPorts(); + List portList = ports.stream() + .filter(p -> p.networkId().equals(networkId)) + .collect(Collectors.toList()); + + return portList; + } + + @Override + public OpenstackPort port(Port port) { + Collection ports = restHandler.getPorts(); + String uuid = port.annotations().value("portName").substring(3); + return ports.stream() + .filter(p -> p.id().startsWith(uuid)) + .findFirst().orElse(null); + } + + @Override + public OpenstackPort port(String portId) { + Collection ports = restHandler.getPorts(); + return ports.stream() + .filter(p -> p.id().equals(portId)) + .findFirst().orElse(null); + } + + @Override + public OpenstackNetwork network(String networkId) { + Collection networks = restHandler.getNetworks(); + return networks.stream() + .filter(n -> n.id().equals(networkId)) + .findFirst().orElse(null); + } + + private void processDeviceAdded(Device device) { + log.debug("device {} is added", device.id()); + } + + private void processPortAdded(Device device, Port port) { + if (!port.annotations().value("portName").equals("vxlan")) { + OpenstackSwitchingRulePopulator rulePopulator = + new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, + deviceService, restHandler, driverService); + rulePopulator.populateSwitchingRules(device, port); + } + } + + private void processPortRemoved(Device device, Port port) { + // TODO: Remove flow rules for the VM removed + log.debug("port {} is removed", port.toString()); + } + + private void registerDhcpInfo(OpenstackPort openstackPort) { + Ip4Address ip4Address; + Ip4Address subnetMask; + Ip4Address dhcpServer; + Ip4Address gatewayIPAddress; + Ip4Address domainServer; + OpenstackSubnet openstackSubnet; + + ip4Address = (Ip4Address) openstackPort.fixedIps().values().toArray()[0]; + + openstackSubnet = restHandler.getSubnets().stream() + .filter(n -> n.networkId().equals(openstackPort.networkId())) + .findFirst().get(); + + subnetMask = Ip4Address.valueOf(buildSubnetMask(openstackSubnet.cidr())); + gatewayIPAddress = Ip4Address.valueOf(openstackSubnet.gatewayIp()); + dhcpServer = gatewayIPAddress; + // TODO: supports multiple DNS servers + if (openstackSubnet.dnsNameservers().isEmpty()) { + domainServer = Ip4Address.valueOf("8.8.8.8"); + } else { + domainServer = openstackSubnet.dnsNameservers().get(0); + } + List options = Lists.newArrayList(); + options.add(subnetMask); + options.add(dhcpServer); + options.add(gatewayIPAddress); + options.add(domainServer); + + dhcpService.setStaticMapping(openstackPort.macAddress(), ip4Address, true, options); + } + + private byte[] buildSubnetMask(String cidr) { + int prefix; + String[] parts = cidr.split("/"); + prefix = Integer.parseInt(parts[1]); + int mask = 0xffffffff << (32 - prefix); + byte[] bytes = new byte[]{(byte) (mask >>> 24), + (byte) (mask >> 16 & 0xff), (byte) (mask >> 8 & 0xff), (byte) (mask & 0xff)}; + + return bytes; + } + + + + private class InternalPacketProcessor implements PacketProcessor { + + @Override + public void process(PacketContext context) { + + if (context.isHandled()) { + return; + } + + InboundPacket pkt = context.inPacket(); + Ethernet ethernet = pkt.parsed(); + + if (ethernet.getEtherType() == Ethernet.TYPE_ARP) { + arpHandler.processPacketIn(pkt); + } + } + } + + private class InternalDeviceListener implements DeviceListener { + + @Override + public void event(DeviceEvent deviceEvent) { + deviceEventExcutorService.execute(new InternalEventHandler(deviceEvent)); + } + } + + private class InternalEventHandler implements Runnable { + + volatile DeviceEvent deviceEvent; + + InternalEventHandler(DeviceEvent deviceEvent) { + this.deviceEvent = deviceEvent; + } + + @Override + public void run() { + + if (doNotPushFlows) { + return; + } + + switch (deviceEvent.type()) { + case DEVICE_ADDED: + processDeviceAdded((Device) deviceEvent.subject()); + break; + case DEVICE_UPDATED: + Port port = (Port) deviceEvent.subject(); + if (port.isEnabled()) { + processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); + } + break; + case DEVICE_AVAILABILITY_CHANGED: + Device device = (Device) deviceEvent.subject(); + if (deviceService.isAvailable(device.id())) { + processDeviceAdded(device); + } + break; + case PORT_ADDED: + processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); + break; + case PORT_UPDATED: + processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); + break; + case PORT_REMOVED: + processPortRemoved((Device) deviceEvent.subject(), deviceEvent.port()); + break; + default: + break; + } + } + } + + private class InternalConfigListener implements NetworkConfigListener { + + public void configureNetwork() { + OpenstackSwitchingConfig cfg = + cfgService.getConfig(appId, OpenstackSwitchingConfig.class); + if (cfg == null) { + log.error("There is no openstack server information in config."); + return; + } + doNotPushFlows = cfg.doNotPushFlows(); + restHandler = new OpenstackRestHandler(cfg); + arpHandler = new OpenstackArpHandler(restHandler, packetService); + } + + @Override + public void event(NetworkConfigEvent event) { + if (((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || + event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) && + event.configClass().equals(OpenstackSwitchingConfig.class)) { + configureNetwork(); + } + } + + } + + private final class PortInfo { + DeviceId deviceId; + String portName; + Ip4Address fixedIp; + Ip4Address hostIp; + + private PortInfo(DeviceId deviceId, String portName, Ip4Address fixedIp, + Ip4Address hostIp) { + this.deviceId = deviceId; + this.portName = portName; + this.fixedIp = fixedIp; + this.hostIp = hostIp; + } + } + +} \ No newline at end of file diff --git a/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java new file mode 100644 index 00000000..38c03638 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java @@ -0,0 +1,307 @@ +/* +* Copyright 2015 Open Networking Laboratory +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.onosproject.openstackswitching; + +import org.onlab.packet.Ethernet; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.net.behaviour.ExtensionTreatmentResolver; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.driver.DefaultDriverData; +import org.onosproject.net.driver.DefaultDriverHandler; +import org.onosproject.net.driver.Driver; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.net.driver.DriverService; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatment; +import org.onosproject.net.flow.instructions.ExtensionPropertyException; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; + +/** + * Populates switching flow rules. + */ +public class OpenstackSwitchingRulePopulator { + + private static Logger log = LoggerFactory + .getLogger(OpenstackSwitchingRulePopulator.class); + private static final int SWITCHING_RULE_PRIORITY = 50000; + + private FlowObjectiveService flowObjectiveService; + private DriverService driverService; + private DeviceService deviceService; + private OpenstackRestHandler restHandler; + private ApplicationId appId; + + private Collection openstackNetworkList; + private Collection openstackPortList; + + /** + * Creates OpenstackSwitchingRulPopulator. + * + * @param appId application id + * @param flowObjectiveService FlowObjectiveService reference + * @param deviceService DeviceService reference + * @param driverService DriverService reference + */ + public OpenstackSwitchingRulePopulator(ApplicationId appId, + FlowObjectiveService flowObjectiveService, + DeviceService deviceService, + OpenstackRestHandler restHandler, + DriverService driverService) { + this.flowObjectiveService = flowObjectiveService; + this.deviceService = deviceService; + this.driverService = driverService; + this.restHandler = restHandler; + this.appId = appId; + + openstackNetworkList = restHandler.getNetworks(); + openstackPortList = restHandler.getPorts(); + } + + /** + * Populates flow rules for the VM created. + * + * @param device device to populate rules to + * @param port port for the VM created + */ + public void populateSwitchingRules(Device device, Port port) { + populateFlowRulesForTrafficToSameCnode(device, port); + populateFlowRulesForTrafficToDifferentCnode(device, port); + } + + /** + * Populates the flow rules for traffic to VMs in the same Cnode as the sender. + * + * @param device device to put the rules + * @param port port info of the VM + */ + private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) { + Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName")); + if (vmIp != null) { + setFlowRuleForVMsInSameCnode(vmIp, device.id(), port); + } + } + + /** + * Populates the flow rules for traffic to VMs in different Cnode using + * Nicira extention. + * + * @param device device to put rules + * @param port port information of the VM + */ + private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) { + String portName = port.annotations().value("portName"); + String channelId = device.annotations().value("channelId"); + Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]); + Ip4Address fixedIp = getFixedIpAddressForPort(portName); + MacAddress vmMac = getVmMacAddressForPort(portName); + String vni = getVniForPort(portName); + deviceService.getAvailableDevices().forEach(d -> { + if (!d.equals(device)) { + deviceService.getPorts(d.id()).forEach(p -> { + String pName = p.annotations().value("portName"); + if (!p.equals(port) && vni.equals(getVniForPort(pName))) { + String cidx = d.annotations().value("channelId"); + Ip4Address hostIpx = Ip4Address.valueOf(cidx.split(":")[0]); + MacAddress vmMacx = getVmMacAddressForPort(pName); + Ip4Address fixedIpx = getFixedIpAddressForPort(pName); + + setVxLanFlowRule(vni, device.id(), hostIpx, fixedIpx, vmMacx); + setVxLanFlowRule(vni, d.id(), hostIpAddress, fixedIp, vmMac); + } + }); + } + }); + } + + /** + * Returns the VNI of the VM of the port. + * + * @param portName VM port + * @return VNI + */ + private String getVniForPort(String portName) { + String uuid = portName.substring(3); + OpenstackPort port = openstackPortList.stream() + .filter(p -> p.id().startsWith(uuid)) + .findAny().orElse(null); + if (port == null) { + log.warn("No port information for port {}", portName); + return null; + } + + OpenstackNetwork network = openstackNetworkList.stream() + .filter(n -> n.id().equals(port.networkId())) + .findAny().orElse(null); + if (network == null) { + log.warn("No VNI information for network {}", port.networkId()); + return null; + } + + return network.segmentId(); + } + + /** + * Returns the Fixed IP address of the VM. + * + * @param portName VM port info + * @return IP address of the VM + */ + private Ip4Address getFixedIpAddressForPort(String portName) { + + String uuid = portName.substring(3); + OpenstackPort port = openstackPortList.stream() + .filter(p -> p.id().startsWith(uuid)) + .findFirst().orElse(null); + + if (port == null) { + log.error("There is no port information for port name {}", portName); + return null; + } + + if (port.fixedIps().isEmpty()) { + log.error("There is no fixed IP info in the port information"); + return null; + } + + return (Ip4Address) port.fixedIps().values().toArray()[0]; + } + + /** + * Returns the MAC address of the VM of the port. + * + * @param portName VM port + * @return MAC address of the VM + */ + private MacAddress getVmMacAddressForPort(String portName) { + + String uuid = portName.substring(3); + OpenstackPort port = openstackPortList.stream() + .filter(p -> p.id().startsWith(uuid)) + .findFirst().orElse(null); + + if (port == null) { + log.error("There is port information for port name {}", portName); + return null; + } + + return port.macAddress(); + } + + /** + * Sets the flow rules for traffic between VMs in the same Cnode. + * + * @param ip4Address VM IP address + * @param id device ID to put rules + * @param port VM port + */ + private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id, + Port port) { + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); + + sBuilder.matchEthType(Ethernet.TYPE_IPV4) + .matchIPDst(ip4Address.toIpPrefix()); + tBuilder.setOutput(port.number()); + + ForwardingObjective fo = DefaultForwardingObjective.builder() + .withSelector(sBuilder.build()) + .withTreatment(tBuilder.build()) + .withPriority(SWITCHING_RULE_PRIORITY) + .withFlag(ForwardingObjective.Flag.VERSATILE) + .fromApp(appId) + .add(); + + flowObjectiveService.forward(id, fo); + } + + /** + * Sets the flow rules between traffic from VMs in different Cnode. + * + * @param vni VNI + * @param id device ID + * @param hostIp host IP of the VM + * @param vmIp fixed IP of the VM + * @param vmMac MAC address of the VM + */ + private void setVxLanFlowRule(String vni, DeviceId id, Ip4Address hostIp, + Ip4Address vmIp, MacAddress vmMac) { + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); + + sBuilder.matchEthType(Ethernet.TYPE_IPV4) + .matchIPDst(vmIp.toIpPrefix()); + tBuilder.setTunnelId(Long.parseLong(vni)) + .extension(buildNiciraExtenstion(id, hostIp), id) + .setOutput(getTunnelPort(id)); + + ForwardingObjective fo = DefaultForwardingObjective.builder() + .withSelector(sBuilder.build()) + .withTreatment(tBuilder.build()) + .withPriority(SWITCHING_RULE_PRIORITY) + .withFlag(ForwardingObjective.Flag.VERSATILE) + .fromApp(appId) + .add(); + + flowObjectiveService.forward(id, fo); + } + + private ExtensionTreatment buildNiciraExtenstion(DeviceId id, Ip4Address hostIp) { + Driver driver = driverService.getDriver(id); + DriverHandler driverHandler = new DefaultDriverHandler(new DefaultDriverData(driver, id)); + ExtensionTreatmentResolver resolver = driverHandler.behaviour(ExtensionTreatmentResolver.class); + + ExtensionTreatment extensionInstruction = + resolver.getExtensionInstruction( + ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type()); + + try { + extensionInstruction.setPropertyValue("tunnelDst", hostIp); + } catch (ExtensionPropertyException e) { + log.error("Error setting Nicira extension setting {}", e); + } + + return extensionInstruction; + } + + private PortNumber getTunnelPort(DeviceId id) { + Port port = deviceService.getPorts(id).stream() + .filter(p -> p.annotations().value("portName").equals("vxlan")) + .findAny().orElse(null); + + if (port == null) { + log.error("No TunnelPort was created."); + return null; + } + return port.number(); + } +} diff --git a/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/package-info.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/package-info.java new file mode 100644 index 00000000..cd50f912 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * OpenStack switch interface. + */ +package org.onosproject.openstackswitching; diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java similarity index 96% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java rename to framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java index fc1509d4..0a0b5dce 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java @@ -43,6 +43,9 @@ public class OpenstackNetworkCodec extends JsonCodec { public OpenstackNetwork decode(ObjectNode json, CodecContext context) { JsonNode networkInfo = json.get(NETWORK); + if (networkInfo == null) { + networkInfo = json; + } String name = networkInfo.path(NAME).asText(); String tenantId = networkInfo.path(TENANT_ID).asText(); diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java similarity index 55% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java rename to framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java index f4c401fb..bf04cc4d 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java @@ -15,48 +15,52 @@ */ package org.onosproject.openstackswitching.web; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.onosproject.openstackswitching.OpenstackNetwork; -import org.onosproject.openstackswitching.OpenstackSwitchingService; import org.onosproject.rest.AbstractWebResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.InputStream; +/** + * Handles REST API call of Neutron ML2 plugin. + */ @Path("networks") public class OpenstackNetworkWebResource extends AbstractWebResource { protected static final Logger log = LoggerFactory .getLogger(OpenstackNetworkWebResource.class); - private static final OpenstackNetworkCodec NETWORK_CODEC = new OpenstackNetworkCodec(); - @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response createNetwork(InputStream input) { - try { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode networkNode = (ObjectNode) mapper.readTree(input); + log.debug("REST API networks is called {}", input.toString()); + return Response.status(Response.Status.OK).build(); + } - OpenstackNetwork openstackNetwork = NETWORK_CODEC.decode(networkNode, this); + @PUT + @Path("{id}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response updateNetwork(InputStream input) { + log.debug("REST API networks is called {}", input.toString()); + return Response.status(Response.Status.OK).build(); + } - OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); - switchingService.createNetwork(openstackNetwork); - return Response.status(Response.Status.OK).build(); - } catch (Exception e) { - log.error("Creates VirtualPort failed because of exception {}", - e.toString()); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) - .build(); - } + @DELETE + @Path("{id}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response deleteNetwork(InputStream input) { + log.debug("REST API networks is called {}", input.toString()); + return Response.status(Response.Status.OK).build(); } } diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java similarity index 97% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java rename to framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java index 765b6901..63e6d2ea 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java @@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory; import java.util.HashMap; /** - * It encodes and decodes the OpenstackPort. + * Encodes and decodes the OpenstackPort. */ public class OpenstackPortCodec extends JsonCodec { @@ -58,6 +58,9 @@ public class OpenstackPortCodec extends JsonCodec { HashMap fixedIpMap = new HashMap<>(); JsonNode portInfo = json.get(PORT); + if (portInfo == null) { + portInfo = json; + } String status = portInfo.path(STATUS).asText(); String name = portInfo.path(NAME).asText(); diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java similarity index 60% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java rename to framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java index 67a9cebb..faffa732 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java @@ -33,6 +33,9 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.InputStream; +/** + * Handles Rest API call from Neutron ML2 plugin. + */ @Path("ports") public class OpenstackPortWebResource extends AbstractWebResource { @@ -50,13 +53,15 @@ public class OpenstackPortWebResource extends AbstractWebResource { ObjectNode portNode = (ObjectNode) mapper.readTree(input); OpenstackPort openstackPort = PORT_CODEC.decode(portNode, this); - - OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); + OpenstackSwitchingService switchingService = + getService(OpenstackSwitchingService.class); switchingService.createPorts(openstackPort); - log.info("REST API ports is called with {}", portNode.toString()); + + log.debug("REST API ports is called with {}", portNode.toString()); return Response.status(Response.Status.OK).build(); + } catch (Exception e) { - log.error("Creates VirtualPort failed because of exception {}", + log.error("Creates Port failed because of exception {}", e.toString()); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) .build(); @@ -64,23 +69,12 @@ public class OpenstackPortWebResource extends AbstractWebResource { } @DELETE + @Path("{id}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response deletesPorts(InputStream input) { - try { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode portNode = (ObjectNode) mapper.readTree(input); - - OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); - switchingService.deletePorts(); - log.info("REST API ports is called with {}", portNode.toString()); - return Response.status(Response.Status.OK).build(); - } catch (Exception e) { - log.error("Delete VirtualPort failed because of exception {}", - e.toString()); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) - .build(); - } + log.debug("REST API ports is called with {}", input.toString()); + return Response.status(Response.Status.OK).build(); } @PUT @@ -88,19 +82,7 @@ public class OpenstackPortWebResource extends AbstractWebResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response updatePorts(InputStream input) { - try { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode portNode = (ObjectNode) mapper.readTree(input); - - OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); - switchingService.updatePorts(); - log.info("REST API ports is called with {}", portNode.toString()); - return Response.status(Response.Status.OK).build(); - } catch (Exception e) { - log.error("Update VirtualPort failed because of exception {}", - e.toString()); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) - .build(); - } + log.info("REST API ports is called with {}", input.toString()); + return Response.status(Response.Status.OK).build(); } } diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java similarity index 80% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java rename to framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java index a643057a..2a7af82a 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java @@ -18,17 +18,21 @@ package org.onosproject.openstackswitching.web; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Lists; +import org.onlab.packet.Ip4Address; import org.onosproject.codec.CodecContext; import org.onosproject.codec.JsonCodec; import org.onosproject.openstackswitching.OpenstackSubnet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; + /** - * It encodes and decodes the OpenstackSubnet. + * Encodes and decodes the OpenstackSubnet. */ - public class OpenstackSubnetCodec extends JsonCodec { private static Logger log = LoggerFactory .getLogger(OpenstackSubnetCodec.class); @@ -47,12 +51,19 @@ public class OpenstackSubnetCodec extends JsonCodec { @Override public OpenstackSubnet decode(ObjectNode json, CodecContext context) { JsonNode subnetInfo = json.get(SUBNET); + if (subnetInfo == null) { + subnetInfo = json; + } String name = subnetInfo.path(NAME).asText(); boolean enableDhcp = subnetInfo.path(ENABLE_DHCP).asBoolean(); String networkId = subnetInfo.path(NETWORK_ID).asText(); String tenantId = subnetInfo.path(TENANT_ID).asText(); - String dnsNameservsers = subnetInfo.path(DNS_NAMESERVERS).asText(); + ArrayNode dnsNameservsers = (ArrayNode) subnetInfo.path(DNS_NAMESERVERS); + List dnsList = Lists.newArrayList(); + if (dnsNameservsers != null && !dnsNameservsers.isMissingNode()) { + dnsNameservsers.forEach(dns -> dnsList.add(Ip4Address.valueOf(dns.asText()))); + } String gatewayIp = subnetInfo.path(GATEWAY_IP).asText(); String cidr = subnetInfo.path(CIDR).asText(); String id = subnetInfo.path(ID).asText(); @@ -62,7 +73,7 @@ public class OpenstackSubnetCodec extends JsonCodec { .setEnableDhcp(enableDhcp) .setNetworkId(networkId) .setTenantId(tenantId) - .setDnsNameservers(dnsNameservsers) + .setDnsNameservers(dnsList) .setGatewayIp(gatewayIp) .setCidr(cidr) .setId(id) diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java similarity index 54% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java rename to framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java index af1ae9dd..43205eac 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java +++ b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java @@ -15,18 +15,19 @@ */ package org.onosproject.openstackswitching.web; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.onosproject.openstackswitching.OpenstackSubnet; -import org.onosproject.openstackswitching.OpenstackSwitchingService; +/** + * Handles Rest API call from Neutron ML2 plugin. + */ import org.onosproject.rest.AbstractWebResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -37,28 +38,32 @@ public class OpenstackSubnetWebResource extends AbstractWebResource { protected static final Logger log = LoggerFactory .getLogger(OpenstackSubnetWebResource.class); - private static final OpenstackSubnetCodec SUBNET_CODEC = new OpenstackSubnetCodec(); - @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response createSubnet(InputStream input) { - try { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode subnetNode = (ObjectNode) mapper.readTree(input); + return Response.status(Response.Status.OK).build(); + } + + + @PUT + @Path("{subnetUUID}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response updateSubnet(@PathParam("id") String id, + final InputStream input) { + return Response.status(Response.Status.OK).build(); - OpenstackSubnet openstackSubnet = SUBNET_CODEC.decode(subnetNode, this); + } - OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); - switchingService.createSubnet(openstackSubnet); - log.info("REST API subnets is called with {}", subnetNode.toString()); - return Response.status(Response.Status.OK).build(); - } catch (Exception e) { - log.error("Creates VirtualSubnet failed because of exception {}", - e.toString()); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) - .build(); - } + @DELETE + @Path("{subnetUUID}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response deleteSubnet(@PathParam("id") String id, + final InputStream input) { + return Response.status(Response.Status.OK).build(); } + } diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/package-info.java b/framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/package-info.java similarity index 100% rename from framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/package-info.java rename to framework/src/onos/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/package-info.java diff --git a/framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/openstackswitching/app/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml rename to framework/src/onos/apps/openstackswitching/app/src/main/webapp/WEB-INF/web.xml diff --git a/framework/src/onos/apps/openstackswitching/network-cfg.json b/framework/src/onos/apps/openstackswitching/network-cfg.json new file mode 100644 index 00000000..62c3a515 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/network-cfg.json @@ -0,0 +1,55 @@ +{ + "apps" : { + "org.onosproject.openstackswitching" : { + "openstackswitching" : { + "do_not_push_flows" : "false", + "neutron_server" : "http://127.0.0.1:9696/v2.0/", + "keystone_server" : "http://127.0.0.1:5000/v2.0/", + "user_name" : "admin", + "password" : "nova" + } + }, + "org.onosproject.dhcp" : { + "dhcp" : { + "ip": "10.0.0.1", + "mac": "1a:2b:3c:4e:5e:6f", + "subnet": "255.0.0.0", + "broadcast": "10.255.255.255", + "router": "10.0.0.1", + "domain": "10.0.0.1", + "ttl": "63", + "lease": "300", + "renew": "150", + "rebind": "200", + "delay": "3", + "timeout": "150", + "startip": "10.0.0.110", + "endip": "10.0.0.130" + } + }, + "org.onosproject.cordvtn" : { + "cordvtn" : { + "ovsdbNodes" : [ + { + "host" : "compute-01", + "ip" : "128.199.162.106", + "port" : "6640", + "bridgeId" : "of:0000000000000001" + }, + { + "host" : "compute-02", + "ip" : "103.253.145.133", + "port" : "6640", + "bridgeId" : "of:0000000000000002" + }, + { + "host" : "network", + "ip" : "128.199.125.11", + "port" : "6640", + "bridgeId" : "of:0000000000000003" + } + ] + } + } + } +} diff --git a/framework/src/onos/apps/openstackswitching/pom.xml b/framework/src/onos/apps/openstackswitching/pom.xml index 52129b6f..9dbdcf5f 100644 --- a/framework/src/onos/apps/openstackswitching/pom.xml +++ b/framework/src/onos/apps/openstackswitching/pom.xml @@ -26,101 +26,18 @@ ../pom.xml - onos-app-openstackswitching - bundle + onos-openstackswitching + pom - SONA Openstack Switching applications - - 1.4.0-SNAPSHOT - org.onosproject.openstackswitching - /onos/openstackswitching - 1.0.0 - ONOS OpenStack Switching REST API - - APIs for receiving Neutron information. - - org.onosproject.openstackswitching.web - SKT, Inc. - + SONA Openstack Switching application + + api + app + - - org.onosproject - onos-rest - ${project.version} - - - org.onosproject - onlab-rest - ${project.version} - - - javax.ws.rs - jsr311-api - 1.1.1 - - - com.sun.jersey - jersey-servlet - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.core - jackson-annotations - - - org.osgi - org.osgi.compendium - - - org.osgi - org.osgi.core - - - org.onosproject - onos-app-dhcp-api - ${project.version} - - - - - org.apache.felix - maven-bundle-plugin - true - - - <_wab>src/main/webapp/ - - ${project.groupId}.${project.artifactId} - - - org.slf4j, - org.osgi.framework, - javax.ws.rs, - javax.ws.rs.core, - com.sun.jersey.api.core, - com.sun.jersey.spi.container.servlet, - com.sun.jersey.server.impl.container.servlet, - com.fasterxml.jackson.databind, - com.fasterxml.jackson.databind.node, - com.fasterxml.jackson.core, - org.apache.karaf.shell.commands, - com.google.common.*, - org.onlab.packet.*, - org.onosproject.* - - ${web.context} - - - - - - diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java deleted file mode 100644 index 4be8a50d..00000000 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Copyright 2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.openstackswitching; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onlab.packet.Ethernet; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.MacAddress; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.dhcp.DhcpService; -import org.onosproject.net.Device; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Port; -import org.onosproject.net.device.DeviceEvent; -import org.onosproject.net.device.DeviceListener; -import org.onosproject.net.device.DeviceService; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.packet.InboundPacket; -import org.onosproject.net.packet.PacketContext; -import org.onosproject.net.packet.PacketProcessor; -import org.onosproject.net.packet.PacketService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -@SuppressWarnings("ALL") -@Service -@Component(immediate = true) -/** - * It populates forwarding rules for VMs created by Openstack. - */ -public class OpenstackSwitchingManager implements OpenstackSwitchingService { - - private static Logger log = LoggerFactory - .getLogger(OpenstackSwitchingManager.class); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected CoreService coreService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected PacketService packetService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DeviceService deviceService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected FlowObjectiveService flowObjectiveService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DhcpService dhcpService; - - public static final int DHCP_PORT = 67; - - private ApplicationId appId; - private OpenstackArpHandler arpHandler; - - private OpenstackSwitchingRulePopulator rulePopulator; - private ExecutorService deviceEventExcutorService = Executors.newFixedThreadPool(10); - - private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor(); - private InternalDeviceListener internalDeviceListener = new InternalDeviceListener(); - - // Map - private Map openstackPortMap; - // Map - private Map openstackNetworkMap; - // Map - private Map openstackSubnetMap; - // Map > - private Map> vniPortMap; - private Map tunnelPortMap; - - - @Activate - protected void activate() { - appId = coreService - .registerApplication("org.onosproject.openstackswitching"); - rulePopulator = new OpenstackSwitchingRulePopulator(appId, flowObjectiveService); - packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1)); - deviceService.addListener(internalDeviceListener); - - openstackPortMap = Maps.newHashMap(); - openstackNetworkMap = Maps.newHashMap(); - openstackSubnetMap = Maps.newHashMap(); - - vniPortMap = Maps.newHashMap(); - tunnelPortMap = Maps.newHashMap(); - arpHandler = new OpenstackArpHandler(openstackPortMap, packetService); - log.info("Started"); - } - - @Deactivate - protected void deactivate() { - packetService.removeProcessor(internalPacketProcessor); - deviceService.removeListener(internalDeviceListener); - - deviceEventExcutorService.shutdown(); - - log.info("Stopped"); - } - - @Override - public void createPorts(OpenstackPort openstackPort) { - //For DHCP purpose - //registerDhcpInfo(openstackPort); - openstackPortMap.put(openstackPort.id(), openstackPort); - } - - /* - private void registerDhcpInfo(OpenstackPort openstackPort) { - Ip4Address ip4Address; - Ip4Address subnetMask; - Ip4Address dhcpServer; - Ip4Address gatewayIPAddress; - Ip4Address domainServer; - OpenstackSubnet openstackSubnet; - - ip4Address = (Ip4Address) openstackPort.fixedIps().values().toArray()[0]; - - openstackSubnet = openstackSubnetMap.values().stream() - .filter(n -> n.networkId().equals(openstackPort.networkId())) - .findFirst().get(); - - int prefix; - String[] parts = openstackSubnet.cidr().split("/"); - prefix = Integer.parseInt(parts[1]); - int mask = 0xffffffff << (32 - prefix); - byte[] bytes = new byte[]{(byte) (mask >>> 24), - (byte) (mask >> 16 & 0xff), (byte) (mask >> 8 & 0xff), (byte) (mask & 0xff)}; - - subnetMask = Ip4Address.valueOf(bytes); - gatewayIPAddress = Ip4Address.valueOf(openstackSubnet.gatewayIp()); - dhcpServer = gatewayIPAddress; - domainServer = Ip4Address.valueOf("8.8.8.8"); - - dhcpService.setStaticMappingOpenstack(openstackPort.macAddress(), - ip4Address, subnetMask, dhcpServer, gatewayIPAddress, domainServer); - } - */ - - @Override - public void deletePorts() { - - } - - @Override - public void updatePorts() { - - } - - @Override - public void createNetwork(OpenstackNetwork openstackNetwork) { - openstackNetworkMap.put(openstackNetwork.id(), openstackNetwork); - } - - - @Override - public void createSubnet(OpenstackSubnet openstackSubnet) { - openstackSubnetMap.put(openstackSubnet.id(), openstackSubnet); - log.debug("Added Subnet Info {}", openstackNetworkMap.get(openstackSubnet.id())); - } - - private void processDeviceAdded(Device device) { - log.debug("device {} is added", device.id()); - rulePopulator.populateDefaultRules(device.id()); - } - - private void processPortAdded(Device device, Port port) { - // TODO: Simplify the data structure to store the network info - // TODO: Make it stateless - // TODO: All the logics need to be processed inside of the rulePopulator class - synchronized (vniPortMap) { - log.debug("port {} is updated", port.toString()); - - updatePortMaps(device, port); - if (!port.annotations().value("portName").equals("vxlan")) { - populateFlowRulesForTrafficToSameCnode(device, port); - populateFlowRulesForTrafficToDifferentCnode(device, port); - } - } - } - - private void processPortRemoved(Device device, Port port) { - log.debug("port {} is removed", port.toString()); - // TODO: need to update the vniPortMap - } - - /** - * Populates the flow rules for traffic to VMs in different Cnode using - * Nicira extention. - * - * @param device device to put rules - * @param port port information of the VM - */ - private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) { - String portName = port.annotations().value("portName"); - String channelId = device.annotations().value("channelId"); - Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]); - Ip4Address fixedIp = getFixedIpAddressForPort(portName); - // TODO: Avoid duplicate flow rule set up for VMs in other Cnode - // (possibly avoided by flowrule subsystem?) - if (tunnelPortMap.get(hostIpAddress) == null) { - log.debug("There is no tunnel port information"); - return; - } - String vni = getVniForPort(portName); - MacAddress vmMac = getVmMacAddressForPort(portName); - if (!vniPortMap.isEmpty() && vniPortMap.get(vni) != null) { - for (PortInfo portInfo : vniPortMap.get(vni)) { - if (!portInfo.portName.equals(portName) && - !portInfo.hostIp.equals(hostIpAddress)) { - MacAddress vmMacx = getVmMacAddressForPort(portInfo.portName); - rulePopulator.populateForwardingRuleForOtherCnode(vni, - device.id(), portInfo.hostIp, portInfo.fixedIp, vmMacx, - tunnelPortMap.get(hostIpAddress).number(), - portInfo.deviceId, hostIpAddress, fixedIp, vmMac, - tunnelPortMap.get(portInfo.hostIp).number()); - } - } - } - } - - /** - * Populates the flow rules for traffic to VMs in the same Cnode as the sender. - * - * @param device device to put the rules - * @param port port info of the VM - */ - private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) { - Ip4Prefix cidr = getCidrForPort(port.annotations().value("portName")); - Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName")); - if (vmIp != null) { - rulePopulator.populateForwardingRule(vmIp, device.id(), port, cidr); - } - } - - /** - * Updates the port maps using the port information. - * - * @param device device info - * @param port port of the VM - */ - private void updatePortMaps(Device device, Port port) { - String portName = port.annotations().value("portName"); - String channelId = device.annotations().value("channelId"); - Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]); - if (portName.startsWith("vxlan")) { - tunnelPortMap.put(hostIpAddress, port); - } else { - String vni = getVniForPort(portName); - Ip4Address fixedIp = getFixedIpAddressForPort(portName); - if (vniPortMap.get(vni) == null) { - vniPortMap.put(vni, Lists.newArrayList()); - } - vniPortMap.get(vni).add(new PortInfo(device.id(), portName, fixedIp, hostIpAddress)); - } - } - - /** - * Returns CIDR information from the subnet map for the port. - * - * @param portName port name of the port of the VM - * @return CIDR of the VNI of the VM - */ - private Ip4Prefix getCidrForPort(String portName) { - String networkId = null; - String uuid = portName.substring(3); - OpenstackPort port = openstackPortMap.values().stream() - .filter(p -> p.id().startsWith(uuid)) - .findFirst().get(); - if (port == null) { - log.debug("No port information for port {}", portName); - return null; - } - - OpenstackSubnet subnet = openstackSubnetMap.values().stream() - .filter(s -> s.networkId().equals(port.networkId())) - .findFirst().get(); - if (subnet == null) { - log.debug("No subnet information for network {}", subnet.id()); - return null; - } - - return Ip4Prefix.valueOf(subnet.cidr()); - } - - /** - * Returns the VNI of the VM of the port. - * - * @param portName VM port - * @return VNI - */ - private String getVniForPort(String portName) { - String networkId = null; - String uuid = portName.substring(3); - OpenstackPort port = openstackPortMap.values().stream() - .filter(p -> p.id().startsWith(uuid)) - .findFirst().get(); - if (port == null) { - log.debug("No port information for port {}", portName); - return null; - } - OpenstackNetwork network = openstackNetworkMap.values().stream() - .filter(n -> n.id().equals(port.networkId())) - .findFirst().get(); - if (network == null) { - log.debug("No VNI information for network {}", network.id()); - return null; - } - - return network.segmentId(); - } - - /** - * Returns the Fixed IP address of the VM. - * - * @param portName VM port info - * @return IP address of the VM - */ - private Ip4Address getFixedIpAddressForPort(String portName) { - - // FIXME - For now we use the information stored from neutron Rest API call. - // TODO - Later, the information needs to be extracted from Neutron on-demand. - String uuid = portName.substring(3); - OpenstackPort port = openstackPortMap.values().stream() - .filter(p -> p.id().startsWith(uuid)) - .findFirst().get(); - - if (port == null) { - log.error("There is no port information for port name {}", portName); - return null; - } - - if (port.fixedIps().isEmpty()) { - log.error("There is no fixed IP info in the port information"); - return null; - } - - return (Ip4Address) port.fixedIps().values().toArray()[0]; - } - - /** - * Returns the MAC address of the VM of the port. - * - * @param portName VM port - * @return MAC address of the VM - */ - private MacAddress getVmMacAddressForPort(String portName) { - - String uuid = portName.substring(3); - OpenstackPort port = openstackPortMap.values().stream() - .filter(p -> p.id().startsWith(uuid)) - .findFirst().get(); - - if (port == null) { - log.error("There is no mac information for port name {}", portName); - return null; - } - - return port.macAddress(); - } - - private class InternalPacketProcessor implements PacketProcessor { - - @Override - public void process(PacketContext context) { - - if (context.isHandled()) { - return; - } - - InboundPacket pkt = context.inPacket(); - Ethernet ethernet = pkt.parsed(); - - if (ethernet.getEtherType() == Ethernet.TYPE_ARP) { - arpHandler.processPacketIn(pkt); - } - } - } - - private class InternalDeviceListener implements DeviceListener { - - @Override - public void event(DeviceEvent event) { - deviceEventExcutorService.execute(new InternalEventHandler(event)); - } - } - - private class InternalEventHandler implements Runnable { - - volatile DeviceEvent deviceEvent; - - InternalEventHandler(DeviceEvent deviceEvent) { - this.deviceEvent = deviceEvent; - } - - @Override - public void run() { - switch (deviceEvent.type()) { - case DEVICE_ADDED: - processDeviceAdded((Device) deviceEvent.subject()); - break; - case DEVICE_UPDATED: - Port port = (Port) deviceEvent.subject(); - if (port.isEnabled()) { - processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); - } - break; - case DEVICE_AVAILABILITY_CHANGED: - Device device = (Device) deviceEvent.subject(); - if (deviceService.isAvailable(device.id())) { - processDeviceAdded(device); - } - break; - case PORT_ADDED: - processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); - break; - case PORT_UPDATED: - processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); - break; - case PORT_REMOVED: - processPortRemoved((Device) deviceEvent.subject(), deviceEvent.port()); - break; - default: - break; - } - } - } - - private final class PortInfo { - DeviceId deviceId; - String portName; - Ip4Address fixedIp; - Ip4Address hostIp; - - private PortInfo(DeviceId deviceId, String portName, Ip4Address fixedIp, - Ip4Address hostIp) { - this.deviceId = deviceId; - this.portName = portName; - this.fixedIp = fixedIp; - this.hostIp = hostIp; - } - } - -} \ No newline at end of file diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java deleted file mode 100644 index f6e98060..00000000 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java +++ /dev/null @@ -1,227 +0,0 @@ -/* -* Copyright 2015 Open Networking Laboratory -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.onosproject.openstackswitching; - -import org.onlab.packet.Ethernet; -import org.onlab.packet.IPv4; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.MacAddress; -import org.onlab.packet.TpPort; -import org.onosproject.core.ApplicationId; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Port; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.DefaultTrafficSelector; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.TrafficSelector; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flowobjective.DefaultForwardingObjective; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.flowobjective.ForwardingObjective; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * It populates switching flow rules. - * - */ -public class OpenstackSwitchingRulePopulator { - - private static Logger log = LoggerFactory - .getLogger(OpenstackSwitchingRulePopulator.class); - - private FlowObjectiveService flowObjectiveService; - private ApplicationId appId; - - /** - * Creates OpenstackSwitchingRulPopulator. - * - * @param appId application id - * @param flowObjectiveService FlowObjectiveService reference - */ - public OpenstackSwitchingRulePopulator(ApplicationId appId, - FlowObjectiveService flowObjectiveService) { - this.flowObjectiveService = flowObjectiveService; - this.appId = appId; - } - - /** - * Populates flows rules for forwarding packets to and from VMs. - * - * @param ip v4 IP Address - * @param id device ID - * @param port port - * @param cidr v4 IP prefix - * @return true if it succeeds to populate rules, false otherwise. - */ - public boolean populateForwardingRule(Ip4Address ip, DeviceId id, Port port, Ip4Prefix cidr) { - - - setFlowRuleForVMsInSameCnode(ip, id, port, cidr); - - return true; - } - - /** - * Populates the common flows rules for all VMs. - * - * - Send ARP packets to the controller - * - Send DHCP packets to the controller - * - * @param id Device ID to populates rules to - */ - public void populateDefaultRules(DeviceId id) { - - setFlowRuleForArp(id); - - log.warn("Default rule has been set"); - } - - /** - * Populates the forwarding rules for VMs with the same VNI but in other Code. - * - * @param vni VNI for the networks - * @param id device ID to populates the flow rules - * @param hostIp host IP address of the VM - * @param vmIp fixed IP address for the VM - * @param vmMac MAC address for the VM - * @param tunnelPort tunnel port number for the VM - * @param idx device ID for OVS of the other VM - * @param hostIpx host IP address of the other VM - * @param vmIpx fixed IP address of the other VM - * @param vmMacx MAC address for the other VM - * @param tunnelPortx x tunnel port number for other VM - */ - public void populateForwardingRuleForOtherCnode(String vni, DeviceId id, Ip4Address hostIp, - Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort, - DeviceId idx, Ip4Address hostIpx, - Ip4Address vmIpx, MacAddress vmMacx, PortNumber tunnelPortx) { - setVxLanFlowRule(vni, id, hostIp, vmIp, vmMac, tunnelPort); - setVxLanFlowRule(vni, idx, hostIpx, vmIpx, vmMacx, tunnelPortx); - } - - /** - * Populates the flow rules for DHCP packets from VMs. - * - * @param id device ID to set the rules - */ - private void setFlowRuleForDhcp(DeviceId id) { - TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); - - sBuilder.matchEthType(Ethernet.TYPE_IPV4) - .matchIPProtocol(IPv4.PROTOCOL_UDP) - .matchUdpDst(TpPort.tpPort(OpenstackSwitchingManager.DHCP_PORT)); - tBuilder.setOutput(PortNumber.CONTROLLER); - - ForwardingObjective fo = DefaultForwardingObjective.builder() - .withSelector(sBuilder.build()) - .withTreatment(tBuilder.build()) - .withPriority(5000) - .withFlag(ForwardingObjective.Flag.VERSATILE) - .fromApp(appId) - .add(); - - flowObjectiveService.forward(id, fo); - } - - /** - * Populates the flow rules for ARP packets from VMs. - * - * @param id device ID to put rules. - */ - private void setFlowRuleForArp(DeviceId id) { - TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); - - sBuilder.matchEthType(Ethernet.TYPE_ARP); - tBuilder.setOutput(PortNumber.CONTROLLER); - - ForwardingObjective fo = DefaultForwardingObjective.builder() - .withSelector(sBuilder.build()) - .withTreatment(tBuilder.build()) - .withPriority(5000) - .withFlag(ForwardingObjective.Flag.VERSATILE) - .fromApp(appId) - .add(); - - flowObjectiveService.forward(id, fo); - } - - /** - * Sets the flow rules for traffic between VMs in the same Cnode. - * - * @param ip4Address VM IP address - * @param id device ID to put rules - * @param port VM port - * @param cidr subnet info of the VMs - */ - private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id, - Port port, Ip4Prefix cidr) { - TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); - - sBuilder.matchEthType(Ethernet.TYPE_IPV4) - .matchIPDst(ip4Address.toIpPrefix()) - .matchIPSrc(cidr); - tBuilder.setOutput(port.number()); - - ForwardingObjective fo = DefaultForwardingObjective.builder() - .withSelector(sBuilder.build()) - .withTreatment(tBuilder.build()) - .withPriority(5000) - .withFlag(ForwardingObjective.Flag.VERSATILE) - .fromApp(appId) - .add(); - - flowObjectiveService.forward(id, fo); - } - - /** - * Sets the flow rules between traffic from VMs in different Cnode. - * - * @param vni VNI - * @param id device ID - * @param hostIp host IP of the VM - * @param vmIp fixed IP of the VM - * @param vmMac MAC address of the VM - * @param tunnelPort tunnel port to forward traffic to - */ - private void setVxLanFlowRule(String vni, DeviceId id, Ip4Address hostIp, - Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort) { - TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); - - sBuilder.matchEthType(Ethernet.TYPE_IPV4) - .matchIPDst(vmIp.toIpPrefix()); - tBuilder.setTunnelId(Long.parseLong(vni)) - //.setTunnelDst() <- for Nicira ext - //.setEthDst(vmMac) - .setOutput(tunnelPort); - - ForwardingObjective fo = DefaultForwardingObjective.builder() - .withSelector(sBuilder.build()) - .withTreatment(tBuilder.build()) - .withPriority(5000) - .withFlag(ForwardingObjective.Flag.VERSATILE) - .fromApp(appId) - .add(); - - flowObjectiveService.forward(id, fo); - } -} diff --git a/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java b/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java index e33d5aa1..70ade23a 100644 --- a/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java +++ b/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java @@ -117,7 +117,7 @@ public final class PIMInterfaces { * @param cp The connectPoint representing the PIMInterface to be removed. */ private void removeInterface(ConnectPoint cp) { - removeInterface(cp); + PIMInterfaces.this.removeInterface(cp); } @Override diff --git a/framework/src/onos/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java b/framework/src/onos/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java index 2b0ef989..8204a109 100644 --- a/framework/src/onos/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java +++ b/framework/src/onos/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java @@ -89,14 +89,17 @@ public class RouteEntry { /** * Creates the binary string representation of an IP prefix. * The prefix can be either IPv4 or IPv6. - * The string length is equal to the prefix length. + * The string length is equal to the prefix length + 1. + * + * For each string, we put a extra "0" in the front. The purpose of + * doing this is to store the default route inside InvertedRadixTree. * * @param ipPrefix the IP prefix to use * @return the binary string representation */ public static String createBinaryString(IpPrefix ipPrefix) { if (ipPrefix.prefixLength() == 0) { - return ""; + return "0"; } byte[] octets = ipPrefix.address().toOctets(); @@ -109,7 +112,8 @@ public class RouteEntry { boolean isSet = ((value & mask) != 0); result.append(isSet ? "1" : "0"); } - return result.toString(); + + return "0" + result.toString(); } @Override diff --git a/framework/src/onos/apps/routing-api/src/test/java/org/onosproject/routing/RouteEntryTest.java b/framework/src/onos/apps/routing-api/src/test/java/org/onosproject/routing/RouteEntryTest.java index b89eb2d1..981d6a09 100644 --- a/framework/src/onos/apps/routing-api/src/test/java/org/onosproject/routing/RouteEntryTest.java +++ b/framework/src/onos/apps/routing-api/src/test/java/org/onosproject/routing/RouteEntryTest.java @@ -121,52 +121,52 @@ public class RouteEntryTest { Ip4Prefix prefix; prefix = Ip4Prefix.valueOf("0.0.0.0/0"); - assertThat(RouteEntry.createBinaryString(prefix), is("")); + assertThat(RouteEntry.createBinaryString(prefix), is("0")); prefix = Ip4Prefix.valueOf("192.168.166.0/22"); assertThat(RouteEntry.createBinaryString(prefix), - is("1100000010101000101001")); + is("0" + "1100000010101000101001")); prefix = Ip4Prefix.valueOf("192.168.166.0/23"); assertThat(RouteEntry.createBinaryString(prefix), - is("11000000101010001010011")); + is("0" + "11000000101010001010011")); prefix = Ip4Prefix.valueOf("192.168.166.0/24"); assertThat(RouteEntry.createBinaryString(prefix), - is("110000001010100010100110")); + is("0" + "110000001010100010100110")); prefix = Ip4Prefix.valueOf("130.162.10.1/25"); assertThat(RouteEntry.createBinaryString(prefix), - is("1000001010100010000010100")); + is("0" + "1000001010100010000010100")); prefix = Ip4Prefix.valueOf("255.255.255.255/32"); assertThat(RouteEntry.createBinaryString(prefix), - is("11111111111111111111111111111111")); + is("0" + "11111111111111111111111111111111")); Ip6Prefix prefix6; Pattern pattern; Matcher matcher; prefix6 = Ip6Prefix.valueOf("::/0"); - assertThat(RouteEntry.createBinaryString(prefix6), is("")); + assertThat(RouteEntry.createBinaryString(prefix6), is("0")); prefix6 = Ip6Prefix.valueOf("2000::1000/112"); - pattern = Pattern.compile("00100{108}"); + pattern = Pattern.compile("0" + "00100{108}"); matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); assertTrue(matcher.matches()); prefix6 = Ip6Prefix.valueOf("2000::1000/116"); - pattern = Pattern.compile("00100{108}0001"); + pattern = Pattern.compile("0" + "00100{108}0001"); matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); assertTrue(matcher.matches()); prefix6 = Ip6Prefix.valueOf("2000::2000/116"); - pattern = Pattern.compile("00100{108}0010"); + pattern = Pattern.compile("0" + "00100{108}0010"); matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); assertTrue(matcher.matches()); prefix6 = Ip6Prefix.valueOf("2000::1234/128"); - pattern = Pattern.compile("00100{108}0001001000110100"); + pattern = Pattern.compile("0" + "00100{108}0001001000110100"); matcher = pattern.matcher(RouteEntry.createBinaryString(prefix6)); assertTrue(matcher.matches()); } diff --git a/framework/src/onos/apps/sdnip/features.xml b/framework/src/onos/apps/sdnip/features.xml index 21ae89d3..5bd0dbc4 100644 --- a/framework/src/onos/apps/sdnip/features.xml +++ b/framework/src/onos/apps/sdnip/features.xml @@ -15,7 +15,6 @@ ~ limitations under the License. --> - mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features onos-api diff --git a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java index c0001bdc..9113e013 100644 --- a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java +++ b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java @@ -83,7 +83,8 @@ public class SdnIpFib implements FibListener { @Override - public void update(Collection updates, Collection withdraws) { + public void update(Collection updates, + Collection withdraws) { int submitCount = 0, withdrawCount = 0; // // NOTE: Semantically, we MUST withdraw existing intents before @@ -157,7 +158,8 @@ public class SdnIpFib implements FibListener { MacAddress nextHopMacAddress) { // Find the attachment point (egress interface) of the next hop - Interface egressInterface = interfaceService.getMatchingInterface(nextHopIpAddress); + Interface egressInterface = + interfaceService.getMatchingInterface(nextHopIpAddress); if (egressInterface == null) { log.warn("No outgoing interface found for {}", nextHopIpAddress); @@ -182,10 +184,19 @@ public class SdnIpFib implements FibListener { TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); if (prefix.isIp4()) { selector.matchEthType(Ethernet.TYPE_IPV4); - selector.matchIPDst(prefix); + // if it is default route, then we do not need match destination + // IP address + if (prefix.prefixLength() != 0) { + selector.matchIPDst(prefix); + } } else { selector.matchEthType(Ethernet.TYPE_IPV6); - selector.matchIPv6Dst(prefix); + // if it is default route, then we do not need match destination + // IP address + if (prefix.prefixLength() != 0) { + selector.matchIPv6Dst(prefix); + } + } // Rewrite the destination MAC address diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java index a737339f..99225874 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java @@ -448,7 +448,6 @@ public class DefaultRoutingHandler { if (nextHops.isEmpty()) { nextHops.add(destSw); } - // If both target switch and dest switch are edge routers, then set IP // rule for both subnet and router IP. boolean targetIsEdge; @@ -467,7 +466,7 @@ public class DefaultRoutingHandler { if (targetIsEdge && destIsEdge) { Set subnets = config.getSubnets(destSw); log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}", - targetSw, destSw, subnets); + targetSw, destSw, subnets); result = rulePopulator.populateIpRuleForSubnet(targetSw, subnets, destSw, @@ -479,24 +478,23 @@ public class DefaultRoutingHandler { Ip4Address routerIp = destRouterIp; IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for router IP {}", - targetSw, destSw, routerIpPrefix); + targetSw, destSw, routerIpPrefix); result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops); if (!result) { return false; } - // If the target switch is an edge router, then set IP rules for the router IP. } else if (targetIsEdge) { + // If the target switch is an edge router, then set IP rules for the router IP. Ip4Address routerIp = destRouterIp; IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for router IP {}", - targetSw, destSw, routerIpPrefix); + targetSw, destSw, routerIpPrefix); result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops); if (!result) { return false; } } - // Populates MPLS rules to all routers log.debug("* populateEcmpRoutingRulePartial in device{} towards {} for all MPLS rules", targetSw, destSw); @@ -504,7 +502,6 @@ public class DefaultRoutingHandler { if (!result) { return false; } - return true; } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java index bc3ce8c6..a07a15d2 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java @@ -15,6 +15,7 @@ */ package org.onosproject.segmentrouting; +import org.onlab.packet.EthType; import org.onlab.packet.Ethernet; import org.onlab.packet.Ip4Address; import org.onlab.packet.Ip4Prefix; @@ -26,7 +27,6 @@ import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; import org.onosproject.segmentrouting.config.DeviceConfiguration; import org.onosproject.segmentrouting.grouphandler.NeighborSet; import org.onosproject.net.DeviceId; -import org.onosproject.net.Link; import org.onosproject.net.Port; import org.onosproject.net.PortNumber; import org.onosproject.net.flow.DefaultTrafficSelector; @@ -227,7 +227,15 @@ public class RoutingRulePopulator { treatment = null; } - if (srManager.getNextObjectiveId(deviceId, ns) <= 0) { + // setup metadata to pass to nextObjective - indicate the vlan on egress + // if needed by the switch pipeline. Since neighbor sets are always to + // other neighboring routers, there is no subnet assigned on those ports. + TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder(selector); + metabuilder.matchVlanId( + VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET)); + + int nextId = srManager.getNextObjectiveId(deviceId, ns, metabuilder.build()); + if (nextId <= 0) { log.warn("No next objective in {} for ns: {}", deviceId, ns); return false; } @@ -236,7 +244,7 @@ public class RoutingRulePopulator { .builder() .fromApp(srManager.appId) .makePermanent() - .nextStep(srManager.getNextObjectiveId(deviceId, ns)) + .nextStep(nextId) .withSelector(selector) .withPriority(100) .withFlag(ForwardingObjective.Flag.SPECIFIC); @@ -279,63 +287,70 @@ public class RoutingRulePopulator { List fwdObjBuilders = new ArrayList<>(); // TODO Handle the case of Bos == false - sbuilder.matchMplsLabel(MplsLabel.mplsLabel(segmentId)); sbuilder.matchEthType(Ethernet.MPLS_UNICAST); + sbuilder.matchMplsLabel(MplsLabel.mplsLabel(segmentId)); + TrafficSelector selector = sbuilder.build(); + + // setup metadata to pass to nextObjective - indicate the vlan on egress + // if needed by the switch pipeline. Since mpls next-hops are always to + // other neighboring routers, there is no subnet assigned on those ports. + TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder(selector); + metabuilder.matchVlanId( + VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET)); - // If the next hop is the destination router, do PHP + // If the next hop is the destination router for the segment, do pop if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) { log.debug("populateMplsRule: Installing MPLS forwarding objective for " - + "label {} in switch {} with PHP", - segmentId, - deviceId); + + "label {} in switch {} with pop", segmentId, deviceId); + // bos pop case (php) ForwardingObjective.Builder fwdObjBosBuilder = getMplsForwardingObjective(deviceId, - destSwId, nextHops, true, - true); - // TODO: Check with Sangho on why we need this - ForwardingObjective.Builder fwdObjNoBosBuilder = - getMplsForwardingObjective(deviceId, - destSwId, - nextHops, true, - false); - if (fwdObjBosBuilder != null) { - fwdObjBuilders.add(fwdObjBosBuilder); - } else { - log.warn("Failed to set MPLS rules."); + metabuilder.build()); + if (fwdObjBosBuilder == null) { return false; } + fwdObjBuilders.add(fwdObjBosBuilder); + + // XXX not-bos pop case, SR app multi-label not implemented yet + /*ForwardingObjective.Builder fwdObjNoBosBuilder = + getMplsForwardingObjective(deviceId, + nextHops, + true, + false);*/ + } else { + // next hop is not destination, SR CONTINUE case (swap with self) log.debug("Installing MPLS forwarding objective for " - + "label {} in switch {} without PHP", - segmentId, - deviceId); + + "label {} in switch {} without pop", segmentId, deviceId); + // continue case with bos - this does get triggered in edge routers + // and in core routers - driver can handle depending on availability + // of MPLS ECMP or not ForwardingObjective.Builder fwdObjBosBuilder = getMplsForwardingObjective(deviceId, - destSwId, nextHops, false, - true); - // TODO: Check with Sangho on why we need this - ForwardingObjective.Builder fwdObjNoBosBuilder = + true, + metabuilder.build()); + if (fwdObjBosBuilder == null) { + return false; + } + fwdObjBuilders.add(fwdObjBosBuilder); + + // XXX continue case with not-bos - SR app multi label not implemented yet + // also requires MPLS ECMP + /*ForwardingObjective.Builder fwdObjNoBosBuilder = getMplsForwardingObjective(deviceId, - destSwId, nextHops, false, - false); - if (fwdObjBosBuilder != null) { - fwdObjBuilders.add(fwdObjBosBuilder); - } else { - log.warn("Failed to set MPLS rules."); - return false; - } + false); */ + } - TrafficSelector selector = sbuilder.build(); for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) { ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId) .makePermanent()).withSelector(selector) @@ -345,76 +360,61 @@ public class RoutingRulePopulator { forward(deviceId, fwdObjBuilder. add(new SRObjectiveContext(deviceId, - SRObjectiveContext.ObjectiveType.FORWARDING))); + SRObjectiveContext.ObjectiveType.FORWARDING))); rulePopulationCounter.incrementAndGet(); } return true; } - private ForwardingObjective.Builder getMplsForwardingObjective(DeviceId deviceId, - DeviceId destSw, - Set nextHops, - boolean phpRequired, - boolean isBos) { + private ForwardingObjective.Builder getMplsForwardingObjective( + DeviceId deviceId, + Set nextHops, + boolean phpRequired, + boolean isBos, + TrafficSelector meta) { + ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective .builder().withFlag(ForwardingObjective.Flag.SPECIFIC); - DeviceId nextHop = (DeviceId) nextHops.toArray()[0]; - - boolean isEdge; - MacAddress srcMac; - MacAddress dstMac; - try { - isEdge = config.isEdgeDevice(deviceId); - srcMac = config.getDeviceMac(deviceId); - dstMac = config.getDeviceMac(nextHop); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting getMplsForwardingObjective"); - return null; - } TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); if (phpRequired) { + // php case - pop should always be flow-action log.debug("getMplsForwardingObjective: php required"); tbuilder.deferred().copyTtlIn(); if (isBos) { - tbuilder.deferred().popMpls(Ethernet.TYPE_IPV4).decNwTtl(); + tbuilder.deferred().popMpls(EthType.EtherType.IPV4.ethType()) + .decNwTtl(); } else { - tbuilder.deferred().popMpls(Ethernet.MPLS_UNICAST).decMplsTtl(); + tbuilder.deferred().popMpls(EthType.EtherType.MPLS_UNICAST.ethType()) + .decMplsTtl(); } } else { + // swap with self case - SR CONTINUE log.debug("getMplsForwardingObjective: php not required"); tbuilder.deferred().decMplsTtl(); } - if (!isECMPSupportedInTransitRouter() && !isEdge) { - PortNumber port = selectOnePort(deviceId, nextHops); - if (port == null) { - log.warn("No link from {} to {}", deviceId, nextHops); - return null; - } - tbuilder.deferred() - .setEthSrc(srcMac) - .setEthDst(dstMac) - .setOutput(port); - fwdBuilder.withTreatment(tbuilder.build()); - } else { - NeighborSet ns = new NeighborSet(nextHops); - fwdBuilder.withTreatment(tbuilder.build()); - fwdBuilder.nextStep(srManager - .getNextObjectiveId(deviceId, ns)); + // All forwarding is via ECMP group, the metadata informs the driver + // that the next-Objective will be used by MPLS flows. In other words, + // MPLS ECMP is requested. It is up to the driver to decide if these + // packets will be hashed or not. + fwdBuilder.withTreatment(tbuilder.build()); + NeighborSet ns = new NeighborSet(nextHops); + log.debug("Trying to get a nextObjid for mpls rule on device:{} to ns:{}", + deviceId, ns); + + int nextId = srManager.getNextObjectiveId(deviceId, ns, meta); + if (nextId <= 0) { + log.warn("No next objective in {} for ns: {}", deviceId, ns); + return null; } + fwdBuilder.nextStep(nextId); return fwdBuilder; } - private boolean isECMPSupportedInTransitRouter() { - - // TODO: remove this function when objectives subsystem is supported. - return false; - } - /** * Creates a filtering objective to permit all untagged packets with a * dstMac corresponding to the router's MAC address. For those pipelines @@ -552,22 +552,6 @@ public class RoutingRulePopulator { } - private PortNumber selectOnePort(DeviceId srcId, Set destIds) { - - Set links = srManager.linkService.getDeviceLinks(srcId); - for (DeviceId destId: destIds) { - for (Link link : links) { - if (link.dst().deviceId().equals(destId)) { - return link.src().port(); - } else if (link.src().deviceId().equals(destId)) { - return link.dst().port(); - } - } - } - - return null; - } - private static class SRObjectiveContext implements ObjectiveContext { enum ObjectiveType { FILTER, diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java index 84fe5168..f6bf649c 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java @@ -424,17 +424,22 @@ public class SegmentRoutingManager implements SegmentRoutingService { /** * Returns the next objective ID for the given NeighborSet. - * If the nextObjectiveID does not exist, a new one is created and returned. + * If the nextObjective does not exist, a new one is created and + * it's id is returned. + * TODO move the side-effect creation of a Next Objective into a new method * * @param deviceId Device ID * @param ns NegighborSet - * @return next objective ID + * @param meta metadata passed into the creation of a Next Objective + * @return next objective ID or -1 if an error was encountered during the + * creation of the nextObjective */ - public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) { + public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns, + TrafficSelector meta) { if (groupHandlerMap.get(deviceId) != null) { log.trace("getNextObjectiveId query in device {}", deviceId); return groupHandlerMap - .get(deviceId).getNextObjectiveId(ns); + .get(deviceId).getNextObjectiveId(ns, meta); } else { log.warn("getNextObjectiveId query in device {} not found", deviceId); return -1; @@ -586,7 +591,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src() .deviceId()); if (groupHandler != null) { - groupHandler.linkUp(link); + groupHandler.linkUp(link, mastershipService.isLocalMaster( + link.src().deviceId())); } else { Device device = deviceService.getDevice(link.src().deviceId()); if (device != null) { @@ -596,7 +602,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { processDeviceAdded(device); groupHandler = groupHandlerMap.get(link.src() .deviceId()); - groupHandler.linkUp(link); + groupHandler.linkUp(link, mastershipService.isLocalMaster(device.id())); } } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java index 7d025c72..b86adada 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java @@ -194,7 +194,7 @@ public class TunnelHandler { tunnel.allowToRemoveGroup(true); } - return groupHandlerMap.get(deviceId).getNextObjectiveId(ns); + return groupHandlerMap.get(deviceId).getNextObjectiveId(ns, null); } } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java index 33496bd7..6b6d960a 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java @@ -93,7 +93,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { + "with label for sw {} is {}", deviceId, nsSet); - createGroupsFromNeighborsets(nsSet); + //createGroupsFromNeighborsets(nsSet); } @Override @@ -107,7 +107,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { Set nsSet = computeImpactedNeighborsetForPortEvent( newNeighborLink.dst().deviceId(), devicePortMap.keySet()); - createGroupsFromNeighborsets(nsSet); + //createGroupsFromNeighborsets(nsSet); } @Override diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java index b394db5e..e792bf66 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java @@ -21,11 +21,11 @@ import static org.slf4j.LoggerFactory.getLogger; import java.net.URI; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import org.onlab.packet.Ip4Prefix; @@ -38,6 +38,7 @@ import org.onosproject.net.DeviceId; import org.onosproject.net.Link; import org.onosproject.net.PortNumber; import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flowobjective.DefaultNextObjective; import org.onosproject.net.flowobjective.FlowObjectiveService; @@ -71,10 +72,10 @@ public class DefaultGroupHandler { protected LinkService linkService; protected FlowObjectiveService flowObjectiveService; - protected HashMap> devicePortMap = new HashMap<>(); - protected HashMap portDeviceMap = new HashMap<>(); - //protected HashMap deviceNextObjectiveIds = - // new HashMap(); + protected ConcurrentHashMap> devicePortMap = + new ConcurrentHashMap<>(); + protected ConcurrentHashMap portDeviceMap = + new ConcurrentHashMap<>(); protected EventuallyConsistentMap< NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null; protected EventuallyConsistentMap< @@ -173,7 +174,7 @@ public class DefaultGroupHandler { * * @param newLink new neighbor link */ - public void linkUp(Link newLink) { + public void linkUp(Link newLink, boolean isMaster) { if (newLink.type() != Link.Type.DIRECT) { log.warn("linkUp: unknown link type"); @@ -186,6 +187,8 @@ public class DefaultGroupHandler { return; } + log.info("* LinkUP: Device {} linkUp at local port {} to neighbor {}", deviceId, + newLink.src().port(), newLink.dst().deviceId()); MacAddress dstMac; try { dstMac = deviceConfig.getDeviceMac(newLink.dst().deviceId()); @@ -194,8 +197,6 @@ public class DefaultGroupHandler { return; } - log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId, - newLink.src().port(), newLink.dst().deviceId()); addNeighborAtPort(newLink.dst().deviceId(), newLink.src().port()); /*if (devicePortMap.get(newLink.dst().deviceId()) == null) { @@ -237,14 +238,20 @@ public class DefaultGroupHandler { nextObjBuilder.addTreatment(tBuilder.build()); - log.debug("linkUp in device {}: Adding Bucket " - + "with Port {} to next object id {}", + log.info("**linkUp in device {}: Adding Bucket " + + "with Port {} to next object id {} and amIMaster:{}", deviceId, newLink.src().port(), - nextId); - NextObjective nextObjective = nextObjBuilder. - add(new SRNextObjectiveContext(deviceId)); - flowObjectiveService.next(deviceId, nextObjective); + nextId, isMaster); + + if (isMaster) { + NextObjective nextObjective = nextObjBuilder. + addToExisting(new SRNextObjectiveContext(deviceId)); + flowObjectiveService.next(deviceId, nextObjective); + } + } else { + log.warn("linkUp in device {}, but global store has no record " + + "for neighbor-set {}", deviceId, ns); } } } @@ -305,15 +312,16 @@ public class DefaultGroupHandler { nextObjBuilder.addTreatment(tBuilder.build()); - log.debug("portDown in device {}: Removing Bucket " + log.info("**portDown in device {}: Removing Bucket " + "with Port {} to next object id {}", deviceId, port, nextId); - NextObjective nextObjective = nextObjBuilder. + // should do removefromexisting and only if master + /*NextObjective nextObjective = nextObjBuilder. remove(new SRNextObjectiveContext(deviceId)); - flowObjectiveService.next(deviceId, nextObjective); + flowObjectiveService.next(deviceId, nextObjective);*/ } } @@ -325,12 +333,15 @@ public class DefaultGroupHandler { /** * Returns the next objective associated with the neighborset. * If there is no next objective for this neighborset, this API - * would create a next objective and return. + * would create a next objective and return. Optionally metadata can be + * passed in for the creation of the next objective. * * @param ns neighborset - * @return int if found or -1 + * @param meta metadata passed into the creation of a Next Objective + * @return int if found or -1 if there are errors in the creation of the + * neighbor set. */ - public int getNextObjectiveId(NeighborSet ns) { + public int getNextObjectiveId(NeighborSet ns, TrafficSelector meta) { Integer nextId = nsNextObjStore. get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); if (nextId == null) { @@ -343,7 +354,7 @@ public class DefaultGroupHandler { .filter((nsStoreEntry) -> (nsStoreEntry.getKey().deviceId().equals(deviceId))) .collect(Collectors.toList())); - createGroupsFromNeighborsets(Collections.singleton(ns)); + createGroupsFromNeighborsets(Collections.singleton(ns), meta); nextId = nsNextObjStore. get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); if (nextId == null) { @@ -421,17 +432,19 @@ public class DefaultGroupHandler { // Update DeviceToPort database log.debug("Device {} addNeighborAtPort: neighbor {} at port {}", deviceId, neighborId, portToNeighbor); - if (devicePortMap.get(neighborId) != null) { - devicePortMap.get(neighborId).add(portToNeighbor); - } else { - Set ports = new HashSet<>(); - ports.add(portToNeighbor); - devicePortMap.put(neighborId, ports); + Set ports = Collections + .newSetFromMap(new ConcurrentHashMap()); + ports.add(portToNeighbor); + Set portnums = devicePortMap.putIfAbsent(neighborId, ports); + if (portnums != null) { + portnums.add(portToNeighbor); } // Update portToDevice database - if (portDeviceMap.get(portToNeighbor) == null) { - portDeviceMap.put(portToNeighbor, neighborId); + DeviceId prev = portDeviceMap.putIfAbsent(portToNeighbor, neighborId); + if (prev != null) { + log.warn("Device: {} port: {} has neighbor: {}. NOT updating " + + "to neighbor: {}", deviceId, portToNeighbor, prev, neighborId); } } @@ -505,61 +518,66 @@ public class DefaultGroupHandler { * Creates Groups from a set of NeighborSet given. * * @param nsSet a set of NeighborSet + * @param meta metadata passed into the creation of a Next Objective */ - public void createGroupsFromNeighborsets(Set nsSet) { + public void createGroupsFromNeighborsets(Set nsSet, + TrafficSelector meta) { for (NeighborSet ns : nsSet) { int nextId = flowObjectiveService.allocateNextId(); NextObjective.Builder nextObjBuilder = DefaultNextObjective .builder().withId(nextId) .withType(NextObjective.Type.HASHED).fromApp(appId); - for (DeviceId d : ns.getDeviceIds()) { - if (devicePortMap.get(d) == null) { - log.warn("Device {} is not in the port map yet", d); + for (DeviceId neighborId : ns.getDeviceIds()) { + if (devicePortMap.get(neighborId) == null) { + log.warn("Neighbor {} is not in the port map yet for dev:{}", + neighborId, deviceId); return; - } else if (devicePortMap.get(d).size() == 0) { + } else if (devicePortMap.get(neighborId).size() == 0) { log.warn("There are no ports for " - + "the Device {} in the port map yet", d); + + "the Device {} in the port map yet", neighborId); return; } - MacAddress deviceMac; + MacAddress neighborMac; try { - deviceMac = deviceConfig.getDeviceMac(d); + neighborMac = deviceConfig.getDeviceMac(neighborId); } catch (DeviceConfigNotFoundException e) { log.warn(e.getMessage() + " Aborting createGroupsFromNeighborsets."); return; } - for (PortNumber sp : devicePortMap.get(d)) { + for (PortNumber sp : devicePortMap.get(neighborId)) { TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment .builder(); - tBuilder.setOutput(sp) - .setEthDst(deviceMac) + tBuilder.setEthDst(neighborMac) .setEthSrc(nodeMacAddr); if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { tBuilder.pushMpls() .copyTtlOut() .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); } + tBuilder.setOutput(sp); nextObjBuilder.addTreatment(tBuilder.build()); } } - + if (meta != null) { + nextObjBuilder.setMeta(meta); + } NextObjective nextObj = nextObjBuilder. add(new SRNextObjectiveContext(deviceId)); - flowObjectiveService.next(deviceId, nextObj); - log.debug("createGroupsFromNeighborsets: Submited " - + "next objective {} in device {}", + log.info("**createGroupsFromNeighborsets: Submited " + + "next objective {} in device {}", nextId, deviceId); + flowObjectiveService.next(deviceId, nextObj); nsNextObjStore.put(new NeighborSetNextObjectiveStoreKey(deviceId, ns), nextId); } } + public void createGroupsFromSubnetConfig() { Map> subnetPortMap = this.deviceConfig.getSubnetPortsMap(this.deviceId); - // Construct a broadcast group for each subnet subnetPortMap.forEach((subnet, ports) -> { SubnetNextObjectiveStoreKey key = @@ -612,6 +630,9 @@ public class DefaultGroupHandler { .withType(NextObjective.Type.HASHED).fromApp(appId); NextObjective nextObjective = nextObjBuilder. remove(new SRNextObjectiveContext(deviceId)); + log.info("**removeGroup: Submited " + + "next objective {} in device {}", + objectiveId, deviceId); flowObjectiveService.next(deviceId, nextObjective); for (Map.Entry entry: nsNextObjStore.entrySet()) { @@ -634,14 +655,14 @@ public class DefaultGroupHandler { } @Override public void onSuccess(Objective objective) { - log.debug("Next objective operation successful in device {}", - deviceId); + log.info("Next objective {} operation successful in device {}", + objective.id(), deviceId); } @Override public void onError(Objective objective, ObjectiveError error) { log.warn("Next objective {} operation failed with error: {} in device {}", - objective, error, deviceId); + objective.id(), error, deviceId); } } } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java index 8e1b6a8f..14d77ba6 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java @@ -81,7 +81,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { log.debug("createGroupsAtTransitRouter: The neighborset with label " + "for sw {} is {}", deviceId, nsSet); - createGroupsFromNeighborsets(nsSet); + //createGroupsFromNeighborsets(nsSet); } @Override @@ -95,7 +95,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { Set nsSet = computeImpactedNeighborsetForPortEvent( newNeighborLink.dst().deviceId(), devicePortMap.keySet()); - createGroupsFromNeighborsets(nsSet); + //createGroupsFromNeighborsets(nsSet); } @Override diff --git a/framework/src/onos/apps/virtualbng/features.xml b/framework/src/onos/apps/virtualbng/features.xml index 2b48bec3..c997d4c6 100644 --- a/framework/src/onos/apps/virtualbng/features.xml +++ b/framework/src/onos/apps/virtualbng/features.xml @@ -15,7 +15,6 @@ ~ limitations under the License. --> - mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features mvn:com.sun.jersey/jersey-client/1.19 diff --git a/framework/src/onos/apps/vtn/app/features.xml b/framework/src/onos/apps/vtn/app/features.xml index c82b41d5..8ee882c4 100644 --- a/framework/src/onos/apps/vtn/app/features.xml +++ b/framework/src/onos/apps/vtn/app/features.xml @@ -15,7 +15,6 @@ ~ limitations under the License. --> - mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features onos-api diff --git a/framework/src/onos/apps/vtn/sfcmgr/pom.xml b/framework/src/onos/apps/vtn/sfcmgr/pom.xml new file mode 100644 index 00000000..8b5f1983 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/pom.xml @@ -0,0 +1,67 @@ + + + + 4.0.0 + + org.onosproject + onos-app-vtn + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-app-sfc-mgr + bundle + + + + org.onosproject + onos-api + + + org.apache.felix + org.apache.felix.scr.annotations + + + org.onosproject + onos-core-serializers + ${project.version} + + + org.onosproject + onos-app-vtn-rsc + ${project.version} + + + + + + + org.apache.felix + maven-bundle-plugin + + + + org.onosproject.openflow.*,org.projectfloodlight.openflow.* + + + + + + + diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java new file mode 100644 index 00000000..e91e6b69 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.forwarder; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtnrsc.PortChain; + +/** + * Abstraction of an entity which provides Service function forwarder. + */ +public interface ServiceFunctionForwarder { + + /** + * Install Service function chain. + * + * @param portChain Port chain + */ + void install(PortChain portChain); + + /** + * Programs forwarding object for Service Function. + * + * @param portChain port chain + * @param appid application id + * @param type forwarding objective operation type + */ + void programServiceFunctionForwarder(PortChain portChain, ApplicationId appid, + Objective.Operation type); +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/package-info.java new file mode 100644 index 00000000..08021f3c --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Service function forwarder for SFC. + */ +package org.onosproject.sfc.forwarder; diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/FlowClassifierInstaller.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/FlowClassifierInstaller.java new file mode 100644 index 00000000..f05a21dc --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/FlowClassifierInstaller.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.installer; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.PortPair; + +/** + * Abstraction of an entity which installs flow classification rules in ovs. + */ +public interface FlowClassifierInstaller { + + /** + * Install flow classifier rules. + * + * @param flowClassifier Flow Classifier + * @param portPair Port pair + */ + void install(FlowClassifier flowClassifier, PortPair portPair); + + /** + * Programs forwarding object for flow classifier. + * + * @param flowClassifier flow classifier + * @param portPair port pair + * @param appid application id + * @param type forwarding objective operation type + */ + void programFlowClassification(FlowClassifier flowClassifier, PortPair portPair, ApplicationId appid, + Objective.Operation type); +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/DefaultFlowClassifierInstaller.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/DefaultFlowClassifierInstaller.java new file mode 100644 index 00000000..e1a80932 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/DefaultFlowClassifierInstaller.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.installer.impl; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flowobjective.Objective.Operation; +import org.onosproject.sfc.installer.FlowClassifierInstaller; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.PortPair; + +/** + * Provides flow classifier installer. + */ +public class DefaultFlowClassifierInstaller implements FlowClassifierInstaller { + + /** + * Default constructor. + */ + public DefaultFlowClassifierInstaller() { + } + + @Override + public void install(FlowClassifier flowClassifier, PortPair portPair) { + // TODO: Process flow-classifier for installation. + } + + @Override + public void programFlowClassification(FlowClassifier flowClassifier, PortPair portPair, ApplicationId appid, + Operation type) { + // TODO: program forwarding objective for flow-classifier installation. + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/package-info.java new file mode 100644 index 00000000..d9796d80 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Implementation of Service for installing flow classifier rules in OVS. + */ +package org.onosproject.sfc.installer.impl; diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/package-info.java new file mode 100644 index 00000000..77c0ab30 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Service for installing flow classifier rules in OVS. + */ +package org.onosproject.sfc.installer; diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java new file mode 100644 index 00000000..ef5fc529 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.manager; + +/** + * SFC application that applies flows to the device. + */ +public interface SfcService { + + /** + * When port-pair is created, check whether Forwarding Rule needs to be + * updated in OVS. + */ + public void onPortPairCreated(); + + /** + * When port-pair is deleted, check whether Forwarding Rule needs to be + * updated in OVS. + */ + public void onPortPairDeleted(); + + /** + * When port-pair-group is created, check whether Forwarding Rule needs to + * be updated in OVS. + */ + public void onPortPairGroupCreated(); + + /** + * When port-pair-group is deleted, check whether Forwarding Rule needs to + * be updated in OVS. + */ + public void onPortPairGroupDeleted(); + + /** + * When flow-classifier is created, check whether Forwarding Rule needs to + * be updated in OVS. + */ + public void onFlowClassifierCreated(); + + /** + * When flow-classifier is deleted, check whether Forwarding Rule needs to + * be updated in OVS. + */ + public void onFlowClassifierDeleted(); + + /** + * When port-chain is created, check whether Forwarding Rule needs to be + * updated in OVS. + */ + public void onPortChainCreated(); + + /** + * When port-chain is deleted, check whether Forwarding Rule needs to be + * updated in OVS. + */ + public void onPortChainDeleted(); +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java new file mode 100644 index 00000000..12d27c87 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java @@ -0,0 +1,125 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.manager.impl; + +import static org.slf4j.LoggerFactory.getLogger; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Service; +import org.onosproject.sfc.manager.SfcService; +import org.onosproject.vtnrsc.PortChain; +import org.slf4j.Logger; + +/** + * Provides implementation of SFC Service. + */ +@Component(immediate = true) +@Service +public class SfcManager implements SfcService { + + private final Logger log = getLogger(getClass()); + + @Activate + public void activate() { + log.info("Started"); + } + + @Deactivate + public void deactivate() { + log.info("Stopped"); + } + + @Override + public void onPortPairCreated() { + log.debug("onPortPairCreated"); + // TODO: Process port-pair on creation. + // TODO: Parameter also needs to be modified. + } + + @Override + public void onPortPairDeleted() { + log.debug("onPortPairDeleted"); + // TODO: Process port-pair on deletion. + // TODO: Parameter also needs to be modified. + } + + @Override + public void onPortPairGroupCreated() { + log.debug("onPortPairGroupCreated"); + // TODO: Process port-pair-group on creation. + // TODO: Parameter also needs to be modified. + } + + @Override + public void onPortPairGroupDeleted() { + log.debug("onPortPairGroupDeleted"); + // TODO: Process port-pair-group on deletion. + // TODO: Parameter also needs to be modified. + } + + @Override + public void onFlowClassifierCreated() { + log.debug("onFlowClassifierCreated"); + // TODO: Process flow-classifier on creation. + // TODO: Parameter also needs to be modified. + } + + @Override + public void onFlowClassifierDeleted() { + log.debug("onFlowClassifierDeleted"); + // TODO: Process flow-classifier on deletion. + // TODO: Parameter also needs to be modified. + } + + @Override + public void onPortChainCreated() { + log.debug("onPortChainCreated"); + // TODO: Process port-chain on creation. + // TODO: Parameter also needs to be modified. + + } + + @Override + public void onPortChainDeleted() { + log.debug("onPortChainDeleted"); + // TODO: Process port-chain on deletion. + // TODO: Parameter also needs to be modified. + } + + /** + * Install SF Forwarding rule into OVS. + * + * @param portChain + * port chain + */ + public void installForwardingRule(PortChain portChain) { + log.debug("installForwardingRule"); + // TODO: Installation of SF Forwarding rule into OVS. + } + + /** + * Uninstall SF Forwarding rule from OVS. + * + * @param portChain + * port chain + */ + public void unInstallForwardingRule(PortChain portChain) { + log.debug("unInstallForwardingRule"); + // TODO: Uninstallation of SF Forwarding rule from OVS. + } +} \ No newline at end of file diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/package-info.java new file mode 100644 index 00000000..7161380a --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * SFC Service manager for interacting with SFC. + */ +package org.onosproject.sfc.manager.impl; diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/package-info.java new file mode 100644 index 00000000..1dd0f5a0 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Service for interacting with SFC. + */ +package org.onosproject.sfc.manager; diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java new file mode 100644 index 00000000..a104e529 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.manager; + +import org.onosproject.net.Device; +import org.onosproject.net.Host; + +/** + * VTN application that applies configuration and flows to the device. + */ +public interface VTNService { + + /** + * Creates a vxlan tunnel and creates the ovs when a ovs controller node is + * detected. + * + * @param device controller-type device + */ + void onControllerDetected(Device device); + + /** + * Drops a vxlan tunnel and drops the ovs when a ovs controller node is + * vanished. + * + * @param device controller-type device + */ + void onControllerVanished(Device device); + + /** + * Applies default forwarding flows when a ovs is detected. + * + * @param device switch-type device + */ + void onOvsDetected(Device device); + + /** + * Remove default forwarding flows when a ovs is vanished. + * + * @param device switch-type device + */ + void onOvsVanished(Device device); + + /** + * Applies multicast flows and tunnel flows when a VM is detected. + * + * @param host a VM + */ + void onHostDetected(Host host); + + /** + * Remove multicast flows and tunnel flows when a VM is vanished. + * + * @param host a VM + */ + void onHostVanished(Host host); + +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java new file mode 100644 index 00000000..be6b9364 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java @@ -0,0 +1,585 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.manager.impl; + +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST; +import static org.slf4j.LoggerFactory.getLogger; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.util.KryoNamespace; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.mastership.MastershipService; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Host; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.net.behaviour.BridgeConfig; +import org.onosproject.net.behaviour.BridgeDescription; +import org.onosproject.net.behaviour.ExtensionTreatmentResolver; +import org.onosproject.net.config.NetworkConfigService; +import org.onosproject.net.config.basics.BasicDeviceConfig; +import org.onosproject.net.device.DeviceEvent; +import org.onosproject.net.device.DeviceListener; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.net.driver.DriverService; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficTreatment.Builder; +import org.onosproject.net.flow.instructions.ExtensionTreatment; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.net.group.DefaultGroupBucket; +import org.onosproject.net.group.DefaultGroupDescription; +import org.onosproject.net.group.DefaultGroupKey; +import org.onosproject.net.group.GroupBucket; +import org.onosproject.net.group.GroupBuckets; +import org.onosproject.net.group.GroupDescription; +import org.onosproject.net.group.GroupKey; +import org.onosproject.net.group.GroupService; +import org.onosproject.net.host.HostEvent; +import org.onosproject.net.host.HostListener; +import org.onosproject.net.host.HostService; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.EventuallyConsistentMap; +import org.onosproject.store.service.LogicalClockService; +import org.onosproject.store.service.StorageService; +import org.onosproject.vtn.manager.VTNService; +import org.onosproject.vtn.table.ClassifierService; +import org.onosproject.vtn.table.L2ForwardService; +import org.onosproject.vtn.table.impl.ClassifierServiceImpl; +import org.onosproject.vtn.table.impl.L2ForwardServiceImpl; +import org.onosproject.vtn.util.DataPathIdGenerator; +import org.onosproject.vtn.util.VtnConfig; +import org.onosproject.vtn.util.VtnData; +import org.onosproject.vtnrsc.AllowedAddressPair; +import org.onosproject.vtnrsc.BindingHostId; +import org.onosproject.vtnrsc.DefaultVirtualPort; +import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.SecurityGroup; +import org.onosproject.vtnrsc.SegmentationId; +import org.onosproject.vtnrsc.SubnetId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetwork; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPort; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; +import org.onosproject.vtnrsc.virtualport.VirtualPortService; +import org.slf4j.Logger; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +/** + * Provides implementation of VTNService. + */ +@Component(immediate = true) +@Service +public class VTNManager implements VTNService { + private final Logger log = getLogger(getClass()); + private static final String APP_ID = "org.onosproject.app.vtn"; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected NetworkConfigService configService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected HostService hostService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected TenantNetworkService tenantNetworkService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VirtualPortService virtualPortService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DriverService driverService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected LogicalClockService clockService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected MastershipService mastershipService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected GroupService groupService; + + private ApplicationId appId; + private ClassifierService classifierService; + private L2ForwardService l2ForwardService; + + private final HostListener hostListener = new InnerHostListener(); + private final DeviceListener deviceListener = new InnerDeviceListener(); + + private static final String IFACEID = "ifaceid"; + private static final String CONTROLLER_IP_KEY = "ipaddress"; + public static final String DRIVER_NAME = "onosfw"; + private static final String EX_PORT_NAME = "eth0"; + private static final String VIRTUALPORT = "vtn-virtual-port"; + private static final String SWITCHES_OF_CONTROLLER = "switchesOfController"; + private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts"; + private static final String DEFAULT_IP = "0.0.0.0"; + + private EventuallyConsistentMap vPortStore; + private EventuallyConsistentMap switchesOfController; + private EventuallyConsistentMap switchOfLocalHostPorts; + + @Activate + public void activate() { + appId = coreService.registerApplication(APP_ID); + classifierService = new ClassifierServiceImpl(appId); + l2ForwardService = new L2ForwardServiceImpl(appId); + + deviceService.addListener(deviceListener); + hostService.addListener(hostListener); + + KryoNamespace.Builder serializer = KryoNamespace.newBuilder() + .register(KryoNamespaces.API) + .register(NetworkOfLocalHostPorts.class) + .register(TenantNetworkId.class) + .register(Host.class) + .register(TenantNetwork.class) + .register(TenantId.class) + .register(SubnetId.class) + .register(VirtualPortId.class) + .register(VirtualPort.State.class) + .register(AllowedAddressPair.class) + .register(FixedIp.class) + .register(BindingHostId.class) + .register(SecurityGroup.class) + .register(IpAddress.class) + .register(DefaultVirtualPort.class); + + vPortStore = storageService + .eventuallyConsistentMapBuilder() + .withName(VIRTUALPORT).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + + switchesOfController = storageService + .eventuallyConsistentMapBuilder() + .withName(SWITCHES_OF_CONTROLLER).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + + switchOfLocalHostPorts = storageService + .eventuallyConsistentMapBuilder() + .withName(SWITCH_OF_LOCAL_HOST_PORTS).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + + log.info("Started"); + } + + @Deactivate + public void deactivate() { + deviceService.removeListener(deviceListener); + hostService.removeListener(hostListener); + log.info("Stopped"); + } + + @Override + public void onControllerDetected(Device controllerDevice) { + if (controllerDevice == null) { + log.error("The controller device is null"); + return; + } + String localIpAddress = controllerDevice.annotations() + .value(CONTROLLER_IP_KEY); + IpAddress localIp = IpAddress.valueOf(localIpAddress); + DeviceId controllerDeviceId = controllerDevice.id(); + DriverHandler handler = driverService.createHandler(controllerDeviceId); + if (mastershipService.isLocalMaster(controllerDeviceId)) { + // Get DataPathIdGenerator + String ipaddress = controllerDevice.annotations().value("ipaddress"); + DataPathIdGenerator dpidGenerator = DataPathIdGenerator.builder() + .addIpAddress(ipaddress).build(); + DeviceId deviceId = dpidGenerator.getDeviceId(); + String dpid = dpidGenerator.getDpId(); + // Inject pipeline driver name + BasicDeviceConfig config = configService.addConfig(deviceId, + BasicDeviceConfig.class); + config.driver(DRIVER_NAME); + configService.applyConfig(deviceId, BasicDeviceConfig.class, config.node()); + // Add Bridge + VtnConfig.applyBridgeConfig(handler, dpid, EX_PORT_NAME); + log.info("A new ovs is created in node {}", localIp.toString()); + switchesOfController.put(localIp, true); + } + // Create tunnel in br-int on all controllers + programTunnelConfig(controllerDeviceId, localIp, handler); + } + + @Override + public void onControllerVanished(Device controllerDevice) { + if (controllerDevice == null) { + log.error("The device is null"); + return; + } + String dstIp = controllerDevice.annotations().value(CONTROLLER_IP_KEY); + IpAddress dstIpAddress = IpAddress.valueOf(dstIp); + DeviceId controllerDeviceId = controllerDevice.id(); + if (mastershipService.isLocalMaster(controllerDeviceId)) { + switchesOfController.remove(dstIpAddress); + } + // remove tunnel in br-int on other controllers + programTunnelConfig(controllerDeviceId, dstIpAddress, null); + } + + @Override + public void onOvsDetected(Device device) { + // Create tunnel out flow rules + applyTunnelOut(device, Objective.Operation.ADD); + } + + @Override + public void onOvsVanished(Device device) { + // Remove Tunnel out flow rules + applyTunnelOut(device, Objective.Operation.REMOVE); + } + + @Override + public void onHostDetected(Host host) { + // apply L2 openflow rules + applyHostMonitoredL2Rules(host, Objective.Operation.ADD); + } + + @Override + public void onHostVanished(Host host) { + // apply L2 openflow rules + applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE); + } + + private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp, + DriverHandler localHandler) { + if (mastershipService.isLocalMaster(localDeviceId)) { + VtnConfig.applyTunnelConfig(localHandler, localIp, IpAddress.valueOf(DEFAULT_IP)); + log.info("Add tunnel on {}", localIp); + } + } + + private void applyTunnelOut(Device device, Objective.Operation type) { + if (device == null) { + log.error("The device is null"); + return; + } + if (!mastershipService.isLocalMaster(device.id())) { + return; + } + String controllerIp = VtnData.getControllerIpOfSwitch(device); + if (controllerIp == null) { + log.error("Can't find controller of device: {}", + device.id().toString()); + return; + } + IpAddress ipAddress = IpAddress.valueOf(controllerIp); + if (!switchesOfController.containsKey(ipAddress)) { + log.error("Can't find controller of device: {}", + device.id().toString()); + return; + } + if (type == Objective.Operation.ADD) { + switchOfLocalHostPorts.put(device.id(), new NetworkOfLocalHostPorts()); + } else if (type == Objective.Operation.REMOVE) { + switchOfLocalHostPorts.remove(device.id()); + } + Iterable devices = deviceService.getAvailableDevices(); + DeviceId localControllerId = VtnData.getControllerId(device, devices); + DriverHandler handler = driverService.createHandler(localControllerId); + Set ports = VtnConfig.getPortNumbers(handler); + Iterable allHosts = hostService.getHosts(); + String tunnelName = "vxlan-" + DEFAULT_IP; + if (allHosts != null) { + Sets.newHashSet(allHosts).stream().forEach(host -> { + MacAddress hostMac = host.mac(); + String ifaceId = host.annotations().value(IFACEID); + if (ifaceId == null) { + log.error("The ifaceId of Host is null"); + return; + } + VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId); + VirtualPort virtualPort = virtualPortService + .getPort(virtualPortId); + TenantNetwork network = tenantNetworkService + .getNetwork(virtualPort.networkId()); + SegmentationId segmentationId = network.segmentationId(); + DeviceId remoteDeviceId = host.location().deviceId(); + Device remoteDevice = deviceService.getDevice(remoteDeviceId); + String remoteControllerIp = VtnData + .getControllerIpOfSwitch(remoteDevice); + if (remoteControllerIp == null) { + log.error("Can't find remote controller of device: {}", + remoteDeviceId.toString()); + return; + } + IpAddress remoteIpAddress = IpAddress + .valueOf(remoteControllerIp); + ports.stream() + .filter(p -> p.name().equalsIgnoreCase(tunnelName)) + .forEach(p -> { + l2ForwardService + .programTunnelOut(device.id(), segmentationId, p, + hostMac, type, remoteIpAddress); + }); + }); + } + } + + private void applyHostMonitoredL2Rules(Host host, Objective.Operation type) { + DeviceId deviceId = host.location().deviceId(); + if (!mastershipService.isLocalMaster(deviceId)) { + return; + } + String ifaceId = host.annotations().value(IFACEID); + if (ifaceId == null) { + log.error("The ifaceId of Host is null"); + return; + } + VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId); + VirtualPort virtualPort = virtualPortService.getPort(virtualPortId); + if (virtualPort == null) { + virtualPort = vPortStore.get(virtualPortId); + } + + Iterable devices = deviceService.getAvailableDevices(); + PortNumber inPort = host.location().port(); + MacAddress mac = host.mac(); + Device device = deviceService.getDevice(deviceId); + String controllerIp = VtnData.getControllerIpOfSwitch(device); + IpAddress ipAddress = IpAddress.valueOf(controllerIp); + TenantNetwork network = tenantNetworkService.getNetwork(virtualPort.networkId()); + if (network == null) { + log.error("Can't find network of the host"); + return; + } + SegmentationId segmentationId = network.segmentationId(); + // Get all the tunnel PortNumber in the current node + Iterable ports = deviceService.getPorts(deviceId); + Collection localTunnelPorts = VtnData.getLocalTunnelPorts(ports); + // Get all the local vm's PortNumber in the current node + Map> localHostPorts = switchOfLocalHostPorts + .get(deviceId).getNetworkOfLocalHostPorts(); + Set networkOflocalHostPorts = localHostPorts.get(network.id()); + for (PortNumber p : localTunnelPorts) { + programGroupTable(deviceId, appId, p, devices, type); + } + + if (type == Objective.Operation.ADD) { + vPortStore.put(virtualPortId, virtualPort); + if (networkOflocalHostPorts == null) { + networkOflocalHostPorts = new HashSet(); + localHostPorts.putIfAbsent(network.id(), networkOflocalHostPorts); + } + networkOflocalHostPorts.add(inPort); + l2ForwardService.programLocalBcastRules(deviceId, segmentationId, + inPort, networkOflocalHostPorts, + localTunnelPorts, + type); + classifierService.programTunnelIn(deviceId, segmentationId, + localTunnelPorts, + type); + } else if (type == Objective.Operation.REMOVE) { + vPortStore.remove(virtualPortId); + if (networkOflocalHostPorts != null) { + l2ForwardService.programLocalBcastRules(deviceId, segmentationId, + inPort, networkOflocalHostPorts, + localTunnelPorts, + type); + networkOflocalHostPorts.remove(inPort); + if (networkOflocalHostPorts.isEmpty()) { + classifierService.programTunnelIn(deviceId, segmentationId, + localTunnelPorts, + type); + switchOfLocalHostPorts.get(deviceId).getNetworkOfLocalHostPorts() + .remove(virtualPort.networkId()); + } + } + } + + l2ForwardService.programLocalOut(deviceId, segmentationId, inPort, mac, + type); + + l2ForwardService.programTunnelBcastRules(deviceId, segmentationId, + networkOflocalHostPorts, + localTunnelPorts, + type); + + programTunnelOuts(devices, ipAddress, segmentationId, mac, + type); + + classifierService.programLocalIn(deviceId, segmentationId, inPort, mac, + appId, type); + } + + private void programTunnelOuts(Iterable devices, + IpAddress ipAddress, + SegmentationId segmentationId, + MacAddress dstMac, + Objective.Operation type) { + String tunnelName = "vxlan-" + DEFAULT_IP; + Sets.newHashSet(devices).stream() + .filter(d -> d.type() == Device.Type.CONTROLLER) + .filter(d -> !("ovsdb:" + ipAddress).equals(d.id().toString())) + .forEach(d -> { + DriverHandler handler = driverService.createHandler(d.id()); + BridgeConfig bridgeConfig = handler + .behaviour(BridgeConfig.class); + Collection bridgeDescriptions = bridgeConfig + .getBridges(); + Set ports = bridgeConfig.getPortNumbers(); + Iterator it = bridgeDescriptions + .iterator(); + if (it.hasNext()) { + BridgeDescription sw = it.next(); + ports.stream() + .filter(p -> p.name() + .equalsIgnoreCase(tunnelName)) + .forEach(p -> { + l2ForwardService.programTunnelOut(sw.deviceId(), + segmentationId, p, + dstMac, type, ipAddress); + }); + } + }); + } + + private class InnerDeviceListener implements DeviceListener { + + @Override + public void event(DeviceEvent event) { + Device device = event.subject(); + if (Device.Type.CONTROLLER == device.type()) { + if (DeviceEvent.Type.DEVICE_ADDED == event.type()) { + onControllerDetected(device); + } + if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) { + if (deviceService.isAvailable(device.id())) { + onControllerDetected(device); + } else { + onControllerVanished(device); + } + } + } else if (Device.Type.SWITCH == device.type()) { + if (DeviceEvent.Type.DEVICE_ADDED == event.type()) { + onOvsDetected(device); + } + if (DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event.type()) { + if (deviceService.isAvailable(device.id())) { + onOvsDetected(device); + } else { + onOvsVanished(device); + } + } + } else { + log.info("Do nothing for this device type"); + } + } + } + + private class InnerHostListener implements HostListener { + + @Override + public void event(HostEvent event) { + Host host = event.subject(); + if (HostEvent.Type.HOST_ADDED == event.type()) { + onHostDetected(host); + } else if (HostEvent.Type.HOST_REMOVED == event.type()) { + onHostVanished(host); + } else if (HostEvent.Type.HOST_UPDATED == event.type()) { + onHostVanished(host); + onHostDetected(host); + } + } + + } + + // Local Host Ports of Network. + private class NetworkOfLocalHostPorts { + private final Map> networkOfLocalHostPorts = + new HashMap>(); + + public Map> getNetworkOfLocalHostPorts() { + return networkOfLocalHostPorts; + } + } + + private void programGroupTable(DeviceId deviceId, ApplicationId appid, + PortNumber portNumber, Iterable devices, Objective.Operation type) { + if (type.equals(Objective.Operation.REMOVE)) { + return; + } + + List buckets = Lists.newArrayList(); + Sets.newHashSet(devices) + .stream() + .filter(d -> d.type() == Device.Type.CONTROLLER) + .filter(d -> !deviceId.equals(d.id())) + .forEach(d -> { + String ipAddress = d.annotations() + .value(CONTROLLER_IP_KEY); + Ip4Address dst = Ip4Address.valueOf(ipAddress); + Builder builder = DefaultTrafficTreatment.builder(); + + DriverHandler handler = driverService.createHandler(deviceId); + ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class); + ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type()); + try { + treatment.setPropertyValue("tunnelDst", dst); + } catch (Exception e) { + log.error("Failed to get extension instruction to set tunnel dst {}", deviceId); + } + + builder.extension(treatment, deviceId); + builder.setOutput(portNumber); + GroupBucket bucket = DefaultGroupBucket + .createAllGroupBucket(builder.build()); + buckets.add(bucket); + }); + final GroupKey key = new DefaultGroupKey(APP_ID.getBytes()); + GroupDescription groupDescription = new DefaultGroupDescription(deviceId, + GroupDescription.Type.ALL, + new GroupBuckets(buckets), + key, + L2ForwardServiceImpl.GROUP_ID, + appid); + groupService.addGroup(groupDescription); + } +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/package-info.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/package-info.java new file mode 100644 index 00000000..4c9a58cc --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * VTN application that applies configuration and flows to the device. + */ +package org.onosproject.vtn.manager.impl; diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/package-info.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/package-info.java new file mode 100644 index 00000000..09bd80f8 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * VTN application that applies configuration and flows to the device. + */ +package org.onosproject.vtn.manager; diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java new file mode 100644 index 00000000..b548938b --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.net.DeviceId; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtnrsc.SegmentationId; + +/** + * ArpService interface providing the rules in ARP table which is Table(10). + */ +public interface ArpService { + + /** + * Assemble the arp rules. + * Match: arp type, vnid and destination ip. + * Action: set arp_operation, move arp_eth_src to arp_eth_dst, set arp_eth_src, + * move arp_ip_src to arp_ip_dst, set arp_ip_src, set output port. + * + * @param deviceId Device Id + * @param dstIP destination ip + * @param matchVni the vni of the source network (l2vni) + * @param dstMac destination mac + * @param type the operation type of the flow rules + */ + void programArpRules(DeviceId deviceId, IpAddress dstIP, + SegmentationId matchVni, MacAddress dstMac, + Objective.Operation type); +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ClassifierService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ClassifierService.java new file mode 100644 index 00000000..69e951a2 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ClassifierService.java @@ -0,0 +1,105 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtnrsc.SegmentationId; + +/** + * Applies classifier flows to the device. Classifier table is Table(0). + */ +public interface ClassifierService { + + /** + * The port rule that message from host matches Table(0) Match: host mac and + * ingress port Action: set vnid and go to L2Forward Table(50). + * + * @param deviceId Device Id + * @param segmentationId the vnid of the host belong to + * @param inPort the ingress port of the host + * @param srcMac the mac of the host + * @param appId the application ID of the vtn + * @param type the operation of the flow + */ + void programLocalIn(DeviceId deviceId, SegmentationId segmentationId, + PortNumber inPort, MacAddress srcMac, + ApplicationId appId, Objective.Operation type); + + /** + * The port rule that message from tunnel Table(0) Match: tunnel port and + * vnid Action: go to L2Forward Table(50). + * + * @param deviceId Device Id + * @param segmentationId the vnid of the host belong to + * @param localTunnelPorts the tunnel pors of the device + * @param type the operation of the flow + */ + void programTunnelIn(DeviceId deviceId, SegmentationId segmentationId, + Iterable localTunnelPorts, + Objective.Operation type); + + /** + * Assemble the L3 Classifier table rules which are sended from external port. + * Match: ipv4 type, ingress port and destination ip. + * Action: go to DNAT Table(20). + * + * @param deviceId Device Id + * @param inPort external port + * @param dstIp floating ip + * @param type the operation type of the flow rules + */ + void programL3ExPortClassifierRules(DeviceId deviceId, PortNumber inPort, + IpAddress dstIp, + Objective.Operation type); + + /** + * Assemble the L3 Classifier table rules which are sended from internal port. + * Match: ingress port, source mac and destination mac. + * Action: set vnid and go to L3Forward Table(30). + * + * @param deviceId Device Id + * @param inPort the ingress port of the host + * @param srcMac source mac + * @param dstMac destination vm gateway mac + * @param actionVni the vni of L3 network + * @param type the operation type of the flow rules + */ + void programL3InPortClassifierRules(DeviceId deviceId, + PortNumber inPort, MacAddress srcMac, + MacAddress dstMac, + SegmentationId actionVni, + Objective.Operation type); + + /** + * Assemble the Arp Classifier table rules. + * Match: arp type and destination ip. + * Action: set vnid and go to ARP Table(10). + * + * @param deviceId Device Id + * @param dstIp source gateway ip + * @param actionVni the vni of the source network (l2vni) + * @param type the operation type of the flow rules + */ + void programArpClassifierRules(DeviceId deviceId, IpAddress dstIp, + SegmentationId actionVni, + Objective.Operation type); + +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/DnatService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/DnatService.java new file mode 100644 index 00000000..88c56288 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/DnatService.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.net.DeviceId; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtnrsc.SegmentationId; + +/** + * DnatService interface provides the rules in DNAT table which is Table(20) for ovs pipeline. + * DNAT means Destination Network Address Translation, it is acronym for network terminology. + * Handle the downward flows. + */ +public interface DnatService { + + /** + * Assemble the DNAT table rules. + * Match: ipv4 type and destination ip. + * Action: set eth_src, set ip_dst, set vnid and goto L3Forward Table(30). + * + * @param deviceId Device Id + * @param dstIp floating ip + * @param ethSrc floating ip gateway mac + * @param ipDst destination vm ip + * @param actionVni the vni of L3 network + * @param type the operation type of the flow rules + */ + void programRules(DeviceId deviceId, IpAddress dstIp, + MacAddress ethSrc, IpAddress ipDst, + SegmentationId actionVni, Objective.Operation type); +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/L2ForwardService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/L2ForwardService.java new file mode 100644 index 00000000..cb661f8b --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/L2ForwardService.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtnrsc.SegmentationId; + +/** + * Applies L2 flows to the device. L2Forward table is Table(50). + */ +public interface L2ForwardService { + + /** + * The local broadcast rule that message matches Table(50). + * Match: broadcast mac and vnid. + * Action: set output port. + * + * @param deviceId Device Id + * @param segmentationId the vnid of the host belong to + * @param inPort the ingress port of the host + * @param localVmPorts the local ports of the network which connect host + * @param localTunnelPorts the tunnel pors of the device + * @param type the operation of the flow + */ + void programLocalBcastRules(DeviceId deviceId, + SegmentationId segmentationId, + PortNumber inPort, + Iterable localVmPorts, + Iterable localTunnelPorts, + Objective.Operation type); + + /** + * The tunnel broadcast rule that message matches Table(50). + * Match: broadcast mac and vnid. + * Action: output port. + * + * @param deviceId Device Id + * @param segmentationId the vnid of the host belong to + * @param localVmPorts the local ports of the network which connect host + * @param localTunnelPorts the tunnel pors of the device + * @param type the operation of the flow + */ + void programTunnelBcastRules(DeviceId deviceId, + SegmentationId segmentationId, + Iterable localVmPorts, + Iterable localTunnelPorts, + Objective.Operation type); + + /** + * The local out rule that message matches Table(50). + * Match: local host mac and vnid. + * Action: output local host port. + * + * @param deviceId Device Id + * @param segmentationId the vnid of the host belong to + * @param outPort the ingress port of the host + * @param sourceMac the mac of the host + * @param type the operation of the flow + */ + void programLocalOut(DeviceId deviceId, SegmentationId segmentationId, + PortNumber outPort, MacAddress sourceMac, + Objective.Operation type); + + /** + * The tunnel out rule that message matches Table(50). + * Match: host mac and vnid. + * Action: output tunnel port. + * + * @param deviceId Device Id + * @param segmentationId the vnid of the host belong to + * @param tunnelOutPort the port of the tunnel + * @param dstMac the mac of the host + * @param type the operation of the flow + * @param ipAddress the ipAddress of the node + */ + void programTunnelOut(DeviceId deviceId, SegmentationId segmentationId, + PortNumber tunnelOutPort, MacAddress dstMac, + Objective.Operation type, IpAddress ipAddress); + +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/L3ForwardService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/L3ForwardService.java new file mode 100644 index 00000000..718253a4 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/L3ForwardService.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.net.DeviceId; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtnrsc.SegmentationId; + +/** + * L3ForwardService interface provide the rules in L3Forward table which is Table(30). + */ +public interface L3ForwardService { + + /** + * Assemble the L3Forward table rules. + * Match: ipv4 type, vnid and destination ip. + * Action: set eth_src, set eth_dst, set vnid and goto L2Forward Table(50). + * + * @param deviceId Device Id + * @param l3Vni the vni of L3 network + * @param dstVmIP destination vm ip + * @param dstVni the vni of the destination network (l2vni) + * @param dstVmGwMac destination VM gateway mac + * @param dstVmMac destination VM mac + * @param type the operation type of the flow rules + */ + void programRouteRules(DeviceId deviceId, SegmentationId l3Vni, + IpAddress dstVmIP, SegmentationId dstVni, + MacAddress dstVmGwMac, MacAddress dstVmMac, + Objective.Operation type); + +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/SnatService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/SnatService.java new file mode 100644 index 00000000..e57596ed --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/SnatService.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.net.DeviceId; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtnrsc.SegmentationId; + +/** + * SnatService interface provides the rules in SNAT table which is Table(40) for ovs pipeline. + * SNAT means Source Network Address Translation, it is acronym for network terminology. + * Handle the upward flows. + */ +public interface SnatService { + + /** + * Assemble the SNAT table rules. + * Match: ipv4 type, vnid and source ip. + * Action: set eth_src, set eth_dst, set ip_src, set vnid and goto L2Forward Table(50). + * + * @param deviceId Device Id + * @param matchVni the vni of L3 network + * @param srcIP source ip + * @param ethDst external gateway mac + * @param ethSrc external port mac + * @param ipSrc floating ip + * @param actionVni external network VNI + * @param type the operation type of the flow rules + */ + void programRules(DeviceId deviceId, SegmentationId matchVni, + IpAddress srcIP, MacAddress ethDst, + MacAddress ethSrc, IpAddress ipSrc, + SegmentationId actionVni, Objective.Operation type); +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ClassifierServiceImpl.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ClassifierServiceImpl.java new file mode 100644 index 00000000..512a1559 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ClassifierServiceImpl.java @@ -0,0 +1,196 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.packet.EthType.EtherType; +import org.onlab.packet.Ethernet; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.criteria.Criteria; +import org.onosproject.net.flow.instructions.Instructions; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.ForwardingObjective.Flag; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtn.table.ClassifierService; +import org.onosproject.vtnrsc.SegmentationId; +import org.slf4j.Logger; + +import com.google.common.collect.Sets; + +/** + * Provides implementation of ClassifierService. + */ +public class ClassifierServiceImpl implements ClassifierService { + private final Logger log = getLogger(getClass()); + + private static final EtherType ETH_TYPE = EtherType.ARP; + private static final int ARP_CLASSIFIER_PRIORITY = 60000; + private static final int L3_CLASSIFIER_PRIORITY = 0xffff; + private static final int L2_CLASSIFIER_PRIORITY = 50000; + + private final FlowObjectiveService flowObjectiveService; + private final ApplicationId appId; + + /** + * Constructor. + * + * @param appId the application id of vtn + */ + public ClassifierServiceImpl(ApplicationId appId) { + this.appId = checkNotNull(appId, "ApplicationId can not be null"); + ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); + this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); + } + + @Override + public void programLocalIn(DeviceId deviceId, + SegmentationId segmentationId, PortNumber inPort, + MacAddress srcMac, ApplicationId appid, + Objective.Operation type) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchInPort(inPort).matchEthSrc(srcMac).build(); + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); + treatment.add(Instructions + .modTunnelId(Long.parseLong(segmentationId.toString()))); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment.build()) + .withSelector(selector).fromApp(appId).makePermanent() + .withFlag(Flag.SPECIFIC).withPriority(L2_CLASSIFIER_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + log.debug("programLocalIn-->ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("programLocalIn-->REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + } + + @Override + public void programTunnelIn(DeviceId deviceId, + SegmentationId segmentationId, + Iterable localTunnelPorts, + Objective.Operation type) { + if (localTunnelPorts == null) { + log.info("No tunnel port in device"); + return; + } + Sets.newHashSet(localTunnelPorts).stream().forEach(tp -> { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchInPort(tp).add(Criteria.matchTunnelId(Long + .parseLong(segmentationId.toString()))) + .build(); + + TrafficTreatment treatment = DefaultTrafficTreatment.builder() + .build(); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment).withSelector(selector) + .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC) + .withPriority(L2_CLASSIFIER_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + log.debug("programTunnelIn-->ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("programTunnelIn-->REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + }); + } + + @Override + public void programL3ExPortClassifierRules(DeviceId deviceId, PortNumber inPort, + IpAddress dstIp, + Objective.Operation type) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_IPV4).matchInPort(inPort) + .matchIPDst(IpPrefix.valueOf(dstIp, 32)).build(); + TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment).withSelector(selector) + .fromApp(appId).withFlag(Flag.SPECIFIC) + .withPriority(L3_CLASSIFIER_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + log.debug("L3ExToInClassifierRules-->ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("L3ExToInClassifierRules-->REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + } + + @Override + public void programL3InPortClassifierRules(DeviceId deviceId, PortNumber inPort, + MacAddress srcMac, MacAddress dstMac, + SegmentationId actionVni, + Objective.Operation type) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchInPort(inPort).matchEthSrc(srcMac).matchEthDst(dstMac) + .build(); + TrafficTreatment treatment = DefaultTrafficTreatment.builder() + .setTunnelId(Long.parseLong(actionVni.segmentationId())).build(); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment).withSelector(selector) + .fromApp(appId).withFlag(Flag.SPECIFIC) + .withPriority(L3_CLASSIFIER_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + log.debug("L3InternalClassifierRules-->ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("L3InternalClassifierRules-->REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + } + + @Override + public void programArpClassifierRules(DeviceId deviceId, IpAddress dstIp, + SegmentationId actionVni, + Objective.Operation type) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchEthType(ETH_TYPE.ethType().toShort()) + .matchArpTpa(Ip4Address.valueOf(dstIp.toString())) + .build(); + TrafficTreatment treatment = DefaultTrafficTreatment.builder() + .setTunnelId(Long.parseLong(actionVni.segmentationId())) + .build(); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment).withSelector(selector) + .fromApp(appId).withFlag(Flag.SPECIFIC) + .withPriority(ARP_CLASSIFIER_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + log.debug("ArpClassifierRules-->ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("ArpClassifierRules-->REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + } + +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/DnatServiceImpl.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/DnatServiceImpl.java new file mode 100644 index 00000000..7b8d42fa --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/DnatServiceImpl.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.packet.Ethernet; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.ForwardingObjective.Flag; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtn.table.DnatService; +import org.onosproject.vtnrsc.SegmentationId; +import org.slf4j.Logger; + +/** + * Provides implementation of DnatService. + */ +public class DnatServiceImpl implements DnatService { + private final Logger log = getLogger(getClass()); + + private static final int DNAT_PRIORITY = 0xffff; + private static final int PREFIX_LENGTH = 32; + + private final FlowObjectiveService flowObjectiveService; + private final ApplicationId appId; + + /** + * Construct a DnatServiceImpl object. + * + * @param appId the application id of vtn + */ + public DnatServiceImpl(ApplicationId appId) { + this.appId = checkNotNull(appId, "ApplicationId can not be null"); + ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); + this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); + } + + @Override + public void programRules(DeviceId deviceId, IpAddress dstIp, + MacAddress ethSrc, IpAddress ipDst, + SegmentationId actionVni, Objective.Operation type) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_IPV4) + .matchIPDst(IpPrefix.valueOf(dstIp, PREFIX_LENGTH)).build(); + + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); + treatment.setEthSrc(ethSrc).setIpDst(ipDst) + .setTunnelId(Long.parseLong(actionVni.segmentationId())); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment.build()) + .withSelector(selector).fromApp(appId).withFlag(Flag.SPECIFIC) + .withPriority(DNAT_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + log.debug("RouteRules-->ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("RouteRules-->REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L2ForwardServiceImpl.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L2ForwardServiceImpl.java new file mode 100644 index 00000000..3581cf6e --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L2ForwardServiceImpl.java @@ -0,0 +1,211 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST; +import static org.slf4j.LoggerFactory.getLogger; + +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.DefaultGroupId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.behaviour.ExtensionTreatmentResolver; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.net.driver.DriverService; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.TrafficTreatment.Builder; +import org.onosproject.net.flow.criteria.Criteria; +import org.onosproject.net.flow.instructions.ExtensionTreatment; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.ForwardingObjective.Flag; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtn.table.L2ForwardService; +import org.onosproject.vtnrsc.SegmentationId; +import org.slf4j.Logger; + +import com.google.common.collect.Sets; + +/** + * Provides implementation of L2ForwardService. + */ +public final class L2ForwardServiceImpl implements L2ForwardService { + private final Logger log = getLogger(getClass()); + + private static final int MAC_PRIORITY = 0xffff; + public static final Integer GROUP_ID = 1; + private final FlowObjectiveService flowObjectiveService; + private final ApplicationId appId; + private final DriverService driverService; + /** + * Constructor. + * + * @param appId the application id of vtn + */ + public L2ForwardServiceImpl(ApplicationId appId) { + this.appId = checkNotNull(appId, "ApplicationId can not be null"); + ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); + this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); + this.driverService = serviceDirectory.get(DriverService.class); + } + + @Override + public void programLocalBcastRules(DeviceId deviceId, + SegmentationId segmentationId, + PortNumber inPort, + Iterable localVmPorts, + Iterable localTunnelPorts, + Objective.Operation type) { + if (localVmPorts == null || localTunnelPorts == null) { + log.info("No other host port and tunnel in the device"); + return; + } + Sets.newHashSet(localVmPorts).stream().forEach(lp -> { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchInPort(lp).matchEthDst(MacAddress.BROADCAST) + .add(Criteria.matchTunnelId(Long + .parseLong(segmentationId.toString()))) + .build(); + TrafficTreatment.Builder treatment = DefaultTrafficTreatment + .builder(); + boolean flag = false; + for (PortNumber outPort : localVmPorts) { + flag = true; + if (outPort != lp) { + treatment.setOutput(outPort); + } + } + if (type.equals(Objective.Operation.REMOVE) && inPort == lp) { + flag = false; + } + treatment.group(new DefaultGroupId(GROUP_ID)); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment.build()) + .withSelector(selector).fromApp(appId).makePermanent() + .withFlag(Flag.SPECIFIC).withPriority(MAC_PRIORITY); + if (flag) { + flowObjectiveService.forward(deviceId, objective.add()); + } else { + flowObjectiveService.forward(deviceId, objective.remove()); + } + }); + } + + @Override + public void programTunnelBcastRules(DeviceId deviceId, + SegmentationId segmentationId, + Iterable localVmPorts, + Iterable localTunnelPorts, + Objective.Operation type) { + if (localVmPorts == null || localTunnelPorts == null) { + log.info("No other host port or tunnel ports in the device"); + return; + } + Sets.newHashSet(localTunnelPorts).stream().forEach(tp -> { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchInPort(tp) + .add(Criteria.matchTunnelId(Long + .parseLong(segmentationId.toString()))) + .matchEthDst(MacAddress.BROADCAST).build(); + TrafficTreatment.Builder treatment = DefaultTrafficTreatment + .builder(); + + for (PortNumber outPort : localVmPorts) { + treatment.setOutput(outPort); + } + + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment.build()) + .withSelector(selector).fromApp(appId).makePermanent() + .withFlag(Flag.SPECIFIC).withPriority(MAC_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + if (Sets.newHashSet(localVmPorts).size() == 0) { + flowObjectiveService.forward(deviceId, objective.remove()); + } else { + flowObjectiveService.forward(deviceId, objective.add()); + } + } else { + flowObjectiveService.forward(deviceId, objective.remove()); + } + }); + } + + @Override + public void programLocalOut(DeviceId deviceId, + SegmentationId segmentationId, + PortNumber outPort, MacAddress sourceMac, + Objective.Operation type) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchTunnelId(Long.parseLong(segmentationId.toString())) + .matchEthDst(sourceMac).build(); + TrafficTreatment treatment = DefaultTrafficTreatment.builder() + .setOutput(outPort).build(); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment).withSelector(selector) + .fromApp(appId).withFlag(Flag.SPECIFIC) + .withPriority(MAC_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + flowObjectiveService.forward(deviceId, objective.add()); + } else { + flowObjectiveService.forward(deviceId, objective.remove()); + } + + } + + @Override + public void programTunnelOut(DeviceId deviceId, + SegmentationId segmentationId, + PortNumber tunnelOutPort, MacAddress dstMac, + Objective.Operation type, IpAddress ipAddress) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchEthDst(dstMac).add(Criteria.matchTunnelId(Long + .parseLong(segmentationId.toString()))) + .build(); + + DriverHandler handler = driverService.createHandler(deviceId); + ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class); + ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type()); + try { + treatment.setPropertyValue("tunnelDst", Ip4Address.valueOf(ipAddress.toString())); + } catch (Exception e) { + log.error("Failed to get extension instruction to set tunnel dst {}", deviceId); + } + + Builder builder = DefaultTrafficTreatment.builder(); + builder.extension(treatment, deviceId) + .setOutput(tunnelOutPort).build(); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(builder.build()).withSelector(selector) + .fromApp(appId).withFlag(Flag.SPECIFIC) + .withPriority(MAC_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + flowObjectiveService.forward(deviceId, objective.add()); + } else { + flowObjectiveService.forward(deviceId, objective.remove()); + } + + } +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L3ForwardServiceImpl.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L3ForwardServiceImpl.java new file mode 100644 index 00000000..cf97e76d --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/L3ForwardServiceImpl.java @@ -0,0 +1,95 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.packet.Ethernet; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.instructions.Instructions; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.ForwardingObjective.Flag; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.net.flowobjective.Objective.Operation; +import org.onosproject.vtn.table.L3ForwardService; +import org.onosproject.vtnrsc.SegmentationId; +import org.slf4j.Logger; + +/** + * Provides implementation of L3ForwardService. + */ +public class L3ForwardServiceImpl implements L3ForwardService { + private final Logger log = getLogger(getClass()); + + private static final int L3FWD_PRIORITY = 0xffff; + private static final short IP_TYPE = Ethernet.TYPE_IPV4; + private static final int PREFIX_LENGTH = 32; + + private final FlowObjectiveService flowObjectiveService; + private final ApplicationId appId; + + /** + * Construct a L3ForwardServiceImpl object. + * + * @param appId the application id of vtn + */ + public L3ForwardServiceImpl(ApplicationId appId) { + this.appId = checkNotNull(appId, "ApplicationId can not be null"); + ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); + this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); + } + + @Override + public void programRouteRules(DeviceId deviceId, SegmentationId l3Vni, + IpAddress dstVmIP, SegmentationId dstVni, + MacAddress dstVmGwMac, MacAddress dstVmMac, + Operation type) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchEthType(IP_TYPE) + .matchTunnelId(Long.parseLong(l3Vni.segmentationId())) + .matchIPDst(IpPrefix.valueOf(dstVmIP, PREFIX_LENGTH)).build(); + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); + treatment.setEthSrc(dstVmGwMac) + .setEthDst(dstVmMac) + .add(Instructions.modTunnelId(Long.parseLong(dstVni + .segmentationId()))); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment.build()) + .withSelector(selector).fromApp(appId).withFlag(Flag.SPECIFIC) + .withPriority(L3FWD_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + log.debug("RouteRules-->ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("RouteRules-->REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + } + +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/SnatServiceImpl.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/SnatServiceImpl.java new file mode 100644 index 00000000..0f090954 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/SnatServiceImpl.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.packet.Ethernet; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.ForwardingObjective.Flag; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.vtn.table.SnatService; +import org.onosproject.vtnrsc.SegmentationId; +import org.slf4j.Logger; + +/** + * Provides implementation of SnatService. + */ +public class SnatServiceImpl implements SnatService { + private final Logger log = getLogger(getClass()); + + private static final int SNAT_PRIORITY = 0xffff; + private static final int PREFIC_LENGTH = 32; + + private final FlowObjectiveService flowObjectiveService; + private final ApplicationId appId; + + /** + * Construct a SnatServiceImpl object. + * + * @param appId the application id of vtn + */ + public SnatServiceImpl(ApplicationId appId) { + this.appId = checkNotNull(appId, "ApplicationId can not be null"); + ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); + this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); + } + + @Override + public void programRules(DeviceId deviceId, SegmentationId matchVni, + IpAddress srcIP, MacAddress ethDst, + MacAddress ethSrc, IpAddress ipSrc, + SegmentationId actionVni, Objective.Operation type) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_IPV4) + .matchTunnelId(Long.parseLong(matchVni.segmentationId())) + .matchIPSrc(IpPrefix.valueOf(srcIP, PREFIC_LENGTH)).build(); + + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); + treatment.setEthDst(ethDst).setEthSrc(ethSrc).setIpSrc(ipSrc) + .setTunnelId(Long.parseLong(actionVni.segmentationId())); + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment.build()) + .withSelector(selector).fromApp(appId).withFlag(Flag.SPECIFIC) + .withPriority(SNAT_PRIORITY); + if (type.equals(Objective.Operation.ADD)) { + log.debug("RouteRules-->ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("RouteRules-->REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/package-info.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/package-info.java new file mode 100644 index 00000000..fd2e18e5 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * VTN application that applies configuration and flows to the device. + */ +package org.onosproject.vtn.table.impl; diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/package-info.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/package-info.java new file mode 100644 index 00000000..cf53c966 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * VTN application that applies configuration and flows to the device. + */ +package org.onosproject.vtn.table; diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/DataPathIdGenerator.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/DataPathIdGenerator.java new file mode 100644 index 00000000..c2413475 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/DataPathIdGenerator.java @@ -0,0 +1,64 @@ +package org.onosproject.vtn.util; + +import static org.onlab.util.Tools.toHex; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Calendar; + +import org.onosproject.core.IdGenerator; +import org.onosproject.net.DeviceId; + +public final class DataPathIdGenerator implements IdGenerator { + private static final String SCHEME = "of"; + private String ipAddress; + private String timeStamp; + + private DataPathIdGenerator(Builder builder) { + this.ipAddress = builder.ipAddress; + Calendar cal = Calendar.getInstance(); + this.timeStamp = String.valueOf(cal.get(Calendar.SECOND)) + + String.valueOf(cal.get(Calendar.MILLISECOND)); + } + + @Override + public long getNewId() { + String dpid = ipAddress.replace(".", "") + timeStamp; + return Long.parseLong(dpid); + } + + public String getDpId() { + return toHex(getNewId()); + } + + public DeviceId getDeviceId() { + try { + URI uri = new URI(SCHEME, toHex(getNewId()), null); + return DeviceId.deviceId(uri); + } catch (URISyntaxException e) { + return null; + } + } + + /** + * Returns a new builder. + * + * @return new builder + */ + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + private String ipAddress; + + public Builder addIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + return this; + } + + public DataPathIdGenerator build() { + return new DataPathIdGenerator(this); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnConfig.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnConfig.java new file mode 100644 index 00000000..5ac04661 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnConfig.java @@ -0,0 +1,123 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.onlab.packet.IpAddress; +import org.onosproject.net.DefaultAnnotations; +import org.onosproject.net.PortNumber; +import org.onosproject.net.behaviour.BridgeConfig; +import org.onosproject.net.behaviour.BridgeName; +import org.onosproject.net.behaviour.DefaultTunnelDescription; +import org.onosproject.net.behaviour.IpTunnelEndPoint; +import org.onosproject.net.behaviour.TunnelConfig; +import org.onosproject.net.behaviour.TunnelDescription; +import org.onosproject.net.behaviour.TunnelEndPoint; +import org.onosproject.net.behaviour.TunnelName; +import org.onosproject.net.driver.DriverHandler; + +/** + * Applies configuration to the device. + */ +public final class VtnConfig { + + private static final String DEFAULT_BRIDGE_NAME = "br-int"; + private static final String DEFAULT_TUNNEL = "vxlan-0.0.0.0"; + private static final Map DEFAULT_TUNNEL_OPTIONS = new HashMap() { + { + put("key", "flow"); + put("remote_ip", "flow"); + } + }; + /** + * Constructs a vtn config object. Utility classes should not have a + * public or default constructor, otherwise IDE will compile unsuccessfully. This + * class should not be instantiated. + */ + private VtnConfig() { + } + + /** + * Creates or update bridge in the controller device. + * + * @param handler DriverHandler + * @param dpid datapath id + * @param exPortName external port name + */ + public static void applyBridgeConfig(DriverHandler handler, String dpid, String exPortName) { + BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class); + bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), dpid, exPortName); + } + + /** + * Creates or update tunnel in the controller device. + * + * @param handler DriverHandler + * @param srcIp the ipAddress of the local controller device + * @param dstIp the ipAddress of the remote controller device + */ + public static void applyTunnelConfig(DriverHandler handler, IpAddress srcIp, + IpAddress dstIp) { + DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder(); + for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) { + optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key)); + } + TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class); + TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(srcIp); + TunnelDescription tunnel = new DefaultTunnelDescription( + tunnelAsSrc, + null, + TunnelDescription.Type.VXLAN, + TunnelName.tunnelName(DEFAULT_TUNNEL), + optionBuilder.build()); + tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), tunnel); + } + + /** + * Creates or update tunnel in the controller device. + * + * @param handler DriverHandler + * @param srcIp the ipAddress of the local controller device + * @param dstIp the ipAddress of the remote controller device + */ + public static void removeTunnelConfig(DriverHandler handler, IpAddress srcIp, + IpAddress dstIp) { + TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class); + TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(srcIp); + TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dstIp); + TunnelDescription tunnel = new DefaultTunnelDescription( + tunnelAsSrc, + tunnelAsDst, + TunnelDescription.Type.VXLAN, + null); + tunnelConfig.removeTunnel(tunnel); + } + + /** + * Gets ports in the controller device. + * + * @param handler DriverHandler + * @return set of port numbers + */ + public static Set getPortNumbers(DriverHandler handler) { + BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class); + return bridgeConfig.getPortNumbers(); + } + +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java new file mode 100644 index 00000000..a8562e7f --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.util; + +import java.util.ArrayList; +import java.util.Collection; + +import org.onosproject.net.AnnotationKeys; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Sets; + +/** + * VtnData utility class. + */ +public final class VtnData { + + private static final Logger log = LoggerFactory.getLogger(VtnData.class); + private static final String SWITCH_CHANNEL_ID = "channelId"; + private static final String PORT_HEAD = "vxlan"; + + /** + * Constructs a VtnData object. Utility classes should not have a public or + * default constructor, otherwise IDE will compile unsuccessfully. This + * class should not be instantiated. + */ + private VtnData() { + } + + /** + * Get the ControllerIp from the device . + * + * @param device Device + * @return Controller Ip + */ + public static String getControllerIpOfSwitch(Device device) { + String url = device.annotations().value(SWITCH_CHANNEL_ID); + return url.substring(0, url.lastIndexOf(":")); + } + + /** + * Get the ControllerId from the device . + * + * @param device Device + * @param devices Devices + * @return Controller Id + */ + public static DeviceId getControllerId(Device device, + Iterable devices) { + for (Device d : devices) { + if (d.type() == Device.Type.CONTROLLER && d.id().toString() + .contains(getControllerIpOfSwitch(device))) { + return d.id(); + } + } + log.info("Can not find controller for device : {}", device.id()); + return null; + } + + /** + * Get local tunnel ports. + * + * @param ports Iterable of Port + * @return Collection of PortNumber + */ + public static Collection getLocalTunnelPorts(Iterable ports) { + Collection localTunnelPorts = new ArrayList<>(); + Sets.newHashSet(ports).stream() + .filter(p -> !p.number().equals(PortNumber.LOCAL)) + .forEach(p -> { + if (p.annotations().value(AnnotationKeys.PORT_NAME) + .startsWith(PORT_HEAD)) { + localTunnelPorts.add(p.number()); + } + }); + return localTunnelPorts; + } + +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/package-info.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/package-info.java new file mode 100644 index 00000000..213b9e28 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * VTN application that applies configuration and flows to the device. + */ +package org.onosproject.vtn.util; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFloatingIp.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFloatingIp.java new file mode 100644 index 00000000..7a297d90 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFloatingIp.java @@ -0,0 +1,140 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; + +import org.onlab.packet.IpAddress; + +/** + * Default implementation of FloatingIp interface. + */ +public final class DefaultFloatingIp implements FloatingIp { + + private final FloatingIpId id; + private final TenantId tenantId; + private final TenantNetworkId networkId; + private final VirtualPortId portId; + private final RouterId routerId; + private final IpAddress floatingIp; + private final IpAddress fixedIp; + private final Status status; + + /** + * + * Creates a floating Ip object. + * + * @param id floatingIp identifier + * @param tenantId tenant identifier + * @param networkId the identifier of network associated with the floating Ip + * @param portId port identifier + * @param routerId router identifier + * @param floatingIp floatingIp address + * @param fixedIp the fixed Ip associated with the floating Ip + * @param status the floating Ip status + */ + public DefaultFloatingIp(FloatingIpId id, TenantId tenantId, + TenantNetworkId networkId, VirtualPortId portId, + RouterId routerId, IpAddress floatingIp, + IpAddress fixedIp, Status status) { + this.id = checkNotNull(id, "id cannot be null"); + this.tenantId = checkNotNull(tenantId, "tenantId cannot be null"); + this.networkId = checkNotNull(networkId, "networkId cannot be null"); + this.portId = portId; + this.routerId = routerId; + this.floatingIp = checkNotNull(floatingIp, "floatingIp cannot be null"); + this.fixedIp = fixedIp; + this.status = checkNotNull(status, "status cannot be null"); + } + + @Override + public FloatingIpId id() { + return id; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public TenantNetworkId networkId() { + return networkId; + } + + @Override + public VirtualPortId portId() { + return portId; + } + + @Override + public RouterId routerId() { + return routerId; + } + + @Override + public IpAddress floatingIp() { + return floatingIp; + } + + @Override + public IpAddress fixedIp() { + return fixedIp; + } + + @Override + public Status status() { + return status; + } + + @Override + public int hashCode() { + return Objects.hash(id, tenantId, networkId, portId, routerId, + floatingIp, fixedIp, status); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultFloatingIp) { + final DefaultFloatingIp that = (DefaultFloatingIp) obj; + return Objects.equals(this.id, that.id) + && Objects.equals(this.tenantId, that.tenantId) + && Objects.equals(this.networkId, that.networkId) + && Objects.equals(this.portId, that.portId) + && Objects.equals(this.routerId, that.routerId) + && Objects.equals(this.floatingIp, that.floatingIp) + && Objects.equals(this.fixedIp, that.fixedIp) + && Objects.equals(this.status, that.status); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("id", id).add("tenantId", tenantId) + .add("networkId", networkId).add("portId", portId) + .add("routerId", routerId).add("floatingIp", floatingIp) + .add("fixedIp", fixedIp).add("floatingIpStatus", status) + .toString(); + } + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultRouter.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultRouter.java new file mode 100644 index 00000000..a2404f56 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultRouter.java @@ -0,0 +1,146 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; +import java.util.Objects; + +/** + * Default implementation of router interface. + */ +public final class DefaultRouter implements Router { + private final RouterId id; + private final String name; + private final boolean adminStateUp; + private final Status status; + private final boolean distributed; + private final RouterGateway externalGatewayInfo; + private final VirtualPortId gatewayPortId; + private final TenantId tenantId; + private final List routes; + + /** + * Creates router object. + * + * @param id router identifier + * @param routerName the name of router + * @param adminStateUp the status of admin state + * @param status the status of router + * @param distributed the status of router distributed + * @param externalGatewayInfo the gateway info of router + * @param gatewayPortId the port identifier of router gateway + * @param tenantId the tenant identifier + * @param routes the routes configure + */ + public DefaultRouter(RouterId id, String routerName, boolean adminStateUp, + Status status, boolean distributed, + RouterGateway externalGatewayInfo, + VirtualPortId gatewayPortId, TenantId tenantId, + List routes) { + this.id = checkNotNull(id, "id cannot be null"); + this.name = routerName; + this.adminStateUp = checkNotNull(adminStateUp, "adminStateUp cannot be null"); + this.status = checkNotNull(status, "status cannot be null"); + this.distributed = checkNotNull(distributed, "distributed cannot be null"); + this.externalGatewayInfo = externalGatewayInfo; + this.gatewayPortId = gatewayPortId; + this.tenantId = checkNotNull(tenantId, "tenantId cannot be null"); + this.routes = routes; + } + + @Override + public RouterId id() { + return id; + } + + @Override + public String name() { + return name; + } + + @Override + public boolean adminStateUp() { + return adminStateUp; + } + + @Override + public Status status() { + return status; + } + + @Override + public boolean distributed() { + return distributed; + } + + @Override + public RouterGateway externalGatewayInfo() { + return externalGatewayInfo; + } + + @Override + public VirtualPortId gatewayPortid() { + return gatewayPortId; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public List routes() { + return routes; + } + + @Override + public int hashCode() { + return Objects.hash(id, name, adminStateUp, status, distributed, + externalGatewayInfo, gatewayPortId, routes); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultRouter) { + final DefaultRouter that = (DefaultRouter) obj; + return Objects.equals(this.id, that.id) + && Objects.equals(this.name, that.name) + && Objects.equals(this.adminStateUp, that.adminStateUp) + && Objects.equals(this.status, that.status) + && Objects.equals(this.distributed, that.distributed) + && Objects.equals(this.externalGatewayInfo, + that.externalGatewayInfo) + && Objects.equals(this.gatewayPortId, that.gatewayPortId) + && Objects.equals(this.routes, that.routes); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("id", id).add("routerName", name) + .add("adminStateUp", adminStateUp).add("status", status) + .add("distributed", distributed) + .add("externalGatewayInfo", externalGatewayInfo) + .add("gatewayPortid", gatewayPortId).add("routes", routes).toString(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FloatingIp.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FloatingIp.java new file mode 100644 index 00000000..0933d9ef --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FloatingIp.java @@ -0,0 +1,94 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.onlab.packet.IpAddress; + +/** + * Representation of a floatingIp. + */ +public interface FloatingIp { + + /** + * Coarse classification of the type of the FloatingIp. + */ + public enum Status { + /** + * Signifies that a floating Ip is currently active. + */ + ACTIVE, + /** + * Signifies that a floating Ip is currently inactive. + */ + INACTIVE + } + + /** + * Returns the floatingIp identifier. + * + * @return identifier + */ + FloatingIpId id(); + + /** + * Returns the tenant identifier. + * + * @return the tenant identifier + */ + TenantId tenantId(); + + /** + * Returns the network identifier. + * + * @return the network identifier + */ + TenantNetworkId networkId(); + + /** + * Returns the port identifier. + * + * @return the port identifier + */ + VirtualPortId portId(); + + /** + * Returns the router identifier. + * + * @return the router identifier + */ + RouterId routerId(); + + /** + * Returns the floating ip address. + * + * @return floatingIp + */ + IpAddress floatingIp(); + + /** + * Returns the fixed ip address. + * + * @return fixedIp + */ + IpAddress fixedIp(); + + /** + * Returns the status of floating ip. + * + * @return floatingIpStatus + */ + Status status(); +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FloatingIpId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FloatingIpId.java new file mode 100644 index 00000000..1b48c7d6 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FloatingIpId.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; +import java.util.UUID; + +/** + * Immutable representation of a floating IP identifier. + */ +public final class FloatingIpId { + private final UUID floatingIpId; + + // Public construction is prohibited + private FloatingIpId(UUID floatingIpId) { + this.floatingIpId = checkNotNull(floatingIpId, "floatingIpId cannot be null"); + } + + /** + * Creates a floating IP identifier. + * + * @param floatingIpId the UUID id of floating IP identifier + * @return object of floating IP identifier + */ + public static FloatingIpId of(UUID floatingIpId) { + return new FloatingIpId(floatingIpId); + } + + /** + * Creates a floating IP identifier. + * + * @param floatingIpId the floating IP identifier in string + * @return object of floating IP identifier + */ + public static FloatingIpId of(String floatingIpId) { + return new FloatingIpId(UUID.fromString(floatingIpId)); + } + + /** + * Returns the floating IP identifier. + * + * @return the floating IP identifier + */ + public UUID floatingIpId() { + return floatingIpId; + } + + @Override + public int hashCode() { + return floatingIpId.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof FloatingIpId) { + final FloatingIpId that = (FloatingIpId) obj; + return Objects.equals(this.floatingIpId, that.floatingIpId); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("floatingIpId", floatingIpId).toString(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterInterface.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterInterface.java new file mode 100644 index 00000000..5c37c30b --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterInterface.java @@ -0,0 +1,119 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; + +/** + * Representation of a Router interface. + */ +public final class RouterInterface { + private final SubnetId subnetId; + private final VirtualPortId portId; + private final RouterId routerId; + private final TenantId tenantId; + + // Public construction is prohibited + private RouterInterface(SubnetId subnetId, VirtualPortId portId, + RouterId routerId, TenantId tenantId) { + this.subnetId = checkNotNull(subnetId, "subnetId cannot be null"); + this.portId = checkNotNull(portId, "portId cannot be null"); + this.routerId = checkNotNull(routerId, "routerId cannot be null"); + this.tenantId = checkNotNull(tenantId, "tenantId cannot be null"); + } + + /** + * Creates router interface object. + * + * @param subnetId subnet identifier + * @param portId port identifier + * @param routerId router identifier + * @param tenantId tenant identifier + * @return RouterInterface + */ + public static RouterInterface routerInterface(SubnetId subnetId, + VirtualPortId portId, + RouterId routerId, + TenantId tenantId) { + return new RouterInterface(subnetId, portId, routerId, tenantId); + } + + /** + * Returns subnet identifier. + * + * @return subnetId the subnet identifier + */ + public SubnetId subnetId() { + return subnetId; + } + + /** + * Returns port identifier. + * + * @return portId the port identifier + */ + public VirtualPortId portId() { + return portId; + } + + /** + * Returns router identifier. + * + * @return routerId the router identifier + */ + public RouterId routerId() { + return routerId; + } + + /** + * Returns tenant identifier. + * + * @return tenantId the tenant identifier + */ + public TenantId tenantId() { + return tenantId; + } + + @Override + public int hashCode() { + return Objects.hash(subnetId, portId, routerId, tenantId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof RouterInterface) { + final RouterInterface that = (RouterInterface) obj; + return Objects.equals(this.subnetId, that.subnetId) + && Objects.equals(this.portId, that.portId) + && Objects.equals(this.routerId, that.routerId) + && Objects.equals(this.tenantId, that.tenantId); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("subnetId", subnetId) + .add("portId", portId).add("routerId", routerId) + .add("tenantId", tenantId).toString(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpCreateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpCreateCommand.java new file mode 100644 index 00000000..00758dd2 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpCreateCommand.java @@ -0,0 +1,95 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.floatingip; + +import java.util.Set; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onlab.packet.IpAddress; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.DefaultFloatingIp; +import org.onosproject.vtnrsc.FloatingIpId; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.FloatingIp.Status; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.floatingip.FloatingIpService; + +import com.google.common.collect.Sets; + +/** + * Supports for create a floating IP. + */ +@Command(scope = "onos", name = "floatingip-create", + description = "Supports for creating a floating IP") +public class FloatingIpCreateCommand extends AbstractShellCommand { + @Argument(index = 0, name = "id", description = "The floating IP identifier", + required = true, multiValued = false) + String id = null; + + @Argument(index = 1, name = "networkId", description = "The network identifier of floating IP", + required = true, multiValued = false) + String networkId = null; + + @Argument(index = 2, name = "tenantId", description = "The tenant identifier of floating IP", + required = true, multiValued = false) + String tenantId = null; + + @Argument(index = 3, name = "routerId", description = "The router identifier of floating IP", + required = true, multiValued = false) + String routerId = null; + + @Argument(index = 4, name = "fixedIp", description = "The fixed IP of floating IP", + required = true, multiValued = false) + String fixedIp = null; + + @Argument(index = 5, name = "floatingIp", description = "The floating IP of floating IP", + required = true, multiValued = false) + String floatingIp = null; + + @Option(name = "-p", aliases = "--portId", description = "The port identifier of floating IP", + required = false, multiValued = false) + String portId = null; + + @Option(name = "-s", aliases = "--status", description = "The status of floating IP", + required = false, multiValued = false) + String status = null; + + @Override + protected void execute() { + FloatingIpService service = get(FloatingIpService.class); + try { + FloatingIp floatingIpObj = new DefaultFloatingIp( + FloatingIpId.of(id), + TenantId.tenantId(tenantId), + TenantNetworkId.networkId(networkId), + VirtualPortId.portId(portId), + RouterId.valueOf(routerId), + floatingIp == null ? null : IpAddress.valueOf(floatingIp), + fixedIp == null ? null : IpAddress.valueOf(fixedIp), + status == null ? Status.ACTIVE + : Status.valueOf(status)); + Set floatingIpSet = Sets.newHashSet(floatingIpObj); + service.createFloatingIps(floatingIpSet); + } catch (Exception e) { + print(null, e.getMessage()); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpQueryCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpQueryCommand.java new file mode 100644 index 00000000..c441d535 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpQueryCommand.java @@ -0,0 +1,92 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.floatingip; + +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.FloatingIpId; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.floatingip.FloatingIpService; + +/** + * Supports for query a floating IP. + */ +@Command(scope = "onos", name = "floatingips", description = "Supports for querying a floating IP") +public class FloatingIpQueryCommand extends AbstractShellCommand { + @Option(name = "-I", aliases = "--id", description = "The floating IP identifier", + required = false, multiValued = false) + String id = null; + + @Option(name = "-i", aliases = "--fixedIp", description = "The fixed IP of floating IP", + required = false, multiValued = false) + String fixedIp = null; + + @Option(name = "-l", aliases = "--floatingIp", description = "The floating IP of floating IP", + required = false, multiValued = false) + String floatingIp = null; + + private static final String FMT = "floatingIpId=%s, networkId=%s, tenantId=%s, portId=%s," + + "routerId=%s, fixedIp=%s, floatingIp=%s, status=%s"; + + @Override + protected void execute() { + FloatingIpService service = get(FloatingIpService.class); + if (id != null) { + FloatingIp floatingIp = service.getFloatingIp(FloatingIpId + .of(id)); + printFloatingIp(floatingIp); + } else if (fixedIp != null || floatingIp != null) { + Iterable floatingIps = service.getFloatingIps(); + if (floatingIps == null) { + return; + } + if (fixedIp != null) { + for (FloatingIp floatingIp : floatingIps) { + if (floatingIp.fixedIp().toString().equals(fixedIp)) { + printFloatingIp(floatingIp); + return; + } + } + print(null, "The fixedIp is not existed"); + } + if (floatingIp != null) { + for (FloatingIp floatingIpObj : floatingIps) { + if (floatingIpObj.fixedIp().toString().equals(floatingIp)) { + printFloatingIp(floatingIpObj); + return; + } + } + print(null, "The floatingIp is not existed"); + } + } else { + Iterable floatingIps = service.getFloatingIps(); + if (floatingIps == null) { + return; + } + for (FloatingIp floatingIp : floatingIps) { + printFloatingIp(floatingIp); + } + } + } + + private void printFloatingIp(FloatingIp floatingIp) { + print(FMT, floatingIp.id(), floatingIp.networkId(), + floatingIp.tenantId(), floatingIp.portId(), + floatingIp.routerId(), floatingIp.fixedIp(), + floatingIp.floatingIp(), floatingIp.status()); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpRemoveCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpRemoveCommand.java new file mode 100644 index 00000000..a413503a --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpRemoveCommand.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.floatingip; + +import java.util.Set; + +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.FloatingIpId; +import org.onosproject.vtnrsc.floatingip.FloatingIpService; + +import com.google.common.collect.Sets; + +/** + * Supports for remove a floating IP. + */ +@Command(scope = "onos", name = "floatingip-remove", description = "Supports for removing a floating IP") +public class FloatingIpRemoveCommand extends AbstractShellCommand { + @Option(name = "-I", aliases = "--id", description = "The floating IP identifier", + required = false, multiValued = false) + String id = null; + + @Option(name = "-i", aliases = "--fixedIp", description = "The fixed IP of floating IP", + required = false, multiValued = false) + String fixedIp = null; + + @Option(name = "-l", aliases = "--floatingIp", description = "The floating IP of floating IP", + required = false, multiValued = false) + String floatingIp = null; + + @Override + protected void execute() { + FloatingIpService service = get(FloatingIpService.class); + if (id == null && fixedIp == null && floatingIp == null) { + print(null, "one of id, fixedIp, floatingIp should not be null"); + } + try { + Set floatingIpSet = Sets.newHashSet(); + if (id != null) { + floatingIpSet.add(FloatingIpId.of(id)); + service.removeFloatingIps(floatingIpSet); + } else { + Iterable floatingIps = service.getFloatingIps(); + if (floatingIps == null) { + return; + } + if (fixedIp != null) { + for (FloatingIp floatingIp : floatingIps) { + if (floatingIp.fixedIp().toString().equals(fixedIp)) { + floatingIpSet.add(floatingIp.id()); + service.removeFloatingIps(floatingIpSet); + return; + } + } + print(null, "The fixedIp is not existed"); + return; + } + if (floatingIp != null) { + for (FloatingIp floatingIpObj : floatingIps) { + if (floatingIpObj.fixedIp().toString() + .equals(floatingIp)) { + floatingIpSet.add(floatingIpObj.id()); + service.removeFloatingIps(floatingIpSet); + return; + } + } + print(null, "The floatingIp is not existed"); + return; + } + } + } catch (Exception e) { + print(null, e.getMessage()); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpUpdateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpUpdateCommand.java new file mode 100644 index 00000000..413b3bdb --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/FloatingIpUpdateCommand.java @@ -0,0 +1,103 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.floatingip; + +import java.util.Set; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onlab.packet.IpAddress; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.DefaultFloatingIp; +import org.onosproject.vtnrsc.FloatingIpId; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.FloatingIp.Status; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.floatingip.FloatingIpService; + +import com.google.common.collect.Sets; + +/** + * Supports for update a floating IP. + */ +@Command(scope = "onos", name = "floatingip-update", + description = "Supports for updating a floating IP") +public class FloatingIpUpdateCommand extends AbstractShellCommand { + @Argument(index = 0, name = "id", description = "The floating IP identifier", + required = true, multiValued = false) + String id = null; + + @Option(name = "-n", aliases = "--networkId", description = "The network identifier of floating IP", + required = false, multiValued = false) + String networkId = null; + + @Option(name = "-t", aliases = "--tenantId", description = "The tenant identifier of floating IP", + required = false, multiValued = false) + String tenantId = null; + + @Option(name = "-r", aliases = "--routerId", description = "The router identifier of floating IP", + required = false, multiValued = false) + String routerId = null; + + @Option(name = "-p", aliases = "--portId", description = "The port identifier of floating IP", + required = false, multiValued = false) + String portId = null; + + @Option(name = "-s", aliases = "--status", description = "The status of floating IP", + required = false, multiValued = false) + String status = null; + + @Option(name = "-i", aliases = "--fixedIp", description = "The fixed IP of floating IP", + required = false, multiValued = false) + String fixedIp = null; + + @Option(name = "-l", aliases = "--floatingIp", description = "The floating IP of floating IP", + required = false, multiValued = false) + String floatingIp = null; + + @Override + protected void execute() { + FloatingIpService service = get(FloatingIpService.class); + FloatingIpId floatingIpId = FloatingIpId.of(id); + FloatingIp floatingIpStore = get(FloatingIpService.class).getFloatingIp(floatingIpId); + try { + FloatingIp floatingIpObj = new DefaultFloatingIp( + floatingIpId, + tenantId == null ? floatingIpStore.tenantId() + : TenantId.tenantId(tenantId), + networkId == null ? floatingIpStore.networkId() + : TenantNetworkId.networkId(networkId), + portId == null ? floatingIpStore.portId() + : VirtualPortId.portId(portId), + routerId == null ? floatingIpStore.routerId() + : RouterId.valueOf(routerId), + floatingIp == null ? floatingIpStore.floatingIp() + : IpAddress.valueOf(floatingIp), + fixedIp == null ? floatingIpStore.fixedIp() + : IpAddress.valueOf(fixedIp), + status == null ? floatingIpStore.status() + : Status.valueOf(status)); + Set floatingIpSet = Sets.newHashSet(floatingIpObj); + service.updateFloatingIps(floatingIpSet); + } catch (Exception e) { + print(null, e.getMessage()); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/package-info.java new file mode 100644 index 00000000..ac560771 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/floatingip/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Command line interface for floatingIP. + */ +package org.onosproject.vtnrsc.cli.floatingip; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterCreateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterCreateCommand.java new file mode 100644 index 00000000..3a736deb --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterCreateCommand.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.router; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.DefaultRouter; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.Router.Status; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.router.RouterService; + +import com.google.common.collect.Sets; + +/** + * Supports for create a router. + */ +@Command(scope = "onos", name = "router-create", + description = "Supports for creating a router") +public class RouterCreateCommand extends AbstractShellCommand { + @Argument(index = 0, name = "id", description = "The router identifier", + required = true, multiValued = false) + String id = null; + + @Argument(index = 1, name = "routerName", description = "The name of router", + required = true, multiValued = false) + String routerName = null; + + @Argument(index = 2, name = "tenantId", description = "The tenant identifier of router", + required = true, multiValued = false) + String tenantId = null; + + @Option(name = "-g", aliases = "--gatewayPortId", description = "The gatewayPort identifier of router", + required = false, multiValued = false) + String gatewayPortId = null; + + @Option(name = "-e", aliases = "--externalGatewayInfo", description = "The external gateway info of router", + required = false, multiValued = false) + String externalGatewayInfo = null; + + @Option(name = "-s", aliases = "--status", description = "The status of router", + required = false, multiValued = false) + String status = null; + + @Option(name = "-a", aliases = "--adminStateUp", description = "The boolean adminStateUp of router", + required = false, multiValued = false) + boolean adminStateUp = true; + + @Option(name = "-d", aliases = "--distributed", description = "The boolean distributed of router", + required = false, multiValued = false) + boolean distributed = false; + + @Override + protected void execute() { + RouterService service = get(RouterService.class); + try { + List routes = new ArrayList(); + Router router = new DefaultRouter( + RouterId.valueOf(id), + routerName, + adminStateUp, + status == null ? Status.ACTIVE + : Status.valueOf(status), + distributed, + null, + VirtualPortId.portId(gatewayPortId), + TenantId.tenantId(tenantId), + routes); + Set routerSet = Sets.newHashSet(router); + service.createRouters(routerSet); + } catch (Exception e) { + print(null, e.getMessage()); + } + } + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterQueryCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterQueryCommand.java new file mode 100644 index 00000000..a8a4b585 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterQueryCommand.java @@ -0,0 +1,76 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.router; + +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.router.RouterService; + +/** + * Supports for query a list of router. + */ +@Command(scope = "onos", name = "routers", description = "Supports for creating a router") +public class RouterQueryCommand extends AbstractShellCommand { + @Option(name = "-i", aliases = "--id", description = "The router identifier", + required = false, multiValued = false) + String id = null; + + @Option(name = "-n", aliases = "--routerName", description = "The name of router", + required = false, multiValued = false) + String routerName = null; + + private static final String FMT = "routerId=%s, routerName=%s, tenantId=%s, gatewayPortId=%s," + + "externalGatewayInfo=%s, status=%s, adminStateUp=%s, distributed=%s, routers=%s"; + + @Override + protected void execute() { + RouterService service = get(RouterService.class); + if (id != null) { + Router router = service.getRouter(RouterId.valueOf(id)); + printFloatingIp(router); + } else if (routerName != null) { + Iterable routers = service.getRouters(); + if (routers == null) { + return; + } + for (Router router : routers) { + if (router.name().equals(routerName)) { + printFloatingIp(router); + return; + } + } + print(null, "The routerName is not existed"); + } else { + Iterable routers = service.getRouters(); + if (routers == null) { + return; + } + for (Router router : routers) { + printFloatingIp(router); + } + } + } + + private void printFloatingIp(Router router) { + print(FMT, router.id(), router.name(), router.tenantId(), + router.gatewayPortid(), router.externalGatewayInfo(), + router.status(), router.adminStateUp(), router.distributed(), + router.routes()); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterRemoveCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterRemoveCommand.java new file mode 100644 index 00000000..b48434a1 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterRemoveCommand.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.router; + +import java.util.Set; + +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.router.RouterService; + +import com.google.common.collect.Sets; + +/** + * Supports for remove a router. + */ +@Command(scope = "onos", name = "router-remove", description = "Supports for removing a router") +public class RouterRemoveCommand extends AbstractShellCommand { + @Option(name = "-i", aliases = "--id", description = "The router identifier", + required = false, multiValued = false) + String id = null; + + @Option(name = "-n", aliases = "--routerName", description = "The name of router", + required = false, multiValued = false) + String routerName = null; + + @Override + protected void execute() { + RouterService service = get(RouterService.class); + if (id == null && routerName == null) { + print(null, "one of id, routerName should not be null"); + } + try { + Set routerSet = Sets.newHashSet(); + if (id != null) { + routerSet.add(RouterId.valueOf(id)); + service.removeRouters(routerSet); + } else { + Iterable routers = service.getRouters(); + if (routers == null) { + return; + } + for (Router router : routers) { + if (router.name().equals(routerName)) { + routerSet.add(router.id()); + service.removeRouters(routerSet); + return; + } + } + } + } catch (Exception e) { + print(null, e.getMessage()); + } + } + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterUpdateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterUpdateCommand.java new file mode 100644 index 00000000..699874b3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/RouterUpdateCommand.java @@ -0,0 +1,99 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.router; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.DefaultRouter; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.Router.Status; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.router.RouterService; + +import com.google.common.collect.Sets; + +/** + * Supports for update a router. + */ +@Command(scope = "onos", name = "router-update", description = "Supports for updating a router") +public class RouterUpdateCommand extends AbstractShellCommand { + @Argument(index = 0, name = "id", description = "The router identifier", + required = true, multiValued = false) + String id = null; + + @Option(name = "-r", aliases = "--routerName", description = "The name of router", + required = false, multiValued = false) + String routerName = null; + + @Option(name = "-t", aliases = "--tenantId", description = "The tenant identifier of router", + required = false, multiValued = false) + String tenantId = null; + + @Option(name = "-g", aliases = "--gatewayPortId", description = "The gatewayPort identifier of router", + required = false, multiValued = false) + String gatewayPortId = null; + + @Option(name = "-e", aliases = "--externalGatewayInfo", description = "The externalGatewayInfo of router", + required = false, multiValued = false) + String externalGatewayInfo = null; + + @Option(name = "-s", aliases = "--status", description = "The status of router", + required = false, multiValued = false) + String status = null; + + @Option(name = "-a", aliases = "--adminStateUp", description = "The boolean adminStateUp of router", + required = false, multiValued = false) + boolean adminStateUp = true; + + @Option(name = "-d", aliases = "--distributed", description = "The boolean distributed of router", + required = false, multiValued = false) + boolean distributed = false; + + @Override + protected void execute() { + RouterService service = get(RouterService.class); + RouterId routerId = RouterId.valueOf(id); + Router router = get(RouterService.class).getRouter(routerId); + try { + List routes = new ArrayList(); + Router routerObj = new DefaultRouter( + RouterId.valueOf(id), + routerName == null ? router.name() : routerName, + adminStateUp, + status == null ? Status.ACTIVE + : Status.valueOf(status), + distributed, + null, + gatewayPortId == null ? router.gatewayPortid() + : VirtualPortId.portId(gatewayPortId), + tenantId == null ? router.tenantId() + : TenantId.tenantId(tenantId), + routes); + Set routerSet = Sets.newHashSet(routerObj); + service.createRouters(routerSet); + } catch (Exception e) { + print(null, e.getMessage()); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/package-info.java new file mode 100644 index 00000000..4f1768ac --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/router/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Command line interface for router. + */ +package org.onosproject.vtnrsc.cli.router; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceCreateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceCreateCommand.java new file mode 100644 index 00000000..a3a174c9 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceCreateCommand.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.routerinterface; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.RouterInterface; +import org.onosproject.vtnrsc.SubnetId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService; + +/** + * Supports for create a router interface. + */ +@Command(scope = "onos", name = "routerinterface-create", description = "Supports for creating a router interface") +public class RouterInterfaceCreateCommand extends AbstractShellCommand { + @Argument(index = 0, name = "routerId", description = "The router identifier of router interface", + required = true, multiValued = false) + String routerId = null; + + @Argument(index = 1, name = "tenantId", description = "The tenant identifier of router interface", + required = true, multiValued = false) + String tenantId = null; + + @Argument(index = 2, name = "portId", description = "The port identifier of router interface", + required = true, multiValued = false) + String portId = null; + + @Argument(index = 3, name = "subnetId", description = "The subnet identifier of router interface", + required = true, multiValued = false) + String subnetId = null; + + @Override + protected void execute() { + RouterInterfaceService service = get(RouterInterfaceService.class); + try { + RouterInterface routerInterface = RouterInterface.routerInterface( + SubnetId.subnetId(subnetId), + VirtualPortId.portId(portId), + RouterId.valueOf(routerId), + TenantId.tenantId(tenantId)); + service.addRouterInterface(routerInterface); + } catch (Exception e) { + print(null, e.getMessage()); + } + } + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceQueryCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceQueryCommand.java new file mode 100644 index 00000000..5de35aee --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceQueryCommand.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.routerinterface; + +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.RouterInterface; +import org.onosproject.vtnrsc.SubnetId; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService; + +/** + * Supports for query a router interface. + */ +@Command(scope = "onos", name = "routerinterfaces", description = "Supports for querying a router interface") +public class RouterInterfaceQueryCommand extends AbstractShellCommand { + @Option(name = "-s", aliases = "--subnetId", description = "The subnet identifier of router interface", + required = false, multiValued = false) + String subnetId = null; + + private static final String FMT = "subnetId=%s, tenantId=%s, portId=%s, routerId=%s"; + + @Override + protected void execute() { + RouterInterfaceService service = get(RouterInterfaceService.class); + if (subnetId != null) { + RouterInterface routerInterface = service + .getRouterInterface(SubnetId.subnetId(subnetId)); + printRouterInterface(routerInterface); + } else { + Iterable routerInterfaces = service + .getRouterInterfaces(); + for (RouterInterface routerInterface : routerInterfaces) { + printRouterInterface(routerInterface); + } + } + } + + private void printRouterInterface(RouterInterface routerInterface) { + print(FMT, routerInterface.subnetId(), routerInterface.tenantId(), + routerInterface.portId(), routerInterface.routerId()); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceRemoveCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceRemoveCommand.java new file mode 100644 index 00000000..4e838e26 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/RouterInterfaceRemoveCommand.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.cli.routerinterface; + +import org.apache.karaf.shell.commands.Command; +import org.apache.karaf.shell.commands.Option; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.vtnrsc.RouterInterface; +import org.onosproject.vtnrsc.SubnetId; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService; + +/** + * Supports for remove a router interface. + */ +@Command(scope = "onos", name = "routerinterface-remove", description = "Supports for removing a router interface") +public class RouterInterfaceRemoveCommand extends AbstractShellCommand { + @Option(name = "-s", aliases = "--subnetId", description = "The subnet identifier of router interface", + required = true, multiValued = false) + String subnetId = null; + + @Override + protected void execute() { + RouterInterfaceService service = get(RouterInterfaceService.class); + try { + RouterInterface routerInterface = service + .getRouterInterface(SubnetId.subnetId(subnetId)); + if (routerInterface == null) { + print(null, "subnet ID of interface doesn't exist"); + return; + } + service.removeRouterInterface(routerInterface); + } catch (Exception e) { + print(null, e.getMessage()); + } + + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/package-info.java new file mode 100644 index 00000000..7b82004e --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/routerinterface/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Command line interface for router interface. + */ +package org.onosproject.vtnrsc.cli.routerinterface; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java new file mode 100644 index 00000000..3bac158b --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java @@ -0,0 +1,77 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.event; + +import org.onosproject.event.AbstractEvent; + + +/** + * Describes network vtnrsc event. + */ +public class VtnRscEvent + extends AbstractEvent { + + /** + * Type of vtnrsc events. + */ + public enum Type { + /** + * Signifies that floating IP has create. + */ + FLOATINGIP_PUT, + /** + * Signifies that floating IP has delete. + */ + FLOATINGIP_DELETE, + /** + * Signifies that router has create. + */ + ROUTER_PUT, + /** + * Signifies that router has delete. + */ + ROUTER_DELETE, + /** + * Signifies that router interface has add. + */ + ROUTER_INTERFACE_PUT, + /** + * Signifies that router interface has remove. + */ + ROUTER_INTERFACE_DELETE + } + + /** + * Creates an event of a given type and for the specified vtn event feedback. + * + * @param type Vtnrsc event type + * @param vtnFeedback event VtnrscEventFeedback subject + */ + public VtnRscEvent(Type type, VtnRscEventFeedback vtnFeedback) { + super(type, vtnFeedback); + } + + /** + * Creates an event of a given type and for the specified vtn event feedback. + * + * @param type Vtnrsc event type + * @param vtnFeedback event VtnrscEventFeedback subject + * @param time occurrence time + */ + public VtnRscEvent(Type type, VtnRscEventFeedback vtnFeedback, long time) { + super(type, vtnFeedback, time); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java new file mode 100644 index 00000000..63dcaeee --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java @@ -0,0 +1,123 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.event; + +import java.util.Objects; + +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.RouterInterface; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Representation of a VtnRsc event feedback. + */ +public class VtnRscEventFeedback { + private final FloatingIp floaingtIp; + private final Router router; + private final RouterInterface routerInterface; + + /** + * Creates VtnRscEventFeedback object. + * + * @param floatingIp the floating Ip + */ + public VtnRscEventFeedback(FloatingIp floatingIp) { + this.floaingtIp = checkNotNull(floatingIp, "floaintIp cannot be null"); + this.router = null; + this.routerInterface = null; + } + + /** + * Creates VtnRscEventFeedback object. + * + * @param router the router + */ + public VtnRscEventFeedback(Router router) { + this.floaingtIp = null; + this.router = checkNotNull(router, "router cannot be null"); + this.routerInterface = null; + } + + /** + * Creates VtnRscEventFeedback object. + * + * @param routerInterface the router interface + */ + public VtnRscEventFeedback(RouterInterface routerInterface) { + this.floaingtIp = null; + this.router = null; + this.routerInterface = checkNotNull(routerInterface, + "routerInterface cannot be null"); + } + + /** + * Returns floating IP. + * + * @return floaingtIp the floating IP + */ + public FloatingIp floatingIp() { + return floaingtIp; + } + + /** + * Returns router. + * + * @return router the router + */ + public Router router() { + return router; + } + + /** + * Returns router interface. + * + * @return routerInterface the router interface + */ + public RouterInterface routerInterface() { + return routerInterface; + } + + @Override + public int hashCode() { + return Objects.hash(floaingtIp, router, routerInterface); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof VtnRscEventFeedback) { + final VtnRscEventFeedback that = (VtnRscEventFeedback) obj; + return Objects.equals(this.floaingtIp, that.floaingtIp) + && Objects.equals(this.router, that.router) + && Objects.equals(this.routerInterface, that.routerInterface); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("router", router) + .add("floaingtIp", floaingtIp) + .add("routerInterface", routerInterface) + .toString(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscListener.java new file mode 100644 index 00000000..fdd67552 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscListener.java @@ -0,0 +1,26 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.vtnrsc.event; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of VtnRsc related events. + */ +public interface VtnRscListener extends EventListener { + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/package-info.java new file mode 100644 index 00000000..c1575ad3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Event of VtnRsc for VtnRsc service. + */ +package org.onosproject.vtnrsc.event; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpEvent.java new file mode 100644 index 00000000..f76007f7 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpEvent.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.floatingip; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.vtnrsc.FloatingIp; + +/** + * Describes network Floating IP event. + */ +public class FloatingIpEvent + extends AbstractEvent { + /** + * Type of Floating IP events. + */ + public enum Type { + /** + * Signifies that Floating IP has been created. + */ + FLOATINGIP_PUT, + /** + * Signifies that Floating IP has been deleted. + */ + FLOATINGIP_DELETE + } + + /** + * Creates an event of a given type and for the specified Floating IP. + * + * @param type Floating IP event type + * @param floagingIp Floating IP subject + */ + public FloatingIpEvent(Type type, FloatingIp floagingIp) { + super(type, floagingIp); + } + + /** + * Creates an event of a given type and for the specified Floating IP. + * + * @param type Floating IP event type + * @param floagingIp Floating IP subject + * @param time occurrence time + */ + public FloatingIpEvent(Type type, FloatingIp floagingIp, long time) { + super(type, floagingIp, time); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpListener.java new file mode 100644 index 00000000..a42af136 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpListener.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.floatingip; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of Floating IP related events. + */ +public interface FloatingIpListener extends EventListener { + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpService.java new file mode 100644 index 00000000..3f6f2515 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/FloatingIpService.java @@ -0,0 +1,108 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.floatingip; + +import java.util.Collection; + +import org.onlab.packet.IpAddress; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.FloatingIpId; +import org.onosproject.vtnrsc.TenantId; + +/** + * Service for interacting with the inventory of floating IP. + */ +public interface FloatingIpService { + /** + * Returns exists or not of specific floatingIp identifier. + * + * @param floatingIpId floatingIp identifier + * @return true or false + */ + boolean exists(FloatingIpId floatingIpId); + + /** + * Returns is used or not of specific floating IP address. + * + * @param floatingIpAddr floatingIp address + * @param floatingIpId floatingIp identifier + * @return true or false + */ + boolean floatingIpIsUsed(IpAddress floatingIpAddr, FloatingIpId floatingIpId); + + /** + * Returns is used or not of specific fixed IP address. + * + * @param fixedIpAddr fixedIp address + * @param tenantId the tenant identifier of floating IP + * @param floatingIpId floatingIp identifier + * @return true or false + */ + boolean fixedIpIsUsed(IpAddress fixedIpAddr, TenantId tenantId, FloatingIpId floatingIpId); + + /** + * Returns a collection of the currently known floating IP. + * + * @return collection of floating IP + */ + Collection getFloatingIps(); + + /** + * Returns the floatingIp with the specified identifier. + * + * @param floatingIpId floatingIp identifier + * @return floatingIp or null if one with the given identifier is not known + */ + FloatingIp getFloatingIp(FloatingIpId floatingIpId); + + /** + * Creates new floatingIps. + * + * @param floatingIps the collection of floatingIp + * @return true if the identifier floatingIp has been created right + */ + boolean createFloatingIps(Collection floatingIps); + + /** + * Updates existing floatingIps. + * + * @param floatingIps the collection of floatingIp + * @return true if all floatingIp were updated successfully + */ + boolean updateFloatingIps(Collection floatingIps); + + /** + * Removes the specified floatingIp from the store. + * + * @param floatingIpIds the collection of floatingIp identifier + * @return true if remove identifier floatingIp successfully + */ + boolean removeFloatingIps(Collection floatingIpIds); + + /** + * Adds the specified listener to floating Ip manager. + * + * @param listener floating Ip listener + */ + void addListener(FloatingIpListener listener); + + /** + * Removes the specified listener to floating Ip manager. + * + * @param listener floating Ip listener + */ + void removeListener(FloatingIpListener listener); +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java new file mode 100644 index 00000000..9f944da1 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java @@ -0,0 +1,348 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.floatingip.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.IpAddress; +import org.onlab.util.KryoNamespace; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.EventuallyConsistentMap; +import org.onosproject.store.service.EventuallyConsistentMapEvent; +import org.onosproject.store.service.EventuallyConsistentMapListener; +import org.onosproject.store.service.StorageService; +import org.onosproject.store.service.WallClockTimestamp; +import org.onosproject.vtnrsc.DefaultFloatingIp; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.FloatingIpId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.floatingip.FloatingIpEvent; +import org.onosproject.vtnrsc.floatingip.FloatingIpListener; +import org.onosproject.vtnrsc.floatingip.FloatingIpService; +import org.onosproject.vtnrsc.router.RouterService; +import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; +import org.onosproject.vtnrsc.virtualport.VirtualPortService; +import org.slf4j.Logger; + +import com.google.common.collect.Sets; + +/** + * Provides implementation of the FloatingIp service. + */ +@Component(immediate = true) +@Service +public class FloatingIpManager implements FloatingIpService { + private static final String FLOATINGIP_ID_NOT_NULL = "Floatingip ID cannot be null"; + private static final String FLOATINGIP_NOT_NULL = "Floatingip cannot be null"; + private static final String FLOATINGIP = "vtn-floatingip-store"; + private static final String VTNRSC_APP = "org.onosproject.vtnrsc"; + private static final String LISTENER_NOT_NULL = "Listener cannot be null"; + private static final String EVENT_NOT_NULL = "event cannot be null"; + + private final Logger log = getLogger(getClass()); + private final Set listeners = Sets + .newCopyOnWriteArraySet(); + private EventuallyConsistentMapListener floatingIpListener = + new InnerFloatingIpStoreListener(); + protected EventuallyConsistentMap floatingIpStore; + protected ApplicationId appId; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected TenantNetworkService tenantNetworkService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VirtualPortService virtualPortService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RouterService routerService; + + @Activate + public void activate() { + appId = coreService.registerApplication(VTNRSC_APP); + KryoNamespace.Builder serializer = KryoNamespace + .newBuilder() + .register(KryoNamespaces.API) + .register(FloatingIp.class, FloatingIpId.class, + TenantNetworkId.class, TenantId.class, + FloatingIp.Status.class, RouterId.class, + VirtualPortId.class, DefaultFloatingIp.class); + floatingIpStore = storageService + .eventuallyConsistentMapBuilder() + .withName(FLOATINGIP).withSerializer(serializer) + .withTimestampProvider((k, v) -> new WallClockTimestamp()) + .build(); + floatingIpStore.addListener(floatingIpListener); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + floatingIpStore.removeListener(floatingIpListener); + floatingIpStore.destroy(); + listeners.clear(); + log.info("Stopped"); + } + + @Override + public Collection getFloatingIps() { + return Collections.unmodifiableCollection(floatingIpStore.values()); + } + + @Override + public FloatingIp getFloatingIp(FloatingIpId floatingIpId) { + checkNotNull(floatingIpId, FLOATINGIP_ID_NOT_NULL); + return floatingIpStore.get(floatingIpId); + } + + @Override + public boolean exists(FloatingIpId floatingIpId) { + checkNotNull(floatingIpId, FLOATINGIP_ID_NOT_NULL); + return floatingIpStore.containsKey(floatingIpId); + } + + @Override + public boolean floatingIpIsUsed(IpAddress floatingIpAddr, + FloatingIpId floatingIpId) { + checkNotNull(floatingIpAddr, "Floating IP address cannot be null"); + checkNotNull(floatingIpId, "Floating IP Id cannot be null"); + Collection floatingIps = getFloatingIps(); + for (FloatingIp floatingIp : floatingIps) { + if (floatingIp.floatingIp().equals(floatingIpAddr) + && !floatingIp.id().equals(floatingIpId)) { + return true; + } + } + return false; + } + + @Override + public boolean fixedIpIsUsed(IpAddress fixedIpAddr, TenantId tenantId, + FloatingIpId floatingIpId) { + checkNotNull(fixedIpAddr, "Fixed IP address cannot be null"); + checkNotNull(tenantId, "Tenant Id cannot be null"); + checkNotNull(floatingIpId, "Floating IP Id cannot be null"); + Collection floatingIps = getFloatingIps(); + for (FloatingIp floatingIp : floatingIps) { + IpAddress fixedIp = floatingIp.fixedIp(); + if (fixedIp != null) { + if (fixedIp.equals(fixedIpAddr) + && floatingIp.tenantId().equals(tenantId) + && !floatingIp.id().equals(floatingIpId)) { + return true; + } + } + } + return false; + } + + @Override + public boolean createFloatingIps(Collection floatingIps) { + checkNotNull(floatingIps, FLOATINGIP_NOT_NULL); + boolean result = true; + for (FloatingIp floatingIp : floatingIps) { + verifyFloatingIpData(floatingIp); + if (floatingIp.portId() != null) { + floatingIpStore.put(floatingIp.id(), floatingIp); + if (!floatingIpStore.containsKey(floatingIp.id())) { + log.debug("The floating Ip is created failed whose identifier is {}", + floatingIp.id().toString()); + result = false; + } + } else { + FloatingIp oldFloatingIp = floatingIpStore.get(floatingIp.id()); + if (oldFloatingIp != null) { + floatingIpStore.remove(floatingIp.id(), oldFloatingIp); + if (floatingIpStore.containsKey(floatingIp.id())) { + log.debug("The floating Ip is created failed whose identifier is {}", + floatingIp.id().toString()); + result = false; + } + } + } + } + return result; + } + + @Override + public boolean updateFloatingIps(Collection floatingIps) { + checkNotNull(floatingIps, FLOATINGIP_NOT_NULL); + boolean result = true; + if (floatingIps != null) { + for (FloatingIp floatingIp : floatingIps) { + verifyFloatingIpData(floatingIp); + if (floatingIp.portId() != null) { + floatingIpStore.put(floatingIp.id(), floatingIp); + if (!floatingIpStore.containsKey(floatingIp.id())) { + log.debug("The floating Ip is updated failed whose identifier is {}", + floatingIp.id().toString()); + result = false; + } + } else { + FloatingIp oldFloatingIp = floatingIpStore.get(floatingIp + .id()); + if (oldFloatingIp != null) { + floatingIpStore.remove(floatingIp.id(), oldFloatingIp); + if (floatingIpStore.containsKey(floatingIp.id())) { + log.debug("The floating Ip is updated failed whose identifier is {}", + floatingIp.id().toString()); + result = false; + } + } + } + } + } + return result; + } + + @Override + public boolean removeFloatingIps(Collection floatingIpIds) { + checkNotNull(floatingIpIds, FLOATINGIP_ID_NOT_NULL); + boolean result = true; + if (floatingIpIds != null) { + for (FloatingIpId floatingIpId : floatingIpIds) { + if (!floatingIpStore.containsKey(floatingIpId)) { + log.debug("The floatingIp is not exist whose identifier is {}", + floatingIpId.toString()); + throw new IllegalArgumentException( + "FloatingIP ID doesn't exist"); + } + FloatingIp floatingIp = floatingIpStore.get(floatingIpId); + floatingIpStore.remove(floatingIpId, floatingIp); + if (floatingIpStore.containsKey(floatingIpId)) { + log.debug("The floating Ip is deleted failed whose identifier is {}", + floatingIpId.toString()); + result = false; + } + } + } + return result; + } + + @Override + public void addListener(FloatingIpListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.add(listener); + } + + @Override + public void removeListener(FloatingIpListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.add(listener); + } + + /** + * Verifies validity of FloatingIp data. + * + * @param floatingIps floatingIp instance + */ + private void verifyFloatingIpData(FloatingIp floatingIps) { + checkNotNull(floatingIps, FLOATINGIP_NOT_NULL); + if (!tenantNetworkService.exists(floatingIps.networkId())) { + log.debug("The network identifier {} that the floating Ip {} create for is not exist", + floatingIps.networkId().toString(), floatingIps.id() + .toString()); + throw new IllegalArgumentException( + "Floating network ID doesn't exist"); + } + + VirtualPortId portId = floatingIps.portId(); + if (portId != null && !virtualPortService.exists(portId)) { + log.debug("The port identifier {} that the floating Ip {} create for is not exist", + floatingIps.portId().toString(), floatingIps.id() + .toString()); + throw new IllegalArgumentException("Port ID doesn't exist"); + } + + RouterId routerId = floatingIps.routerId(); + if (routerId != null && !routerService.exists(routerId)) { + log.debug("The router identifier {} that the floating Ip {} create for is not exist", + floatingIps.routerId().toString(), floatingIps.id() + .toString()); + throw new IllegalArgumentException("Router ID doesn't exist"); + } + + if (floatingIpIsUsed(floatingIps.floatingIp(), floatingIps.id())) { + log.debug("The floaing Ip {} that the floating Ip {} create for is used", + floatingIps.floatingIp().toString(), floatingIps.id() + .toString()); + throw new IllegalArgumentException( + "The floating IP address is used"); + } + + IpAddress fixedIp = floatingIps.fixedIp(); + if (fixedIp != null + && fixedIpIsUsed(fixedIp, floatingIps.tenantId(), + floatingIps.id())) { + log.debug("The fixed Ip {} that the floating Ip {} create for is used", + floatingIps.fixedIp().toString(), floatingIps.id() + .toString()); + throw new IllegalArgumentException("The fixed IP address is used"); + } + } + + private class InnerFloatingIpStoreListener + implements + EventuallyConsistentMapListener { + + @Override + public void event(EventuallyConsistentMapEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + FloatingIp floatingIp = event.value(); + if (EventuallyConsistentMapEvent.Type.PUT == event.type()) { + notifyListeners(new FloatingIpEvent( + FloatingIpEvent.Type.FLOATINGIP_PUT, + floatingIp)); + } + if (EventuallyConsistentMapEvent.Type.REMOVE == event.type()) { + notifyListeners(new FloatingIpEvent( + FloatingIpEvent.Type.FLOATINGIP_DELETE, + floatingIp)); + } + } + } + + /** + * Notifies specify event to all listeners. + * + * @param event Floating IP event + */ + private void notifyListeners(FloatingIpEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + listeners.forEach(listener -> listener.event(event)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/package-info.java new file mode 100644 index 00000000..c638eba0 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Provides implementation of the FloatingIp service. + */ +package org.onosproject.vtnrsc.floatingip.impl; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/package-info.java new file mode 100644 index 00000000..274cbdd0 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Service for interacting with the inventory of FloatingIp. + */ +package org.onosproject.vtnrsc.floatingip; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java index c160d221..c5911ff2 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java @@ -24,49 +24,59 @@ import org.onosproject.vtnrsc.FlowClassifierId; public interface FlowClassifierService { /** - * Store Flow Classifier. + * Check whether Flow Classifier is present based on given Flow Classifier + * Id. * - * @param flowClassifier Flow Classifier - * @return true if adding Flow Classifier into store is success otherwise return false. + * @param id flow classifier identifier + * @return true if flow classifier is present otherwise return false */ - boolean createFlowClassifier(FlowClassifier flowClassifier); + boolean exists(FlowClassifierId id); /** - * Return the existing collection of Flow Classifier. + * Returns the number of flow classifiers known to the system. * - * @return Flow Classifier collections. + * @return number of flow classifiers */ - Iterable getFlowClassifiers(); + int getFlowClassifierCount(); + + /** + * Store Flow Classifier. + * + * @param flowClassifier flow classifier + * @return true if adding flow classifier into store is success otherwise + * return false + */ + boolean createFlowClassifier(FlowClassifier flowClassifier); /** - * Check whether Flow Classifier is present based on given Flow Classifier Id. + * Return the existing collection of Flow Classifier. * - * @param id Flow Classifier. - * @return true if Flow Classifier is present otherwise return false. + * @return flow classifier collections */ - boolean hasFlowClassifier(FlowClassifierId id); + Iterable getFlowClassifiers(); /** * Retrieve the Flow Classifier based on given Flow Classifier id. * - * @param id Flow Classifier Id. - * @return Flow Classifier if present otherwise returns null. + * @param id flow classifier identifier + * @return flow classifier if present otherwise returns null */ FlowClassifier getFlowClassifier(FlowClassifierId id); /** * Update Flow Classifier based on given Flow Classifier Id. * - * @param flowClassifier Flow Classifier. - * @return true if update is success otherwise return false. + * @param flowClassifier flow classifier + * @return true if flow classifier update is success otherwise return false */ boolean updateFlowClassifier(FlowClassifier flowClassifier); /** * Remove Flow Classifier from store based on given Flow Classifier Id. * - * @param id Flow Classifier Id. - * @return true if Flow Classifier removal is success otherwise return false. + * @param id flow classifier identifier + * @return true if flow classifier removal is success otherwise return + * false */ boolean removeFlowClassifier(FlowClassifierId id); } diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java index ee5873d6..4a60cd34 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java @@ -54,7 +54,7 @@ public class FlowClassifierManager implements FlowClassifierService { protected StorageService storageService; @Activate - private void activate() { + protected void activate() { KryoNamespace.Builder serializer = KryoNamespace.newBuilder() .register(KryoNamespaces.API) .register(MultiValuedTimestamp.class) @@ -67,34 +67,25 @@ public class FlowClassifierManager implements FlowClassifierService { } @Deactivate - private void deactivate() { + protected void deactivate() { flowClassifierStore.destroy(); log.info("Flow Classifier service deactivated"); } @Override - public boolean createFlowClassifier(FlowClassifier flowClassifier) { - log.debug("createFlowClassifier"); - checkNotNull(flowClassifier, FLOW_CLASSIFIER_NOT_NULL); - FlowClassifierId id = flowClassifier.flowClassifierId(); - - flowClassifierStore.put(id, flowClassifier); - if (!flowClassifierStore.containsKey(id)) { - log.debug("Flow Classifier creation is failed whose identifier is {}.", id.toString()); - return false; - } - return true; + public boolean exists(FlowClassifierId id) { + checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); + return flowClassifierStore.containsKey(id); } @Override - public Iterable getFlowClassifiers() { - return ImmutableList.copyOf(flowClassifierStore.values()); + public int getFlowClassifierCount() { + return flowClassifierStore.size(); } @Override - public boolean hasFlowClassifier(FlowClassifierId id) { - checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); - return flowClassifierStore.containsKey(id); + public Iterable getFlowClassifiers() { + return ImmutableList.copyOf(flowClassifierStore.values()); } @Override @@ -104,10 +95,36 @@ public class FlowClassifierManager implements FlowClassifierService { } @Override - public boolean updateFlowClassifier(FlowClassifier flowClassifier) { + public boolean createFlowClassifier(FlowClassifier flowClassifier) { + log.debug("createFlowClassifier"); checkNotNull(flowClassifier, FLOW_CLASSIFIER_NOT_NULL); FlowClassifierId id = flowClassifier.flowClassifierId(); + flowClassifierStore.put(id, flowClassifier); + if (!flowClassifierStore.containsKey(id)) { + log.debug("Flow Classifier creation is failed whose identifier is {}.", id.toString()); + return false; + } + return true; + } + + @Override + public boolean updateFlowClassifier(FlowClassifier flowClassifier) { + checkNotNull(flowClassifier, FLOW_CLASSIFIER_NOT_NULL); + + if (!flowClassifierStore.containsKey(flowClassifier.flowClassifierId())) { + log.debug("The flowClassifier is not exist whose identifier was {} ", flowClassifier.flowClassifierId() + .toString()); + return false; + } + + flowClassifierStore.put(flowClassifier.flowClassifierId(), flowClassifier); + + if (!flowClassifier.equals(flowClassifierStore.get(flowClassifier.flowClassifierId()))) { + log.debug("Updation of flowClassifier is failed whose identifier was {} ", flowClassifier + .flowClassifierId().toString()); + return false; + } return true; } diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterEvent.java new file mode 100644 index 00000000..25bd7b31 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterEvent.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.router; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.vtnrsc.Router; + +/** + * Describes network Router event. + */ +public class RouterEvent extends AbstractEvent { + /** + * Type of Router events. + */ + public enum Type { + /** + * Signifies that router has been created. + */ + ROUTER_PUT, + /** + * Signifies that router has been deleted. + */ + ROUTER_DELETE + } + + /** + * Creates an event of a given type and for the specified Router. + * + * @param type Router event type + * @param router Router subject + */ + public RouterEvent(Type type, Router router) { + super(type, router); + } + + /** + * Creates an event of a given type and for the specified Router. + * + * @param type Router event type + * @param router Router subject + * @param time occurrence time + */ + public RouterEvent(Type type, Router router, long time) { + super(type, router, time); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterListener.java new file mode 100644 index 00000000..dc772981 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterListener.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.router; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of Router related events. + */ +public interface RouterListener extends EventListener { + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterService.java new file mode 100644 index 00000000..362fa02b --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/RouterService.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.router; + +import java.util.Collection; + +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.RouterId; + +/** + * Service for interacting with the inventory of Routers. + */ +public interface RouterService { + /** + * Returns exists or not of specific router identifier. + * + * @param routerId router identifier + * @return true or false + */ + boolean exists(RouterId routerId); + + /** + * Returns a collection of the currently known Routers. + * + * @return collection of Routers + */ + Collection getRouters(); + + /** + * Returns the Router with the specified identifier. + * + * @param routerId Router identifier + * @return Router or null if one with the given identifier is not known + */ + Router getRouter(RouterId routerId); + + /** + * Creates new Routers. + * + * @param routers the collection of Routers + * @return true if the identifier Router has been created right. + * false if the identifier Router is failed to store + */ + boolean createRouters(Collection routers); + + /** + * Updates existing Routers. + * + * @param routers the collection of Routers + * @return true if Routers were updated successfully. + * false if Routers were updated failed + */ + boolean updateRouters(Collection routers); + + /** + * Removes the specified Routers from the store. + * + * @param routerIds the collection of Routers identifier + * @return true if remove identifier Routers successfully. false if remove + * identifier Routers failed + */ + boolean removeRouters(Collection routerIds); + + /** + * Adds the specified listener to Router manager. + * + * @param listener Router listener + */ + void addListener(RouterListener listener); + + /** + * Removes the specified listener to Router manager. + * + * @param listener Router listener + */ + void removeListener(RouterListener listener); +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/impl/RouterManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/impl/RouterManager.java new file mode 100644 index 00000000..b796fd7b --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/impl/RouterManager.java @@ -0,0 +1,269 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.router.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.util.KryoNamespace; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.EventuallyConsistentMap; +import org.onosproject.store.service.EventuallyConsistentMapEvent; +import org.onosproject.store.service.EventuallyConsistentMapListener; +import org.onosproject.store.service.StorageService; +import org.onosproject.store.service.WallClockTimestamp; +import org.onosproject.vtnrsc.DefaultRouter; +import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.RouterGateway; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.SubnetId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.router.RouterEvent; +import org.onosproject.vtnrsc.router.RouterListener; +import org.onosproject.vtnrsc.router.RouterService; +import org.onosproject.vtnrsc.subnet.SubnetService; +import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; +import org.onosproject.vtnrsc.virtualport.VirtualPortService; +import org.slf4j.Logger; + +import com.google.common.collect.Sets; + +/** + * Provides implementation of the Router service. + */ +@Component(immediate = true) +@Service +public class RouterManager implements RouterService { + + private static final String ROUTER_ID_NULL = "Router ID cannot be null"; + private static final String ROUTER_NOT_NULL = "Router cannot be null"; + private static final String ROUTER = "vtn-router-store"; + private static final String VTNRSC_APP = "org.onosproject.vtnrsc"; + private static final String LISTENER_NOT_NULL = "Listener cannot be null"; + private static final String EVENT_NOT_NULL = "event cannot be null"; + + private final Logger log = getLogger(getClass()); + private final Set listeners = Sets.newCopyOnWriteArraySet(); + private EventuallyConsistentMapListener routerListener = new InnerRouterStoreListener(); + protected EventuallyConsistentMap routerStore; + protected ApplicationId appId; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected TenantNetworkService tenantNetworkService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VirtualPortService virtualPortService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected SubnetService subnetService; + + @Activate + public void activate() { + appId = coreService.registerApplication(VTNRSC_APP); + KryoNamespace.Builder serializer = KryoNamespace + .newBuilder() + .register(KryoNamespaces.API) + .register(Router.class, RouterId.class, DefaultRouter.class, + TenantNetworkId.class, TenantId.class, + VirtualPortId.class, DefaultRouter.class, + RouterGateway.class, Router.Status.class, + SubnetId.class); + routerStore = storageService + .eventuallyConsistentMapBuilder() + .withName(ROUTER).withSerializer(serializer) + .withTimestampProvider((k, v) -> new WallClockTimestamp()) + .build(); + routerStore.addListener(routerListener); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + routerStore.removeListener(routerListener); + routerStore.destroy(); + listeners.clear(); + log.info("Stopped"); + } + + @Override + public boolean exists(RouterId routerId) { + checkNotNull(routerId, ROUTER_ID_NULL); + return routerStore.containsKey(routerId); + } + + @Override + public Collection getRouters() { + return Collections.unmodifiableCollection(routerStore.values()); + } + + @Override + public Router getRouter(RouterId routerId) { + checkNotNull(routerId, ROUTER_ID_NULL); + return routerStore.get(routerId); + } + + @Override + public boolean createRouters(Collection routers) { + checkNotNull(routers, ROUTER_NOT_NULL); + for (Router router : routers) { + verifyRouterData(router); + routerStore.put(router.id(), router); + if (!routerStore.containsKey(router.id())) { + log.debug("The router is created failed whose identifier is {}", + router.id().toString()); + return false; + } + } + return true; + } + + @Override + public boolean updateRouters(Collection routers) { + checkNotNull(routers, ROUTER_NOT_NULL); + for (Router router : routers) { + if (!routerStore.containsKey(router.id())) { + log.debug("The routers is not exist whose identifier is {}", + router.id().toString()); + throw new IllegalArgumentException( + "routers ID doesn't exist"); + } + verifyRouterData(router); + routerStore.put(router.id(), router); + if (!router.equals(routerStore.get(router.id()))) { + log.debug("The router is updated failed whose identifier is {}", + router.id().toString()); + return false; + } + } + return true; + } + + @Override + public boolean removeRouters(Collection routerIds) { + checkNotNull(routerIds, ROUTER_ID_NULL); + for (RouterId routerId : routerIds) { + if (!routerStore.containsKey(routerId)) { + log.debug("The router is not exist whose identifier is {}", + routerId.toString()); + throw new IllegalArgumentException( + "router ID doesn't exist"); + } + Router router = routerStore.get(routerId); + routerStore.remove(routerId, router); + if (routerStore.containsKey(routerId)) { + log.debug("The router deleted is failed whose identifier is {}", + routerId.toString()); + return false; + } + } + return true; + } + + @Override + public void addListener(RouterListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.add(listener); + } + + @Override + public void removeListener(RouterListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.remove(listener); + } + + /** + * Verifies validity of Router data. + * + * @param routers router instance + */ + private void verifyRouterData(Router routers) { + checkNotNull(routers, ROUTER_NOT_NULL); + if (routers.gatewayPortid() != null + && !virtualPortService.exists(routers.gatewayPortid())) { + log.debug("The gateway port ID is not exist whose identifier is {}", + routers.gatewayPortid().toString()); + throw new IllegalArgumentException("gateway port ID doesn't exist"); + } + + if (routers.externalGatewayInfo() != null) { + RouterGateway routerGateway = routers.externalGatewayInfo(); + if (!tenantNetworkService.exists(routerGateway.networkId())) { + log.debug("The network ID of gateway info is not exist whose identifier is {}", + routers.id().toString()); + throw new IllegalArgumentException( + "network ID of gateway info doesn't exist"); + } + Iterable fixedIps = routerGateway.externalFixedIps(); + for (FixedIp fixedIp : fixedIps) { + if (!subnetService.exists(fixedIp.subnetId())) { + log.debug("The subnet ID of gateway info is not exist whose identifier is {}", + routers.id().toString()); + throw new IllegalArgumentException( + "subnet ID of gateway info doesn't exist"); + } + } + } + } + + private class InnerRouterStoreListener + implements EventuallyConsistentMapListener { + + @Override + public void event(EventuallyConsistentMapEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + Router router = event.value(); + if (EventuallyConsistentMapEvent.Type.PUT == event.type()) { + notifyListeners(new RouterEvent(RouterEvent.Type.ROUTER_PUT, + router)); + } + if (EventuallyConsistentMapEvent.Type.REMOVE == event.type()) { + notifyListeners(new RouterEvent(RouterEvent.Type.ROUTER_DELETE, + router)); + } + } + } + + /** + * Notifies specify event to all listeners. + * + * @param event Floating IP event + */ + private void notifyListeners(RouterEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + listeners.forEach(listener -> listener.event(event)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/impl/package-info.java new file mode 100644 index 00000000..1254f982 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Provides implementation of the Router service. + */ +package org.onosproject.vtnrsc.router.impl; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/package-info.java new file mode 100644 index 00000000..fb6834aa --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/router/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Service for interacting with the inventory of Router. + */ +package org.onosproject.vtnrsc.router; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceEvent.java new file mode 100644 index 00000000..7f5cfa13 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceEvent.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.routerinterface; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.vtnrsc.RouterInterface; + +/** + * Describes network Router Interface event. + */ +public class RouterInterfaceEvent + extends AbstractEvent { + + /** + * Type of Router Interface events. + */ + public enum Type { + /** + * Signifies that router interface has been added. + */ + ROUTER_INTERFACE_PUT, + /** + * Signifies that router interface has been removed. + */ + ROUTER_INTERFACE_DELETE + } + + /** + * Creates an event of a given type and for the specified Router Interface. + * + * @param type Router Interface event type + * @param routerInterface Router Interface subject + */ + public RouterInterfaceEvent(Type type, RouterInterface routerInterface) { + super(type, routerInterface); + } + + /** + * Creates an event of a given type and for the specified Router Interface. + * + * @param type Router Interface event type. + * @param routerInterface Router Interface subject + * @param time occurrence time + */ + public RouterInterfaceEvent(Type type, RouterInterface routerInterface, + long time) { + super(type, routerInterface, time); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceListener.java new file mode 100644 index 00000000..1d0dab6f --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceListener.java @@ -0,0 +1,27 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.vtnrsc.routerinterface; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of Router Interface related events. + */ +public interface RouterInterfaceListener + extends EventListener { + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceService.java new file mode 100644 index 00000000..8cf147a5 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/RouterInterfaceService.java @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.routerinterface; + +import java.util.Collection; + +import org.onosproject.vtnrsc.RouterInterface; +import org.onosproject.vtnrsc.SubnetId; + +/** + * Service for interacting with the inventory of Router interface. + */ +public interface RouterInterfaceService { + /** + * Returns exists or not of specific subnet identifier. + * + * @param subnetId subnet identifier + * @return true or false + */ + boolean exists(SubnetId subnetId); + + /** + * Returns a collection of the currently known Router interface. + * + * @return collection of RouterInterface + */ + Collection getRouterInterfaces(); + + /** + * Returns the Router interface with the specified subnet identifier. + * + * @param subnetId subnet identifier + * @return RouterInterface or null if one with the given identifier is not + * known + */ + RouterInterface getRouterInterface(SubnetId subnetId); + + /** + * Adds the specified RouterInterface. + * + * @param routerInterface the interface add to router + * @return true if add router interface successfully + */ + boolean addRouterInterface(RouterInterface routerInterface); + + /** + * Removes the specified RouterInterface. + * + * @param routerInterface the interface remove from router + * @return true if remove router interface successfully + */ + boolean removeRouterInterface(RouterInterface routerInterface); + + /** + * Adds the specified listener to Router Interface manager. + * + * @param listener Router Interface listener + */ + void addListener(RouterInterfaceListener listener); + + /** + * Removes the specified listener to RouterInterface manager. + * + * @param listener Router Interface listener + */ + void removeListener(RouterInterfaceListener listener); +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/impl/RouterInterfaceManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/impl/RouterInterfaceManager.java new file mode 100644 index 00000000..244a5c03 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/impl/RouterInterfaceManager.java @@ -0,0 +1,235 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.routerinterface.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.util.KryoNamespace; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.EventuallyConsistentMap; +import org.onosproject.store.service.EventuallyConsistentMapEvent; +import org.onosproject.store.service.EventuallyConsistentMapListener; +import org.onosproject.store.service.StorageService; +import org.onosproject.store.service.WallClockTimestamp; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.RouterInterface; +import org.onosproject.vtnrsc.SubnetId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.router.RouterService; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceEvent; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceListener; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService; +import org.onosproject.vtnrsc.subnet.SubnetService; +import org.onosproject.vtnrsc.virtualport.VirtualPortService; +import org.slf4j.Logger; + +import com.google.common.collect.Sets; + +/** + * Provides implementation of the Router interface service. + */ +@Component(immediate = true) +@Service +public class RouterInterfaceManager implements RouterInterfaceService { + private static final String SUBNET_ID_NULL = "Subnet ID cannot be null"; + private static final String ROUTER_INTERFACE_NULL = "Router Interface cannot be null"; + private static final String ROUTER_INTERFACE = "vtn-router-interface-store"; + private static final String VTNRSC_APP = "org.onosproject.vtnrsc"; + private static final String LISTENER_NOT_NULL = "Listener cannot be null"; + private static final String EVENT_NOT_NULL = "event cannot be null"; + + private final Logger log = getLogger(getClass()); + private final Set listeners = Sets + .newCopyOnWriteArraySet(); + private EventuallyConsistentMapListener routerInterfaceListener = + new InnerRouterInterfaceStoreListener(); + protected EventuallyConsistentMap routerInterfaceStore; + protected ApplicationId appId; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VirtualPortService virtualPortService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected SubnetService subnetService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RouterService routerService; + + @Activate + public void activate() { + appId = coreService.registerApplication(VTNRSC_APP); + KryoNamespace.Builder serializer = KryoNamespace + .newBuilder() + .register(KryoNamespaces.API) + .register(RouterId.class, TenantId.class, VirtualPortId.class, + RouterInterface.class, SubnetId.class); + routerInterfaceStore = storageService + .eventuallyConsistentMapBuilder() + .withName(ROUTER_INTERFACE).withSerializer(serializer) + .withTimestampProvider((k, v) -> new WallClockTimestamp()) + .build(); + routerInterfaceStore.addListener(routerInterfaceListener); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + routerInterfaceStore.removeListener(routerInterfaceListener); + routerInterfaceStore.destroy(); + listeners.clear(); + log.info("Stopped"); + } + + @Override + public boolean exists(SubnetId subnetId) { + checkNotNull(subnetId, SUBNET_ID_NULL); + return routerInterfaceStore.containsKey(subnetId); + } + + @Override + public Collection getRouterInterfaces() { + return Collections + .unmodifiableCollection(routerInterfaceStore.values()); + } + + @Override + public RouterInterface getRouterInterface(SubnetId subnetId) { + checkNotNull(subnetId, SUBNET_ID_NULL); + return routerInterfaceStore.get(subnetId); + } + + @Override + public boolean addRouterInterface(RouterInterface routerInterface) { + checkNotNull(routerInterface, ROUTER_INTERFACE_NULL); + verifyRouterInterfaceData(routerInterface); + routerInterfaceStore.put(routerInterface.subnetId(), routerInterface); + if (!routerInterfaceStore.containsKey(routerInterface.subnetId())) { + log.debug("The router interface is created failed whose identifier is {}", + routerInterface.subnetId().toString()); + return false; + } + return true; + } + + @Override + public boolean removeRouterInterface(RouterInterface routerInterface) { + checkNotNull(routerInterface, ROUTER_INTERFACE_NULL); + if (!routerInterfaceStore.containsKey(routerInterface.subnetId())) { + log.debug("The router interface is not exist whose identifier is {}", + routerInterface.subnetId().toString()); + throw new IllegalArgumentException("subnet ID doesn't exist"); + } + verifyRouterInterfaceData(routerInterface); + routerInterfaceStore + .remove(routerInterface.subnetId(), routerInterface); + if (routerInterfaceStore.containsKey(routerInterface.subnetId())) { + log.debug("The router interface deleted is failed whose identifier is {}", + routerInterface.subnetId().toString()); + return false; + } + return true; + } + + @Override + public void addListener(RouterInterfaceListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.add(listener); + } + + @Override + public void removeListener(RouterInterfaceListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.remove(listener); + } + + /** + * Verifies validity of Router interface data. + * + * @param routers router instance + */ + private void verifyRouterInterfaceData(RouterInterface routerInterface) { + checkNotNull(routerInterface, ROUTER_INTERFACE_NULL); + if (!subnetService.exists(routerInterface.subnetId())) { + log.debug("The subnet ID of interface is not exist whose identifier is {}", + routerInterface.subnetId().toString()); + throw new IllegalArgumentException( + "subnet ID of interface doesn't exist"); + } + if (!virtualPortService.exists(routerInterface.portId())) { + log.debug("The port ID of interface is not exist whose identifier is {}", + routerInterface.portId().toString()); + throw new IllegalArgumentException( + "port ID of interface doesn't exist"); + } + if (!routerService.exists(routerInterface.routerId())) { + log.debug("The router ID of interface is not exist whose identifier is {}", + routerInterface.routerId().toString()); + throw new IllegalArgumentException( + "router ID of interface doesn't exist"); + } + } + + private class InnerRouterInterfaceStoreListener + implements + EventuallyConsistentMapListener { + + @Override + public void event(EventuallyConsistentMapEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + RouterInterface routerInterface = event.value(); + if (EventuallyConsistentMapEvent.Type.PUT == event.type()) { + notifyListeners(new RouterInterfaceEvent( + RouterInterfaceEvent.Type.ROUTER_INTERFACE_PUT, + routerInterface)); + } + if (EventuallyConsistentMapEvent.Type.REMOVE == event.type()) { + notifyListeners(new RouterInterfaceEvent( + RouterInterfaceEvent.Type.ROUTER_INTERFACE_DELETE, + routerInterface)); + } + } + } + + /** + * Notifies specify event to all listeners. + * + * @param event Floating IP event + */ + private void notifyListeners(RouterInterfaceEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + listeners.forEach(listener -> listener.event(event)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/impl/package-info.java new file mode 100644 index 00000000..71db9dc5 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Provides implementation of the RouterInterface service. + */ +package org.onosproject.vtnrsc.routerinterface.impl; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/package-info.java new file mode 100644 index 00000000..3804089a --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/routerinterface/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Service for interacting with the inventory of RouterInterface. + */ +package org.onosproject.vtnrsc.routerinterface; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java new file mode 100644 index 00000000..21161ba5 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java @@ -0,0 +1,94 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.service; + +import java.util.Iterator; + +import org.onlab.packet.MacAddress; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.HostId; +import org.onosproject.vtnrsc.SegmentationId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.event.VtnRscListener; + +/** + * Service for interacting with the inventory of Vtn resource. + */ +public interface VtnRscService { + /** + * Adds the specified listener. + * + * @param listener VtnRsc listener + */ + void addListener(VtnRscListener listener); + + /** + * Removes the specified listener. + * + * @param listener VtnRsc listener + */ + void removeListener(VtnRscListener listener); + + /** + * Returns the SegmentationId of tenant. + * + * @param tenantId tenant identifier + * @return SegmentationId the SegmentationId of tenant + */ + SegmentationId getL3vni(TenantId tenantId); + + /** + * Returns Classifier Ovs list of the specific tenant. + * + * @param tenantId tenant identifier + * @return iterable collection of Device + */ + Iterator getClassifierOfTenant(TenantId tenantId); + + /** + * Returns Service function forwarders Ovs list of the specific tenant. + * + * @param tenantId tenant identifier + * @return iterable collection of Device + */ + Iterator getSFFOfTenant(TenantId tenantId); + + /** + * Returns gateway mac address of the specific host. + * + * @param hostId host identifier + * @return MacAddress of host + */ + MacAddress getGatewayMac(HostId hostId); + + /** + * Checks if a specific port is a service function. + * + * @param portId port identifier + * @return true or false + */ + boolean isServiceFunction(VirtualPortId portId); + + /** + * Returns device identifier mapping to the specific port. + * + * @param portId port identifier + * @return device identifier + */ + DeviceId getSFToSFFMaping(VirtualPortId portId); +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java new file mode 100644 index 00000000..ec9ca3ef --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java @@ -0,0 +1,472 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.service.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.util.KryoNamespace; +import org.onosproject.core.CoreService; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Host; +import org.onosproject.net.HostId; +import org.onosproject.net.host.HostEvent; +import org.onosproject.net.host.HostListener; +import org.onosproject.net.host.HostService; +import org.onosproject.net.device.DeviceService; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.EventuallyConsistentMap; +import org.onosproject.store.service.LogicalClockService; +import org.onosproject.store.service.StorageService; +import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.RouterInterface; +import org.onosproject.vtnrsc.SegmentationId; +import org.onosproject.vtnrsc.Subnet; +import org.onosproject.vtnrsc.SubnetId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.VirtualPort; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.event.VtnRscEvent; +import org.onosproject.vtnrsc.event.VtnRscEventFeedback; +import org.onosproject.vtnrsc.event.VtnRscListener; +import org.onosproject.vtnrsc.floatingip.FloatingIpEvent; +import org.onosproject.vtnrsc.floatingip.FloatingIpListener; +import org.onosproject.vtnrsc.floatingip.FloatingIpService; +import org.onosproject.vtnrsc.router.RouterEvent; +import org.onosproject.vtnrsc.router.RouterListener; +import org.onosproject.vtnrsc.router.RouterService; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceEvent; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceListener; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService; +import org.onosproject.vtnrsc.service.VtnRscService; +import org.onosproject.vtnrsc.subnet.SubnetService; +import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; +import org.onosproject.vtnrsc.virtualport.VirtualPortService; +import org.slf4j.Logger; + +import com.google.common.collect.Sets; + +/** + * Provides implementation of the VtnRsc service. + */ +@Component(immediate = true) +@Service +public class VtnRscManager implements VtnRscService { + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected LogicalClockService clockService; + + private final Logger log = getLogger(getClass()); + private final Set listeners = Sets.newCopyOnWriteArraySet(); + private HostListener hostListener = new InnerHostListener(); + private FloatingIpListener floatingIpListener = new InnerFloatingIpListener(); + private RouterListener routerListener = new InnerRouterListener(); + private RouterInterfaceListener routerInterfaceListener = new InnerRouterInterfaceListener(); + + private EventuallyConsistentMap l3vniMap; + private EventuallyConsistentMap> classifierOvsMap; + private EventuallyConsistentMap> sffOvsMap; + + private static final String IFACEID = "ifaceid"; + private static final String RUNNELOPTOPOIC = "tunnel-ops-ids"; + private static final String LISTENER_NOT_NULL = "listener cannot be null"; + private static final String EVENT_NOT_NULL = "event cannot be null"; + private static final String TENANTID_NOT_NULL = "tenantId cannot be null"; + private static final String DEVICEID_NOT_NULL = "deviceId cannot be null"; + private static final String OVSMAP_NOT_NULL = "ovsMap cannot be null"; + private static final String L3VNIMAP = "l3vniMap"; + private static final String CLASSIFIEROVSMAP = "classifierOvsMap"; + private static final String SFFOVSMAP = "sffOvsMap"; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RouterService routerService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FloatingIpService floatingIpService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RouterInterfaceService routerInterfaceService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VirtualPortService virtualPortService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected HostService hostService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected SubnetService subnetService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected TenantNetworkService tenantNetworkService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; + + @Activate + public void activate() { + hostService.addListener(hostListener); + floatingIpService.addListener(floatingIpListener); + routerService.addListener(routerListener); + routerInterfaceService.addListener(routerInterfaceListener); + + KryoNamespace.Builder serializer = KryoNamespace.newBuilder() + .register(KryoNamespaces.API) + .register(TenantId.class, DeviceId.class); + l3vniMap = storageService + .eventuallyConsistentMapBuilder() + .withName(L3VNIMAP).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + + classifierOvsMap = storageService + .>eventuallyConsistentMapBuilder() + .withName(CLASSIFIEROVSMAP).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + + sffOvsMap = storageService + .>eventuallyConsistentMapBuilder() + .withName(SFFOVSMAP).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + } + + @Deactivate + public void deactivate() { + hostService.removeListener(hostListener); + floatingIpService.removeListener(floatingIpListener); + routerService.removeListener(routerListener); + routerInterfaceService.removeListener(routerInterfaceListener); + l3vniMap.destroy(); + classifierOvsMap.destroy(); + sffOvsMap.destroy(); + listeners.clear(); + log.info("Stopped"); + } + + @Override + public void addListener(VtnRscListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.add(listener); + } + + @Override + public void removeListener(VtnRscListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.add(listener); + } + + @Override + public SegmentationId getL3vni(TenantId tenantId) { + checkNotNull(tenantId, "tenantId cannot be null"); + SegmentationId l3vni = l3vniMap.get(tenantId); + if (l3vni == null) { + long segmentationId = coreService.getIdGenerator(RUNNELOPTOPOIC) + .getNewId(); + l3vni = SegmentationId.segmentationId(String + .valueOf(segmentationId)); + l3vniMap.put(tenantId, l3vni); + } + return l3vni; + } + + private class InnerHostListener implements HostListener { + + @Override + public void event(HostEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + Host host = event.subject(); + String ifaceId = host.annotations().value(IFACEID); + VirtualPortId hPortId = VirtualPortId.portId(ifaceId); + TenantId tenantId = virtualPortService.getPort(hPortId).tenantId(); + DeviceId deviceId = host.location().deviceId(); + if (HostEvent.Type.HOST_ADDED == event.type()) { + if (isServiceFunction(hPortId)) { + addDeviceIdOfOvsMap(tenantId, deviceId, sffOvsMap); + } else { + addDeviceIdOfOvsMap(tenantId, deviceId, classifierOvsMap); + } + } else if (HostEvent.Type.HOST_REMOVED == event.type()) { + if (isLastSFHostOfTenant(host, deviceId, tenantId)) { + removeDeviceIdOfOvsMap(tenantId, deviceId, sffOvsMap); + } + if (isLastClassifierHostOfTenant(host, deviceId, tenantId)) { + removeDeviceIdOfOvsMap(tenantId, deviceId, classifierOvsMap); + } + } + } + } + + private class InnerFloatingIpListener implements FloatingIpListener { + + @Override + public void event(FloatingIpEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + FloatingIp floatingIp = event.subject(); + if (FloatingIpEvent.Type.FLOATINGIP_PUT == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.FLOATINGIP_PUT, + new VtnRscEventFeedback( + floatingIp))); + } + if (FloatingIpEvent.Type.FLOATINGIP_DELETE == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.FLOATINGIP_DELETE, + new VtnRscEventFeedback( + floatingIp))); + } + } + } + + private class InnerRouterListener implements RouterListener { + + @Override + public void event(RouterEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + Router router = event.subject(); + if (RouterEvent.Type.ROUTER_PUT == event.type()) { + notifyListeners(new VtnRscEvent(VtnRscEvent.Type.ROUTER_PUT, + new VtnRscEventFeedback(router))); + } + if (RouterEvent.Type.ROUTER_DELETE == event.type()) { + notifyListeners(new VtnRscEvent(VtnRscEvent.Type.ROUTER_DELETE, + new VtnRscEventFeedback(router))); + } + } + } + + private class InnerRouterInterfaceListener + implements RouterInterfaceListener { + + @Override + public void event(RouterInterfaceEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + RouterInterface routerInterface = event.subject(); + if (RouterInterfaceEvent.Type.ROUTER_INTERFACE_PUT == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.ROUTER_INTERFACE_PUT, + new VtnRscEventFeedback( + routerInterface))); + } + if (RouterInterfaceEvent.Type.ROUTER_INTERFACE_DELETE == event + .type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.ROUTER_INTERFACE_DELETE, + new VtnRscEventFeedback( + routerInterface))); + } + } + } + + @Override + public Iterator getClassifierOfTenant(TenantId tenantId) { + checkNotNull(tenantId, TENANTID_NOT_NULL); + Set deviceIdSet = classifierOvsMap.get(tenantId); + Set deviceSet = new HashSet<>(); + if (deviceIdSet != null) { + for (DeviceId deviceId : deviceIdSet) { + deviceSet.add(deviceService.getDevice(deviceId)); + } + } + return deviceSet.iterator(); + } + + @Override + public Iterator getSFFOfTenant(TenantId tenantId) { + checkNotNull(tenantId, TENANTID_NOT_NULL); + Set deviceIdSet = sffOvsMap.get(tenantId); + Set deviceSet = new HashSet<>(); + if (deviceIdSet != null) { + for (DeviceId deviceId : deviceIdSet) { + deviceSet.add(deviceService.getDevice(deviceId)); + } + } + return deviceSet.iterator(); + } + + @Override + public MacAddress getGatewayMac(HostId hostId) { + checkNotNull(hostId, "hostId cannot be null"); + Host host = hostService.getHost(hostId); + String ifaceId = host.annotations().value(IFACEID); + VirtualPortId hPortId = VirtualPortId.portId(ifaceId); + VirtualPort hPort = virtualPortService.getPort(hPortId); + SubnetId subnetId = hPort.fixedIps().iterator().next().subnetId(); + Subnet subnet = subnetService.getSubnet(subnetId); + IpAddress gatewayIp = subnet.gatewayIp(); + Iterable virtualPorts = virtualPortService.getPorts(); + MacAddress macAddress = null; + for (VirtualPort port : virtualPorts) { + Set fixedIpSet = port.fixedIps(); + for (FixedIp fixedIp : fixedIpSet) { + if (fixedIp.ip().equals(gatewayIp)) { + macAddress = port.macAddress(); + } + } + } + return macAddress; + } + + @Override + public boolean isServiceFunction(VirtualPortId portId) { + // TODO Auto-generated method stub + return false; + } + + @Override + public DeviceId getSFToSFFMaping(VirtualPortId portId) { + checkNotNull(portId, "portId cannot be null"); + VirtualPort vmPort = virtualPortService.getPort(portId); + Set hostSet = hostService.getHostsByMac(vmPort.macAddress()); + for (Host host : hostSet) { + if (host.annotations().value(IFACEID).equals(vmPort.portId())) { + return host.location().deviceId(); + } + } + return null; + } + + /** + * Checks whether the last Service Function host of a specific tenant in + * this device. + * + * @param host the host on device + * @param deviceId the device identifier + * @param tenantId the tenant identifier + * @return true or false + */ + private boolean isLastSFHostOfTenant(Host host, DeviceId deviceId, + TenantId tenantId) { + checkNotNull(host, "host cannot be null"); + checkNotNull(deviceId, DEVICEID_NOT_NULL); + checkNotNull(tenantId, TENANTID_NOT_NULL); + Set hostSet = hostService.getConnectedHosts(deviceId); + for (Host h : hostSet) { + String ifaceId = h.annotations().value(IFACEID); + VirtualPortId hPortId = VirtualPortId.portId(ifaceId); + if (virtualPortService.getPort(hPortId).tenantId() != tenantId) { + hostSet.remove(h); + } else { + if (!isServiceFunction(hPortId)) { + hostSet.remove(h); + } + } + } + if (hostSet.size() == 1 && hostSet.contains(host)) { + return true; + } + return false; + } + + /** + * Checks whether the last Classifier host of a specific tenant in this + * device. + * + * @param host the host on device + * @param deviceId the device identifier + * @param tenantId the tenant identifier + * @return true or false + */ + private boolean isLastClassifierHostOfTenant(Host host, DeviceId deviceId, + TenantId tenantId) { + checkNotNull(host, "host cannot be null"); + checkNotNull(deviceId, DEVICEID_NOT_NULL); + checkNotNull(tenantId, TENANTID_NOT_NULL); + Set hostSet = hostService.getConnectedHosts(deviceId); + for (Host h : hostSet) { + String ifaceId = h.annotations().value(IFACEID); + VirtualPortId hPortId = VirtualPortId.portId(ifaceId); + if (virtualPortService.getPort(hPortId).tenantId() != tenantId) { + hostSet.remove(h); + } else { + if (isServiceFunction(hPortId)) { + hostSet.remove(h); + } + } + } + if (hostSet.size() == 1 && hostSet.contains(host)) { + return true; + } + return false; + } + + /** + * Adds specify Device identifier to OvsMap. + * + * @param tenantId the tenant identifier + * @param deviceId the device identifier + * @param ovsMap the instance of map to store device identifier + */ + private void addDeviceIdOfOvsMap(TenantId tenantId, + DeviceId deviceId, + EventuallyConsistentMap> ovsMap) { + checkNotNull(tenantId, TENANTID_NOT_NULL); + checkNotNull(deviceId, DEVICEID_NOT_NULL); + checkNotNull(ovsMap, OVSMAP_NOT_NULL); + if (ovsMap.containsKey(tenantId)) { + Set deviceIdSet = ovsMap.get(tenantId); + deviceIdSet.add(deviceId); + ovsMap.put(tenantId, deviceIdSet); + } else { + Set deviceIdSet = new HashSet<>(); + deviceIdSet.add(deviceId); + ovsMap.put(tenantId, deviceIdSet); + } + } + + /** + * Removes specify Device identifier from OvsMap. + * + * @param tenantId the tenant identifier + * @param deviceId the device identifier + * @param ovsMap the instance of map to store device identifier + */ + private void removeDeviceIdOfOvsMap(TenantId tenantId, + DeviceId deviceId, + EventuallyConsistentMap> ovsMap) { + checkNotNull(tenantId, TENANTID_NOT_NULL); + checkNotNull(deviceId, DEVICEID_NOT_NULL); + checkNotNull(ovsMap, OVSMAP_NOT_NULL); + Set deviceIdSet = ovsMap.get(tenantId); + if (deviceIdSet.size() > 1) { + deviceIdSet.remove(deviceId); + ovsMap.put(tenantId, deviceIdSet); + } else { + ovsMap.remove(tenantId); + } + } + + /** + * Notifies specify event to all listeners. + * + * @param event VtnRsc event + */ + private void notifyListeners(VtnRscEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + listeners.forEach(listener -> listener.event(event)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/package-info.java new file mode 100644 index 00000000..aaea08b3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Provides implementation of the VtnRsc service. + */ +package org.onosproject.vtnrsc.service.impl; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/package-info.java new file mode 100644 index 00000000..37af604a --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Service for interacting with the inventory of Vtn resource. + */ +package org.onosproject.vtnrsc.service; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/subnet/impl/SubnetManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/subnet/impl/SubnetManager.java index 890beb29..94430389 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/subnet/impl/SubnetManager.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/subnet/impl/SubnetManager.java @@ -144,21 +144,19 @@ public class SubnetManager implements SubnetService { @Override public boolean updateSubnets(Iterable subnets) { checkNotNull(subnets, SUBNET_NOT_NULL); - if (subnets != null) { - for (Subnet subnet : subnets) { - if (!subnetStore.containsKey(subnet.id())) { - log.debug("The subnet is not exist whose identifier is {}", - subnet.id().toString()); - return false; - } - - subnetStore.put(subnet.id(), subnet); - - if (!subnet.equals(subnetStore.get(subnet.id()))) { - log.debug("The subnet is updated failed whose identifier is {}", - subnet.id().toString()); - return false; - } + for (Subnet subnet : subnets) { + if (!subnetStore.containsKey(subnet.id())) { + log.debug("The subnet is not exist whose identifier is {}", + subnet.id().toString()); + return false; + } + + subnetStore.put(subnet.id(), subnet); + + if (!subnet.equals(subnetStore.get(subnet.id()))) { + log.debug("The subnet is updated failed whose identifier is {}", + subnet.id().toString()); + return false; } } return true; @@ -167,14 +165,12 @@ public class SubnetManager implements SubnetService { @Override public boolean removeSubnets(Iterable subnetIds) { checkNotNull(subnetIds, SUBNET_ID_NULL); - if (subnetIds != null) { - for (SubnetId subnetId : subnetIds) { - subnetStore.remove(subnetId); - if (subnetStore.containsKey(subnetId)) { - log.debug("The subnet created is failed whose identifier is {}", - subnetId.toString()); - return false; - } + for (SubnetId subnetId : subnetIds) { + subnetStore.remove(subnetId); + if (subnetStore.containsKey(subnetId)) { + log.debug("The subnet created is failed whose identifier is {}", + subnetId.toString()); + return false; } } return true; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/apps/vtn/vtnrsc/src/main/resources/OSGI-INF/blueprint/shell-config.xml index c6a9c81b..f7a1bf44 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/resources/OSGI-INF/blueprint/shell-config.xml +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/resources/OSGI-INF/blueprint/shell-config.xml @@ -52,5 +52,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/AllowedAddressPairTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/AllowedAddressPairTest.java new file mode 100644 index 00000000..05152359 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/AllowedAddressPairTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.vtnrsc; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for AllowedAddressPair class. + */ +public class AllowedAddressPairTest { + + final IpAddress ip1 = IpAddress.valueOf("192.168.0.1"); + final IpAddress ip2 = IpAddress.valueOf("192.168.0.2"); + final MacAddress mac1 = MacAddress.valueOf("fa:16:3e:76:83:88"); + final MacAddress mac2 = MacAddress.valueOf("aa:16:3e:76:83:88"); + + /** + * Checks that the AllowedAddressPair class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(AllowedAddressPair.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + AllowedAddressPair p1 = AllowedAddressPair + .allowedAddressPair(ip1, mac1); + AllowedAddressPair p2 = AllowedAddressPair + .allowedAddressPair(ip1, mac1); + AllowedAddressPair p3 = AllowedAddressPair + .allowedAddressPair(ip2, mac2); + new EqualsTester().addEqualityGroup(p1, p2).addEqualityGroup(p3) + .testEquals(); + } + + /** + * Checks the construction of a AllowedAddressPair object. + */ + @Test + public void testConstruction() { + AllowedAddressPair allowedAddressPair = AllowedAddressPair + .allowedAddressPair(ip1, mac1); + assertThat(ip1, is(notNullValue())); + assertThat(ip1, is(allowedAddressPair.ip())); + assertThat(mac1, is(notNullValue())); + assertThat(mac1, is(allowedAddressPair.mac())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultAllocationPoolTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultAllocationPoolTest.java new file mode 100644 index 00000000..9e7d3c1c --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultAllocationPoolTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; +import org.onlab.packet.IpAddress; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for DefaultAllocationPool class. + */ +public class DefaultAllocationPoolTest { + + final IpAddress startIP1 = IpAddress.valueOf("192.168.1.1"); + final IpAddress startIP2 = IpAddress.valueOf("192.168.1.2"); + final IpAddress endIP1 = IpAddress.valueOf("192.168.1.1"); + final IpAddress endIP2 = IpAddress.valueOf("192.168.1.2"); + + /** + * Checks that the DefaultAllocationPool class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultAllocationPool.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + AllocationPool pool1 = new DefaultAllocationPool(startIP1, endIP1); + AllocationPool pool2 = new DefaultAllocationPool(startIP1, endIP1); + AllocationPool pool3 = new DefaultAllocationPool(startIP2, endIP2); + new EqualsTester().addEqualityGroup(pool1, pool2) + .addEqualityGroup(pool3).testEquals(); + } + + /** + * Checks the construction of a DefaultAllocationPool object. + */ + @Test + public void testConstruction() { + final AllocationPool apool = new DefaultAllocationPool(startIP1, endIP1); + assertThat(startIP1, is(apool.startIp())); + assertThat(endIP1, is(apool.endIp())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultFlowClassifierTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultFlowClassifierTest.java new file mode 100644 index 00000000..7032c216 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultFlowClassifierTest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; +import org.onlab.packet.IpPrefix; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for DefaultFlowClassifier class. + */ +public class DefaultFlowClassifierTest { + /** + * Checks that the DefaultFlowClassifier class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultFlowClassifier.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + // Create same two flow classifier objects. + final String name = "FlowClassifier1"; + final String description = "FlowClassifier1"; + final String ethType = "IPv4"; + final String protocol = "tcp"; + final int minSrcPortRange = 5; + final int maxSrcPortRange = 10; + final int minDstPortRange = 5; + final int maxDstPortRange = 10; + final FlowClassifierId flowClassifierId = FlowClassifierId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0"); + final IpPrefix dstIpPrefix = IpPrefix.valueOf("10.10.10.10/0"); + final VirtualPortId virtualSrcPort = VirtualPortId.portId("1"); + final VirtualPortId virtualDstPort = VirtualPortId.portId("2"); + + DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder(); + final FlowClassifier flowClassifier1 = flowClassifierBuilder.setFlowClassifierId(flowClassifierId) + .setTenantId(tenantId).setName(name).setDescription(description).setEtherType(ethType) + .setProtocol(protocol).setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange) + .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix) + .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build(); + + flowClassifierBuilder = new DefaultFlowClassifier.Builder(); + final FlowClassifier sameAsFlowClassifier1 = flowClassifierBuilder.setFlowClassifierId(flowClassifierId) + .setTenantId(tenantId).setName(name).setDescription(description).setEtherType(ethType) + .setProtocol(protocol).setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange) + .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix) + .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build(); + + // Create different classifier object. + final String name2 = "FlowClassifier2"; + final String description2 = "FlowClassifier2"; + final String ethType2 = "IPv6"; + final String protocol2 = "udp"; + final int minSrcPortRange2 = 5; + final int maxSrcPortRange2 = 10; + final int minDstPortRange2 = 5; + final int maxDstPortRange2 = 10; + final FlowClassifierId flowClassifierId2 = FlowClassifierId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId2 = TenantId.tenantId("2"); + final IpPrefix srcIpPrefix2 = IpPrefix.valueOf("0.0.0.0/0"); + final IpPrefix dstIpPrefix2 = IpPrefix.valueOf("10.10.10.10/0"); + final VirtualPortId virtualSrcPort2 = VirtualPortId.portId("3"); + final VirtualPortId virtualDstPort2 = VirtualPortId.portId("4"); + + DefaultFlowClassifier.Builder flowClassifierBuilder3 = new DefaultFlowClassifier.Builder(); + final FlowClassifier flowClassifier2 = flowClassifierBuilder3.setFlowClassifierId(flowClassifierId2) + .setTenantId(tenantId2).setName(name2).setDescription(description2).setEtherType(ethType2) + .setProtocol(protocol2).setMinSrcPortRange(minSrcPortRange2).setMaxSrcPortRange(maxSrcPortRange2) + .setMinDstPortRange(minDstPortRange2).setMaxDstPortRange(maxDstPortRange2).setSrcIpPrefix(srcIpPrefix2) + .setDstIpPrefix(dstIpPrefix2).setSrcPort(virtualSrcPort2).setDstPort(virtualDstPort2).build(); + + new EqualsTester().addEqualityGroup(flowClassifier1, sameAsFlowClassifier1).addEqualityGroup(flowClassifier2) + .testEquals(); + } + + /** + * Checks the construction of a DefaultFlowClassifier object. + */ + @Test + public void testConstruction() { + final String name = "FlowClassifier"; + final String description = "FlowClassifier"; + final String ethType = "IPv4"; + final String protocol = "tcp"; + final int minSrcPortRange = 5; + final int maxSrcPortRange = 10; + final int minDstPortRange = 5; + final int maxDstPortRange = 10; + final FlowClassifierId flowClassifierId = FlowClassifierId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0"); + final IpPrefix dstIpPrefix = IpPrefix.valueOf("10.10.10.10/0"); + final VirtualPortId virtualSrcPort = VirtualPortId.portId("1"); + final VirtualPortId virtualDstPort = VirtualPortId.portId("2"); + + DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder(); + final FlowClassifier flowClassifier = flowClassifierBuilder.setFlowClassifierId(flowClassifierId) + .setTenantId(tenantId).setName(name).setDescription(description).setEtherType(ethType) + .setProtocol(protocol).setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange) + .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix) + .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build(); + + assertThat(flowClassifierId, is(flowClassifier.flowClassifierId())); + assertThat(tenantId, is(flowClassifier.tenantId())); + assertThat(name, is(flowClassifier.name())); + assertThat(description, is(flowClassifier.description())); + assertThat(ethType, is(flowClassifier.etherType())); + assertThat(protocol, is(flowClassifier.protocol())); + assertThat(minSrcPortRange, is(flowClassifier.minSrcPortRange())); + assertThat(maxSrcPortRange, is(flowClassifier.maxSrcPortRange())); + assertThat(minDstPortRange, is(flowClassifier.minDstPortRange())); + assertThat(maxDstPortRange, is(flowClassifier.maxDstPortRange())); + assertThat(srcIpPrefix, is(flowClassifier.srcIpPrefix())); + assertThat(dstIpPrefix, is(flowClassifier.dstIpPrefix())); + assertThat(virtualSrcPort, is(flowClassifier.srcPort())); + assertThat(virtualDstPort, is(flowClassifier.dstPort())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultHostRouteTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultHostRouteTest.java new file mode 100644 index 00000000..53ead67f --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultHostRouteTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for DefaultHostRoute class. + */ +public class DefaultHostRouteTest { + final IpAddress nexthop1 = IpAddress.valueOf("192.168.1.1"); + final IpAddress nexthop2 = IpAddress.valueOf("192.168.1.2"); + final IpPrefix destination1 = IpPrefix.valueOf("1.1.1.1/1"); + final IpPrefix destination2 = IpPrefix.valueOf("1.1.1.1/2"); + + /** + * Checks that the DefaultHostRoute class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultHostRoute.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + HostRoute route1 = new DefaultHostRoute(nexthop1, destination1); + HostRoute route2 = new DefaultHostRoute(nexthop1, destination1); + HostRoute route3 = new DefaultHostRoute(nexthop2, destination2); + new EqualsTester().addEqualityGroup(route1, route2) + .addEqualityGroup(route3).testEquals(); + } + + /** + * Checks the construction of a DefaultHostRoute object. + */ + @Test + public void testConstruction() { + final HostRoute host = new DefaultHostRoute(nexthop1, destination1); + assertThat(nexthop1, is(host.nexthop())); + assertThat(destination1, is(host.destination())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultNeutronNetworkTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultNeutronNetworkTest.java new file mode 100644 index 00000000..7f186a1d --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultNeutronNetworkTest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for DefaultNeutronNetwork class. + */ +public class DefaultNeutronNetworkTest { + + private String networkIdStr1 = "123"; + private String networkIdStr2 = "234"; + private String physicalNetworkStr = "1234"; + private String tenantIdStr = "345"; + private String segmentationIdStr = "1"; + private String name = "456"; + + /** + * Checks that the DefaultNeutronNetwork class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultTenantNetwork.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquality() { + TenantNetworkId networkid1 = TenantNetworkId.networkId(networkIdStr1); + TenantNetworkId networkid2 = TenantNetworkId.networkId(networkIdStr2); + PhysicalNetwork physicalNetwork = PhysicalNetwork + .physicalNetwork(physicalNetworkStr); + TenantId tenantId = TenantId.tenantId(tenantIdStr); + SegmentationId segmentationID = SegmentationId + .segmentationId(segmentationIdStr); + TenantNetwork p1 = new DefaultTenantNetwork(networkid1, name, false, + TenantNetwork.State.ACTIVE, + false, tenantId, false, + TenantNetwork.Type.LOCAL, + physicalNetwork, + segmentationID); + TenantNetwork p2 = new DefaultTenantNetwork(networkid1, name, false, + TenantNetwork.State.ACTIVE, + false, tenantId, false, + TenantNetwork.Type.LOCAL, + physicalNetwork, + segmentationID); + TenantNetwork p3 = new DefaultTenantNetwork(networkid2, name, false, + TenantNetwork.State.ACTIVE, + false, tenantId, false, + TenantNetwork.Type.LOCAL, + physicalNetwork, + segmentationID); + new EqualsTester().addEqualityGroup(p1, p2).addEqualityGroup(p3) + .testEquals(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortChainTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortChainTest.java new file mode 100644 index 00000000..27234ac3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortChainTest.java @@ -0,0 +1,134 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import java.util.LinkedList; +import java.util.List; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for DefaultPortChain class. + */ +public class DefaultPortChainTest { + /** + * Checks that the DefaultPortChain class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultPortChain.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + // Create same two port chain objects. + final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortChain1"; + final String description = "PortChain1"; + // create list of Port Pair Groups. + final List portPairGroups = new LinkedList(); + PortPairGroupId portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairGroups.add(portPairGroupId); + portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3af"); + portPairGroups.add(portPairGroupId); + // create list of Flow classifiers. + final List flowClassifiers = new LinkedList(); + FlowClassifierId flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); + flowClassifiers.add(flowClassifierId); + flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af"); + flowClassifiers.add(flowClassifierId); + + DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder(); + final PortChain portChain1 = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name) + .setDescription(description).setPortPairGroups(portPairGroups).setFlowClassifiers(flowClassifiers) + .build(); + + portChainBuilder = new DefaultPortChain.Builder(); + final PortChain samePortChain1 = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name) + .setDescription(description).setPortPairGroups(portPairGroups).setFlowClassifiers(flowClassifiers) + .build(); + + // Create different port chain object. + final PortChainId portChainId2 = PortChainId.of("79999999-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId2 = TenantId.tenantId("2"); + final String name2 = "PortChain2"; + final String description2 = "PortChain2"; + // create list of Port Pair Groups. + final List portPairGroups2 = new LinkedList(); + portPairGroupId = PortPairGroupId.of("75555555-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairGroups2.add(portPairGroupId); + portPairGroupId = PortPairGroupId.of("75555555-fc23-aeb6-f44b-56dc5e2fb3af"); + portPairGroups2.add(portPairGroupId); + // create list of Flow classifiers. + final List flowClassifiers2 = new LinkedList(); + flowClassifierId = FlowClassifierId.of("76666666-fc23-aeb6-f44b-56dc5e2fb3ae"); + flowClassifiers2.add(flowClassifierId); + flowClassifierId = FlowClassifierId.of("76666666-fc23-aeb6-f44b-56dc5e2fb3af"); + flowClassifiers2.add(flowClassifierId); + + portChainBuilder = new DefaultPortChain.Builder(); + final PortChain portChain2 = portChainBuilder.setId(portChainId2).setTenantId(tenantId2).setName(name2) + .setDescription(description2).setPortPairGroups(portPairGroups2).setFlowClassifiers(flowClassifiers2) + .build(); + + new EqualsTester().addEqualityGroup(portChain1, samePortChain1).addEqualityGroup(portChain2).testEquals(); + } + + /** + * Checks the construction of a DefaultPortChain object. + */ + @Test + public void testConstruction() { + final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortChain"; + final String description = "PortChain"; + // create list of Port Pair Groups. + final List portPairGroups = new LinkedList(); + PortPairGroupId portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairGroups.add(portPairGroupId); + portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3af"); + portPairGroups.add(portPairGroupId); + // create list of Flow classifiers. + final List flowClassifiers = new LinkedList(); + FlowClassifierId flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); + flowClassifiers.add(flowClassifierId); + flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af"); + flowClassifiers.add(flowClassifierId); + + DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder(); + final PortChain portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name) + .setDescription(description).setPortPairGroups(portPairGroups).setFlowClassifiers(flowClassifiers) + .build(); + + assertThat(portChainId, is(portChain.portChainId())); + assertThat(tenantId, is(portChain.tenantId())); + assertThat(name, is(portChain.name())); + assertThat(description, is(portChain.description())); + assertThat(portPairGroups, is(portChain.portPairGroups())); + assertThat(flowClassifiers, is(portChain.flowClassifiers())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortPairGroupTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortPairGroupTest.java new file mode 100644 index 00000000..1b484e94 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortPairGroupTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import java.util.LinkedList; +import java.util.List; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for DefaultPortPairGroup class. + */ +public class DefaultPortPairGroupTest { + /** + * Checks that the DefaultPortPairGroup class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultPortPairGroup.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + // Create same two port-pair-group objects. + final PortPairGroupId portPairGroupId = PortPairGroupId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortPairGroup1"; + final String description = "PortPairGroup1"; + // create port-pair-id list + final List portPairList = new LinkedList(); + PortPairId portPairId = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairList.add(portPairId); + portPairId = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairList.add(portPairId); + + DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder(); + final PortPairGroup portPairGroup1 = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId) + .setName(name).setDescription(description).setPortPairs(portPairList).build(); + + portPairGroupBuilder = new DefaultPortPairGroup.Builder(); + final PortPairGroup samePortPairGroup1 = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId) + .setName(name).setDescription(description).setPortPairs(portPairList).build(); + + // Create different port-pair-group object. + final PortPairGroupId portPairGroupId2 = PortPairGroupId.of("79999999-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId2 = TenantId.tenantId("2"); + final String name2 = "PortPairGroup2"; + final String description2 = "PortPairGroup2"; + // create port-pair-id list + final List portPairList2 = new LinkedList(); + portPairId = PortPairId.of("75555555-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairList2.add(portPairId); + portPairId = PortPairId.of("75555555-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairList2.add(portPairId); + + portPairGroupBuilder = new DefaultPortPairGroup.Builder(); + final PortPairGroup portPairGroup2 = portPairGroupBuilder.setId(portPairGroupId2).setTenantId(tenantId2) + .setName(name2).setDescription(description2).setPortPairs(portPairList2).build(); + + new EqualsTester().addEqualityGroup(portPairGroup1, samePortPairGroup1).addEqualityGroup(portPairGroup2) + .testEquals(); + } + + /** + * Checks the construction of a DefaultPortPairGroup object. + */ + @Test + public void testConstruction() { + final PortPairGroupId portPairGroupId = PortPairGroupId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortPairGroup"; + final String description = "PortPairGroup"; + // create port-pair-id list + final List portPairList = new LinkedList(); + PortPairId portPairId = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairList.add(portPairId); + portPairId = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairList.add(portPairId); + + DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder(); + final PortPairGroup portPairGroup = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId) + .setName(name).setDescription(description).setPortPairs(portPairList).build(); + + assertThat(portPairGroupId, is(portPairGroup.portPairGroupId())); + assertThat(tenantId, is(portPairGroup.tenantId())); + assertThat(name, is(portPairGroup.name())); + assertThat(description, is(portPairGroup.description())); + assertThat(portPairList, is(portPairGroup.portPairs())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortPairTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortPairTest.java new file mode 100644 index 00000000..c8004ce6 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultPortPairTest.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for DefaultPortPair class. + */ +public class DefaultPortPairTest { + /** + * Checks that the DefaultPortPair class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultPortPair.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + // Create same two port pair objects. + final PortPairId portPairId = PortPairId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortPair1"; + final String description = "PortPair1"; + final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; + final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; + + DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); + final PortPair portPair1 = portPairBuilder.setId(portPairId).setTenantId(tenantId).setName(name) + .setDescription(description).setIngress(ingress).setEgress(egress).build(); + + portPairBuilder = new DefaultPortPair.Builder(); + final PortPair samePortPair1 = portPairBuilder.setId(portPairId).setTenantId(tenantId).setName(name) + .setDescription(description).setIngress(ingress).setEgress(egress).build(); + + // Create different port pair object. + final PortPairId portPairId2 = PortPairId.of("79999999-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId2 = TenantId.tenantId("2"); + final String name2 = "PortPair2"; + final String description2 = "PortPair2"; + final String ingress2 = "d5555555-24fc-4fae-af4b-321c5e2eb3d1"; + final String egress2 = "a6666666-4a56-2a6e-cd3a-9dee4e2ec345"; + + portPairBuilder = new DefaultPortPair.Builder(); + final PortPair portPair2 = portPairBuilder.setId(portPairId2).setTenantId(tenantId2).setName(name2) + .setDescription(description2).setIngress(ingress2).setEgress(egress2).build(); + + new EqualsTester().addEqualityGroup(portPair1, samePortPair1).addEqualityGroup(portPair2).testEquals(); + } + + /** + * Checks the construction of a DefaultPortPair object. + */ + @Test + public void testConstruction() { + final PortPairId portPairId = PortPairId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortPair"; + final String description = "PortPair"; + final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; + final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; + + DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); + final PortPair portPair = portPairBuilder.setId(portPairId).setTenantId(tenantId).setName(name) + .setDescription(description).setIngress(ingress).setEgress(egress).build(); + + assertThat(portPairId, is(portPair.portPairId())); + assertThat(tenantId, is(portPair.tenantId())); + assertThat(name, is(portPair.name())); + assertThat(description, is(portPair.description())); + assertThat(ingress, is(portPair.ingress())); + assertThat(egress, is(portPair.egress())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultVirtualPortTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultVirtualPortTest.java new file mode 100644 index 00000000..81d8b14d --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/DefaultVirtualPortTest.java @@ -0,0 +1,132 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.vtnrsc; + +import java.util.Map; +import java.util.Set; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.net.DeviceId; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.common.testing.EqualsTester; + +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for DefaultVirtualPort class. + */ +public class DefaultVirtualPortTest { + + private Set fixedIps; + private Map propertyMap; + private Set allowedAddressPairs; + private Set securityGroups; + private VirtualPortId id1; + private VirtualPortId id2; + private String macAddressStr = "fa:12:3e:56:ee:a2"; + private String ipAddress = "10.1.1.1"; + private String deviceStr = "of:000000000000001"; + private String tenantIdStr = "123"; + private String portId1 = "1241"; + private String portId2 = "1242"; + private String tenantNetworkId = "1234567"; + private String subnet = "1212"; + private String hostIdStr = "fa:e2:3e:56:ee:a2"; + + private void initVirtualPortId() { + id1 = VirtualPortId.portId(portId1); + id2 = VirtualPortId.portId(portId2); + } + + private void initFixedIpSet() { + FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(subnet), + IpAddress.valueOf(ipAddress)); + fixedIps = Sets.newHashSet(); + fixedIps.add(fixedIp); + } + + private void initPropertyMap() { + String deviceOwner = "james"; + propertyMap = Maps.newHashMap(); + propertyMap.putIfAbsent("deviceOwner", deviceOwner); + } + + private void initAddressPairSet() { + allowedAddressPairs = Sets.newHashSet(); + AllowedAddressPair allowedAddressPair = AllowedAddressPair + .allowedAddressPair(IpAddress.valueOf(ipAddress), + MacAddress.valueOf(macAddressStr)); + allowedAddressPairs.add(allowedAddressPair); + } + + private void initSecurityGroupSet() { + securityGroups = Sets.newHashSet(); + } + + /** + * Checks that the DefaultVirtualPort class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(SecurityGroup.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + initVirtualPortId(); + initFixedIpSet(); + initPropertyMap(); + initAddressPairSet(); + initSecurityGroupSet(); + TenantNetworkId networkId = TenantNetworkId.networkId(tenantNetworkId); + MacAddress macAddress = MacAddress.valueOf(macAddressStr); + TenantId tenantId = TenantId.tenantId(tenantIdStr); + DeviceId deviceId = DeviceId.deviceId(deviceStr); + BindingHostId bindingHostId = BindingHostId.bindingHostId(hostIdStr); + + VirtualPort d1 = new DefaultVirtualPort(id1, networkId, true, + propertyMap, + VirtualPort.State.ACTIVE, + macAddress, tenantId, deviceId, + fixedIps, bindingHostId, + allowedAddressPairs, + securityGroups); + VirtualPort d2 = new DefaultVirtualPort(id1, networkId, true, + propertyMap, + VirtualPort.State.ACTIVE, + macAddress, tenantId, deviceId, + fixedIps, bindingHostId, + allowedAddressPairs, + securityGroups); + VirtualPort d3 = new DefaultVirtualPort(id2, networkId, true, + propertyMap, + VirtualPort.State.ACTIVE, + macAddress, tenantId, deviceId, + fixedIps, bindingHostId, + allowedAddressPairs, + securityGroups); + new EqualsTester().addEqualityGroup(d1, d2).addEqualityGroup(d3) + .testEquals(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/FixedIpTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/FixedIpTest.java new file mode 100644 index 00000000..d77532a7 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/FixedIpTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.vtnrsc; + +import org.junit.Test; +import org.onlab.packet.IpAddress; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for FixedIp class. + */ +public class FixedIpTest { + + final SubnetId subnetId1 = SubnetId.subnetId("lef11-95w-4er-9c9c"); + final SubnetId subnetId2 = SubnetId.subnetId("lefaa-95w-4er-9c9c"); + final IpAddress ip1 = IpAddress.valueOf("192.168.0.1"); + final IpAddress ip2 = IpAddress.valueOf("192.168.1.1"); + + /** + * Checks that the FixedIp class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(FixedIp.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + FixedIp fixedIp1 = FixedIp.fixedIp(subnetId1, ip1); + FixedIp fixedIp2 = FixedIp.fixedIp(subnetId1, ip1); + FixedIp fixedIp3 = FixedIp.fixedIp(subnetId2, ip2); + new EqualsTester().addEqualityGroup(fixedIp1, fixedIp2) + .addEqualityGroup(fixedIp3).testEquals(); + } + + /** + * Checks the construction of a FixedIp object. + */ + @Test + public void testConstruction() { + FixedIp fixedIp = FixedIp.fixedIp(subnetId1, ip1); + assertThat(ip1, is(notNullValue())); + assertThat(ip1, is(fixedIp.ip())); + assertThat(subnetId1, is(notNullValue())); + assertThat(subnetId1, is(fixedIp.subnetId())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/FlowClassifierIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/FlowClassifierIdTest.java new file mode 100644 index 00000000..0bef00fc --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/FlowClassifierIdTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import java.util.UUID; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for FlowClassifierId class. + */ +public class FlowClassifierIdTest { + + final FlowClassifierId flowClassifierId1 = FlowClassifierId + .of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final FlowClassifierId sameAsFlowClassifierId1 = FlowClassifierId + .of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final FlowClassifierId flowClassifierId2 = FlowClassifierId + .of("dace4513-24fc-4fae-af4b-321c5e2eb3d1"); + + /** + * Checks that the FlowClassifierId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(FlowClassifierId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(flowClassifierId1, sameAsFlowClassifierId1) + .addEqualityGroup(flowClassifierId2).testEquals(); + } + + /** + * Checks the construction of a FlowClassifierId object. + */ + @Test + public void testConstruction() { + final String flowClassifierIdValue = "dace4513-24fc-4fae-af4b-321c5e2eb3d1"; + final FlowClassifierId flowClassifierId = FlowClassifierId.of(flowClassifierIdValue); + assertThat(flowClassifierId, is(notNullValue())); + assertThat(flowClassifierId.value(), is(UUID.fromString(flowClassifierIdValue))); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PhysicalNetworkTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PhysicalNetworkTest.java new file mode 100644 index 00000000..c4f591e7 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PhysicalNetworkTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for PhysicalNetwork class. + */ +public class PhysicalNetworkTest { + + final PhysicalNetwork physicalNetwork1 = PhysicalNetwork.physicalNetwork("1"); + final PhysicalNetwork sameAsPhysicalNetwork1 = PhysicalNetwork.physicalNetwork("1"); + final PhysicalNetwork physicalNetwork2 = PhysicalNetwork.physicalNetwork("2"); + + /** + * Checks that the PhysicalNetwork class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(PhysicalNetwork.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(physicalNetwork1, sameAsPhysicalNetwork1) + .addEqualityGroup(physicalNetwork2).testEquals(); + } + + /** + * Checks the construction of a PhysicalNetwork object. + */ + @Test + public void testConstruction() { + final String physicalNetworkValue = "s"; + final PhysicalNetwork physicalNetwork = PhysicalNetwork + .physicalNetwork(physicalNetworkValue); + assertThat(physicalNetwork, is(notNullValue())); + assertThat(physicalNetwork.physicalNetwork(), is(physicalNetworkValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortChainIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortChainIdTest.java new file mode 100644 index 00000000..1e84fc5d --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortChainIdTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import java.util.UUID; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for PortChainId class. + */ +public class PortChainIdTest { + + final PortChainId portChainId1 = PortChainId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final PortChainId sameAsPortChainId1 = PortChainId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final PortChainId portChainId2 = PortChainId.of("dace4513-24fc-4fae-af4b-321c5e2eb3d1"); + + /** + * Checks that the PortChainId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(PortChainId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(portChainId1, sameAsPortChainId1).addEqualityGroup(portChainId2) + .testEquals(); + } + + /** + * Checks the construction of a PortChainId object. + */ + @Test + public void testConstruction() { + final String portChainIdValue = "dace4513-24fc-4fae-af4b-321c5e2eb3d1"; + final PortChainId portChainId = PortChainId.of(portChainIdValue); + assertThat(portChainId, is(notNullValue())); + assertThat(portChainId.value(), is(UUID.fromString(portChainIdValue))); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortPairGroupIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortPairGroupIdTest.java new file mode 100644 index 00000000..20eb24a5 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortPairGroupIdTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import java.util.UUID; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for PortPairGroupId class. + */ +public class PortPairGroupIdTest { + + final PortPairGroupId portPairGroupId1 = PortPairGroupId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final PortPairGroupId sameAsPortPairGroupId1 = PortPairGroupId + .of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final PortPairGroupId portPairGroupId2 = PortPairGroupId.of("dace4513-24fc-4fae-af4b-321c5e2eb3d1"); + + /** + * Checks that the PortPairGroupId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(PortPairGroupId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(portPairGroupId1, sameAsPortPairGroupId1) + .addEqualityGroup(portPairGroupId2).testEquals(); + } + + /** + * Checks the construction of a PortPairGroupId object. + */ + @Test + public void testConstruction() { + final String portPairGroupIdValue = "dace4513-24fc-4fae-af4b-321c5e2eb3d1"; + final PortPairGroupId portPairGroupId = PortPairGroupId.of(portPairGroupIdValue); + assertThat(portPairGroupId, is(notNullValue())); + assertThat(portPairGroupId.value(), is(UUID.fromString(portPairGroupIdValue))); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortPairIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortPairIdTest.java new file mode 100644 index 00000000..757d3a69 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/PortPairIdTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import java.util.UUID; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for PortPairId class. + */ +public class PortPairIdTest { + + final PortPairId portPairId1 = PortPairId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final PortPairId sameAsPortPairId1 = PortPairId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final PortPairId portPairId2 = PortPairId.of("dace4513-24fc-4fae-af4b-321c5e2eb3d1"); + + /** + * Checks that the PortPairId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(PortPairId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(portPairId1, sameAsPortPairId1).addEqualityGroup(portPairId2).testEquals(); + } + + /** + * Checks the construction of a PortPairId object. + */ + @Test + public void testConstruction() { + final String portPairIdValue = "dace4513-24fc-4fae-af4b-321c5e2eb3d1"; + final PortPairId portPairId = PortPairId.of(portPairIdValue); + assertThat(portPairId, is(notNullValue())); + assertThat(portPairId.value(), is(UUID.fromString(portPairIdValue))); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/RouterGatewayTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/RouterGatewayTest.java new file mode 100644 index 00000000..9f60de8f --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/RouterGatewayTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for RouterGateway class. + */ +public class RouterGatewayTest { + final TenantNetworkId networkId1 = TenantNetworkId.networkId("1"); + final TenantNetworkId networkId2 = TenantNetworkId.networkId("2"); + final Set fixedIpSet1 = new HashSet<>(); + final Set fixedIpSet2 = new HashSet<>(); + + /** + * Checks that the RouterGateway class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(RouterGateway.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + RouterGateway routerGateway1 = RouterGateway.routerGateway(networkId1, + true, + fixedIpSet1); + RouterGateway routerGateway2 = RouterGateway.routerGateway(networkId1, + true, + fixedIpSet1); + RouterGateway routerGateway3 = RouterGateway.routerGateway(networkId2, + true, + fixedIpSet2); + new EqualsTester().addEqualityGroup(routerGateway1, routerGateway2) + .addEqualityGroup(routerGateway3).testEquals(); + } + + /** + * Checks the construction of a RouterGateway object. + */ + @Test + public void testConstruction() { + RouterGateway routerGateway = RouterGateway.routerGateway(networkId1, + true, + fixedIpSet1); + assertThat(fixedIpSet1, is(notNullValue())); + assertThat(fixedIpSet1, is(routerGateway.externalFixedIps())); + assertThat(networkId1, is(notNullValue())); + assertThat(networkId1, is(routerGateway.networkId())); + assertThat(routerGateway.enableSnat(), is(true)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/RouterIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/RouterIdTest.java new file mode 100644 index 00000000..225211b9 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/RouterIdTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for RouterId class. + */ +public class RouterIdTest { + final RouterId routerId1 = RouterId.valueOf("1"); + final RouterId sameAsRouterId1 = RouterId.valueOf("1"); + final RouterId routerId2 = RouterId.valueOf("2"); + + /** + * Checks that the RouterId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(RouterId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(routerId1, sameAsRouterId1).addEqualityGroup(routerId2) + .testEquals(); + } + + /** + * Checks the construction of a RouterId object. + */ + @Test + public void testConstruction() { + final String routerIdValue = "s"; + final RouterId routerId = RouterId.valueOf(routerIdValue); + assertThat(routerId, is(notNullValue())); + assertThat(routerId.routerId(), is(routerIdValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SecurityGroupTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SecurityGroupTest.java new file mode 100644 index 00000000..20871c02 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SecurityGroupTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.vtnrsc; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for SecurityGroup class. + */ +public class SecurityGroupTest { + + final SecurityGroup securityGroup1 = SecurityGroup.securityGroup("1"); + final SecurityGroup sameAssecurityGroup = SecurityGroup.securityGroup("1"); + final SecurityGroup securityGroup2 = SecurityGroup.securityGroup("2"); + + /** + * Checks that the SecurityGroup class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(SecurityGroup.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(securityGroup1, sameAssecurityGroup) + .addEqualityGroup(securityGroup2).testEquals(); + } + + /** + * Checks the construction of a SecurityGroup object. + */ + @Test + public void testConstruction() { + final String securityGroupValue = "1"; + final SecurityGroup securityGroup = SecurityGroup.securityGroup(securityGroupValue); + assertThat(securityGroup, is(notNullValue())); + assertThat(securityGroup.securityGroup(), is(securityGroupValue)); + + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SegmentationIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SegmentationIdTest.java new file mode 100644 index 00000000..dfb3dcf8 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SegmentationIdTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for SegmentationId class. + */ +public class SegmentationIdTest { + + final SegmentationId segmentationID1 = SegmentationId.segmentationId("1"); + final SegmentationId sameAsSegmentationID1 = SegmentationId.segmentationId("1"); + final SegmentationId segmentationID2 = SegmentationId.segmentationId("2"); + + /** + * Checks that the SegmentationId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(SegmentationId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(segmentationID1, sameAsSegmentationID1) + .addEqualityGroup(segmentationID2).testEquals(); + } + + /** + * Checks the construction of a segmentationId object. + */ + @Test + public void testConstruction() { + final String segmentationIdValue = "s"; + final SegmentationId segmentationId = SegmentationId.segmentationId(segmentationIdValue); + assertThat(segmentationId, is(notNullValue())); + assertThat(segmentationId.segmentationId(), is(segmentationIdValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SubnetIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SubnetIdTest.java new file mode 100644 index 00000000..5a1809ce --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/SubnetIdTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for SubnetId class. + */ +public class SubnetIdTest { + + final SubnetId subnetId1 = SubnetId.subnetId("1"); + final SubnetId sameAsSubnetId1 = SubnetId.subnetId("1"); + final SubnetId subnetId2 = SubnetId.subnetId("2"); + + /** + * Checks that the SubnetId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(SubnetId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(subnetId1, sameAsSubnetId1).addEqualityGroup(subnetId2) + .testEquals(); + } + + /** + * Checks the construction of a SubnetId object. + */ + @Test + public void testConstruction() { + final String subnetIdValue = "s"; + final SubnetId subnetId = SubnetId.subnetId(subnetIdValue); + assertThat(subnetId, is(notNullValue())); + assertThat(subnetId.subnetId(), is(subnetIdValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/TenantIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/TenantIdTest.java new file mode 100644 index 00000000..f601d427 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/TenantIdTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for TenantId class. + */ +public class TenantIdTest { + + final TenantId tenantId1 = TenantId.tenantId("1"); + final TenantId sameAsTenantId1 = TenantId.tenantId("1"); + final TenantId tenantId2 = TenantId.tenantId("2"); + + /** + * Checks that the TenantId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(TenantId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(tenantId1, sameAsTenantId1).addEqualityGroup(tenantId2) + .testEquals(); + } + + /** + * Checks the construction of a TenantId object. + */ + @Test + public void testConstruction() { + final String tenantIdValue = "s"; + final TenantId tenantId = TenantId.tenantId(tenantIdValue); + assertThat(tenantId, is(notNullValue())); + assertThat(tenantId.tenantId(), is(tenantIdValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/TenantNetworkIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/TenantNetworkIdTest.java new file mode 100644 index 00000000..3bd72026 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/TenantNetworkIdTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for TenantNetworkId class. + */ +public class TenantNetworkIdTest { + + final TenantNetworkId networkId1 = TenantNetworkId.networkId("1"); + final TenantNetworkId sameAsnetworkId1 = TenantNetworkId.networkId("1"); + final TenantNetworkId networkId2 = TenantNetworkId.networkId("2"); + + /** + * Checks that the TenantNetworkId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(TenantNetworkId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(networkId1, sameAsnetworkId1) + .addEqualityGroup(networkId2).testEquals(); + } + + /** + * Checks the construction of a TenantNetworkId object. + */ + @Test + public void testConstruction() { + final String networkIdValue = "s"; + final TenantNetworkId networkId = TenantNetworkId.networkId(networkIdValue); + assertThat(networkId, is(notNullValue())); + assertThat(networkId.networkId(), is(networkIdValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/VirtualPortIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/VirtualPortIdTest.java new file mode 100644 index 00000000..70966118 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/VirtualPortIdTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.vtnrsc; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +/** + * Unit tests for VirtualPortId class. + */ +public class VirtualPortIdTest { + + final VirtualPortId virtualPortId1 = VirtualPortId.portId("1"); + final VirtualPortId sameAsVirtualPortId1 = VirtualPortId.portId("1"); + final VirtualPortId virtualPortId2 = VirtualPortId.portId("2"); + + /** + * Checks that the VirtualPortId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(VirtualPortId.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(virtualPortId1, sameAsVirtualPortId1) + .addEqualityGroup(virtualPortId2).testEquals(); + } + + /** + * Checks the construction of a VirtualPortId object. + */ + @Test + public void testConstruction() { + final String vPortIdValue = "aaa"; + final VirtualPortId virtualPortId = VirtualPortId.portId(vPortIdValue); + assertThat(virtualPortId, is(notNullValue())); + assertThat(virtualPortId.portId(), is(vPortIdValue)); + + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/floatingip/DefaultFloatingIpTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/floatingip/DefaultFloatingIpTest.java new file mode 100644 index 00000000..d6826f5d --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/floatingip/DefaultFloatingIpTest.java @@ -0,0 +1,125 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.floatingip; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onosproject.vtnrsc.DefaultFloatingIp; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.FloatingIpId; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPortId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for DefaultFloatingIp class. + */ +public class DefaultFloatingIpTest { + + private String floatingIpIdStr1 = "5fb63824-4d5c-4b85-9f2f-ebb93c9ce3df"; + private String floatingIpIdStr2 = "fa44f585-fe02-40d3-afe7-d1d7e5782c99"; + private String floatingIpStr = "10.1.1.2"; + private String fixedIpStr = "192.168.1.2"; + private String tenantIdStr = "123"; + private String tenantNetworkId = "1234567"; + private String virtualPortId = "1212"; + private String routerIdStr = "123"; + + /** + * Checks that the DefaultFloatingIp class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultFloatingIp.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + final TenantId tenantId = TenantId.tenantId(tenantIdStr); + final TenantNetworkId networkId = TenantNetworkId + .networkId(tenantNetworkId); + final VirtualPortId portId = VirtualPortId.portId(virtualPortId); + final RouterId routerId = RouterId.valueOf(routerIdStr); + final FloatingIpId id1 = FloatingIpId.of(floatingIpIdStr1); + final FloatingIpId id2 = FloatingIpId.of(floatingIpIdStr2); + final IpAddress floatingIpAddress = IpAddress.valueOf(floatingIpStr); + final IpAddress fixedIpAddress = IpAddress.valueOf(fixedIpStr); + + FloatingIp fip1 = new DefaultFloatingIp(id1, tenantId, networkId, + portId, routerId, + floatingIpAddress, + fixedIpAddress, + FloatingIp.Status.ACTIVE); + FloatingIp fip2 = new DefaultFloatingIp(id1, tenantId, networkId, + portId, routerId, + floatingIpAddress, + fixedIpAddress, + FloatingIp.Status.ACTIVE); + FloatingIp fip3 = new DefaultFloatingIp(id2, tenantId, networkId, + portId, routerId, + floatingIpAddress, + fixedIpAddress, + FloatingIp.Status.ACTIVE); + + new EqualsTester().addEqualityGroup(fip1, fip2).addEqualityGroup(fip3) + .testEquals(); + } + + /** + * Checks the construction of a DefaultFloatingIp object. + */ + @Test + public void testConstruction() { + final TenantId tenantId = TenantId.tenantId(tenantIdStr); + final TenantNetworkId networkId = TenantNetworkId + .networkId(tenantNetworkId); + final VirtualPortId portId = VirtualPortId.portId(virtualPortId); + final RouterId routerId = RouterId.valueOf(routerIdStr); + final FloatingIpId id = FloatingIpId.of(floatingIpIdStr1); + final IpAddress floatingIpAddress = IpAddress.valueOf(floatingIpStr); + final IpAddress fixedIpAddress = IpAddress.valueOf(fixedIpStr); + + FloatingIp fip = new DefaultFloatingIp(id, tenantId, networkId, portId, + routerId, floatingIpAddress, + fixedIpAddress, + FloatingIp.Status.ACTIVE); + assertThat(id, is(notNullValue())); + assertThat(id, is(fip.id())); + assertThat(tenantId, is(notNullValue())); + assertThat(tenantId, is(fip.tenantId())); + assertThat(networkId, is(notNullValue())); + assertThat(networkId, is(fip.networkId())); + assertThat(portId, is(notNullValue())); + assertThat(portId, is(fip.portId())); + assertThat(routerId, is(notNullValue())); + assertThat(routerId, is(fip.routerId())); + assertThat(floatingIpAddress, is(notNullValue())); + assertThat(floatingIpAddress, is(fip.floatingIp())); + assertThat(fixedIpAddress, is(notNullValue())); + assertThat(fixedIpAddress, is(fip.fixedIp())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/floatingip/FloatingIpIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/floatingip/FloatingIpIdTest.java new file mode 100644 index 00000000..6ae27e9e --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/floatingip/FloatingIpIdTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.floatingip; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.FloatingIpId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for FloatingIpId class. + */ +public class FloatingIpIdTest { + private String floatingIpIdStr1 = "5fb63824-4d5c-4b85-9f2f-ebb93c9ce3df"; + private String floatingIpIdStr2 = "fa44f585-fe02-40d3-afe7-d1d7e5782c99"; + + /** + * Checks that the FloatingIpId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(FloatingIpId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + FloatingIpId id1 = FloatingIpId.of(floatingIpIdStr1); + FloatingIpId id2 = FloatingIpId.of(floatingIpIdStr1); + FloatingIpId id3 = FloatingIpId.of(floatingIpIdStr2); + new EqualsTester().addEqualityGroup(id1, id2).addEqualityGroup(id3) + .testEquals(); + } + + /** + * Checks the construction of a FloatingIpId object. + */ + @Test + public void testConstruction() { + final FloatingIpId id = FloatingIpId.of(floatingIpIdStr1); + assertThat(id, is(notNullValue())); + assertThat(id.floatingIpId().toString(), is(floatingIpIdStr1)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManagerTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManagerTest.java new file mode 100644 index 00000000..8283a52b --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManagerTest.java @@ -0,0 +1,146 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.flowclassifier.impl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +import org.junit.Test; + +import org.onlab.packet.IpPrefix; + +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.DefaultFlowClassifier; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.util.VtnStorageServiceTest; + +/** + * Unit tests for FlowClassifierManager class. + */ +public class FlowClassifierManagerTest { + + final String name = "FlowClassifier"; + final String description = "FlowClassifier"; + final String ethType = "IPv4"; + final String protocol = "udp"; + final int minSrcPortRange = 1024; + final int maxSrcPortRange = 5000; + final int minDstPortRange = 1024; + final int maxDstPortRange = 5000; + final FlowClassifierId flowClassifierId = FlowClassifierId.of("71111111-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("8"); + final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0"); + final IpPrefix dstIpPrefix = IpPrefix.valueOf("100.100.100.100/0"); + final VirtualPortId virtualSrcPort = VirtualPortId.portId("100"); + final VirtualPortId virtualDstPort = VirtualPortId.portId("200"); + DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder(); + FlowClassifierManager flowClassifierMgr = new FlowClassifierManager(); + FlowClassifier flowClassifier = null; + private final VtnStorageServiceTest storageService = new VtnStorageServiceTest(); + + /** + * Checks the operation of createFlowClassifier() method. + */ + @Test + public void testCreateFlowClassifier() { + // initialize flow classifier manager + flowClassifierMgr.storageService = storageService; + flowClassifierMgr.activate(); + + // create flow classifier + flowClassifier = flowClassifierBuilder.setFlowClassifierId(flowClassifierId).setTenantId(tenantId) + .setName(name).setDescription(description).setEtherType(ethType).setProtocol(protocol) + .setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange) + .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix) + .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build(); + assertThat(flowClassifierMgr.createFlowClassifier(flowClassifier), is(true)); + } + + /** + * Checks the operation of exists() method. + */ + @Test + public void testExists() { + testCreateFlowClassifier(); + assertThat(flowClassifierMgr.exists(flowClassifierId), is(true)); + } + + /** + * Checks the operation of getFlowClassifierCount() method. + */ + @Test + public void testGetFlowClassifierCount() { + testCreateFlowClassifier(); + assertThat(flowClassifierMgr.getFlowClassifierCount(), is(1)); + } + + /** + * Checks the operation of getFlowClassifiers() method. + */ + @Test + public void testGetFlowClassifiers() { + testCreateFlowClassifier(); + final Iterable flowClassifierList = flowClassifierMgr.getFlowClassifiers(); + assertThat(flowClassifierList, is(notNullValue())); + assertThat(flowClassifierList.iterator().hasNext(), is(true)); + } + + /** + * Checks the operation of getFlowClassifier() method. + */ + @Test + public void testGetFlowClassifier() { + testCreateFlowClassifier(); + assertThat(flowClassifier, is(notNullValue())); + assertThat(flowClassifierMgr.getFlowClassifier(flowClassifierId), is(flowClassifier)); + } + + /** + * Checks the operation of updateFlowClassifier() method. + */ + @Test + public void testUpdateFlowClassifier() { + // create a flow classifier + testCreateFlowClassifier(); + + // new updates + final String name2 = "FlowClassifier2"; + final String description2 = "FlowClassifier2"; + final String ethType2 = "IPv6"; + final String protocol2 = "tcp"; + final TenantId tenantId2 = TenantId.tenantId("10"); + final VirtualPortId virtualSrcPort2 = VirtualPortId.portId("300"); + final VirtualPortId virtualDstPort2 = VirtualPortId.portId("400"); + flowClassifier = flowClassifierBuilder.setFlowClassifierId(flowClassifierId) + .setTenantId(tenantId2).setName(name2).setDescription(description2).setEtherType(ethType2) + .setProtocol(protocol2).setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange) + .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix) + .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort2).setDstPort(virtualDstPort2).build(); + assertThat(flowClassifierMgr.updateFlowClassifier(flowClassifier), is(true)); + } + + /** + * Checks the operation of removeFlowClassifier() method. + */ + @Test + public void testRemoveFlowClassifier() { + testCreateFlowClassifier(); + assertThat(flowClassifierMgr.removeFlowClassifier(flowClassifierId), is(true)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portchain/impl/PortChainManagerTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portchain/impl/PortChainManagerTest.java new file mode 100644 index 00000000..0831ec9c --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portchain/impl/PortChainManagerTest.java @@ -0,0 +1,155 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.portchain.impl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +import org.junit.Test; +import java.util.List; +import java.util.LinkedList; + +import org.onosproject.vtnrsc.PortChainId; +import org.onosproject.vtnrsc.PortPairGroupId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.PortChain; +import org.onosproject.vtnrsc.DefaultPortChain; +import org.onosproject.vtnrsc.DefaultFlowClassifier; +import org.onosproject.vtnrsc.util.VtnStorageServiceTest; + +/** + * Unit tests for PortChainManager class. + */ +public class PortChainManagerTest { + final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortChain"; + final String description = "PortChain"; + final List portPairGroupList = new LinkedList(); + final List flowClassifierList = new LinkedList(); + DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder(); + DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder(); + PortChainManager portChainMgr = new PortChainManager(); + PortChain portChain = null; + private final VtnStorageServiceTest storageService = new VtnStorageServiceTest(); + + /** + * Checks the operation of createPortChain() method. + */ + @Test + public void testCreatePortChain() { + // initialize port chain manager + portChainMgr.storageService = storageService; + portChainMgr.activate(); + + // create list of Port Pair Groups. + PortPairGroupId portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairGroupList.add(portPairGroupId); + portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3af"); + portPairGroupList.add(portPairGroupId); + + // create list of Flow classifiers. + FlowClassifierId flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); + flowClassifierList.add(flowClassifierId); + flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af"); + flowClassifierList.add(flowClassifierId); + + // create port chain + portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name).setDescription(description) + .setPortPairGroups(portPairGroupList).setFlowClassifiers(flowClassifierList).build(); + assertThat(portChainMgr.createPortChain(portChain), is(true)); + } + + /** + * Checks the operation of exists() method. + */ + @Test + public void testExists() { + testCreatePortChain(); + assertThat(portChainMgr.exists(portChainId), is(true)); + } + + /** + * Checks the operation of getPortChainCount() method. + */ + @Test + public void testGetPortChainCount() { + testCreatePortChain(); + assertThat(portChainMgr.getPortChainCount(), is(1)); + } + + /** + * Checks the operation of getPortChains() method. + */ + @Test + public void testGetPortChains() { + testCreatePortChain(); + final Iterable portChainList = portChainMgr.getPortChains(); + assertThat(portChainList, is(notNullValue())); + assertThat(portChainList.iterator().hasNext(), is(true)); + } + + /** + * Checks the operation of getPortChain() method. + */ + @Test + public void testGetPortChain() { + testCreatePortChain(); + assertThat(portChain, is(notNullValue())); + assertThat(portChainMgr.getPortChain(portChainId), is(portChain)); + } + + /** + * Checks the operation of updatePortChain() method. + */ + @Test + public void testUpdatePortChain() { + // create a port chain + testCreatePortChain(); + + // new updates + final TenantId tenantId2 = TenantId.tenantId("2"); + final String name2 = "PortChain2"; + final String description2 = "PortChain2"; + // create list of Port Pair Groups. + final List portPairGroupList = new LinkedList(); + PortPairGroupId portPairGroupId = PortPairGroupId.of("75555555-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairGroupList.add(portPairGroupId); + portPairGroupId = PortPairGroupId.of("75555555-fc23-aeb6-f44b-56dc5e2fb3af"); + portPairGroupList.add(portPairGroupId); + // create list of Flow classifiers. + final List flowClassifierList = new LinkedList(); + FlowClassifierId flowClassifierId = FlowClassifierId.of("76666666-fc23-aeb6-f44b-56dc5e2fb3ae"); + flowClassifierList.add(flowClassifierId); + flowClassifierId = FlowClassifierId.of("76666666-fc23-aeb6-f44b-56dc5e2fb3af"); + flowClassifierList.add(flowClassifierId); + portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId2).setName(name2) + .setDescription(description2).setPortPairGroups(portPairGroupList) + .setFlowClassifiers(flowClassifierList).build(); + assertThat(portChainMgr.updatePortChain(portChain), is(true)); + } + + /** + * Checks the operation of removePortChain() method. + */ + @Test + public void testRemovePortChain() { + testCreatePortChain(); + assertThat(portChainMgr.removePortChain(portChainId), is(true)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpair/impl/PortPairManagerTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpair/impl/PortPairManagerTest.java new file mode 100644 index 00000000..c936d7cc --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpair/impl/PortPairManagerTest.java @@ -0,0 +1,126 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.portpair.impl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +import org.junit.Test; + +import org.onosproject.vtnrsc.PortPair; +import org.onosproject.vtnrsc.PortPairId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.DefaultPortPair; +import org.onosproject.vtnrsc.util.VtnStorageServiceTest; + +/** + * Unit tests for PortPairManager class. + */ +public class PortPairManagerTest { + final PortPairId portPairId = PortPairId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortPair"; + final String description = "PortPair"; + final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; + final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; + DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); + PortPairManager portPairMgr = new PortPairManager(); + PortPair portPair = null; + private final VtnStorageServiceTest storageService = new VtnStorageServiceTest(); + + /** + * Checks the operation of createPortPair() method. + */ + @Test + public void testCreatePortPair() { + // initialize port pair manager + portPairMgr.storageService = storageService; + portPairMgr.activate(); + + // create port pair + portPair = portPairBuilder.setId(portPairId).setTenantId(tenantId).setName(name) + .setDescription(description).setIngress(ingress).setEgress(egress).build(); + assertThat(portPairMgr.createPortPair(portPair), is(true)); + } + + /** + * Checks the operation of exists() method. + */ + @Test + public void testExists() { + testCreatePortPair(); + assertThat(portPairMgr.exists(portPairId), is(true)); + } + + /** + * Checks the operation of getPortPairCount() method. + */ + @Test + public void testGetPortPairCount() { + testCreatePortPair(); + assertThat(portPairMgr.getPortPairCount(), is(1)); + } + + /** + * Checks the operation of getPortPairs() method. + */ + @Test + public void testGetPortPairs() { + testCreatePortPair(); + final Iterable portPairList = portPairMgr.getPortPairs(); + assertThat(portPairList, is(notNullValue())); + assertThat(portPairList.iterator().hasNext(), is(true)); + } + + /** + * Checks the operation of getPortPair() method. + */ + @Test + public void testGetPortPair() { + testCreatePortPair(); + assertThat(portPair, is(notNullValue())); + assertThat(portPairMgr.getPortPair(portPairId), is(portPair)); + } + + /** + * Checks the operation of updatePortPair() method. + */ + @Test + public void testUpdatePortPair() { + // create a port pair + testCreatePortPair(); + + // new updates + final TenantId tenantId2 = TenantId.tenantId("2"); + final String name2 = "PortPair2"; + final String description2 = "PortPair2"; + final String ingress2 = "d5555555-24fc-4fae-af4b-321c5e2eb3d1"; + final String egress2 = "a6666666-4a56-2a6e-cd3a-9dee4e2ec345"; + portPair = portPairBuilder.setId(portPairId).setTenantId(tenantId2).setName(name2) + .setDescription(description2).setIngress(ingress2).setEgress(egress2).build(); + assertThat(portPairMgr.updatePortPair(portPair), is(true)); + } + + /** + * Checks the operation of removePortPair() method. + */ + @Test + public void testRemovePortPair() { + testCreatePortPair(); + assertThat(portPairMgr.removePortPair(portPairId), is(true)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManagerTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManagerTest.java new file mode 100644 index 00000000..95bcd09a --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManagerTest.java @@ -0,0 +1,140 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.portpairgroup.impl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +import org.junit.Test; +import java.util.List; +import java.util.LinkedList; + +import org.onosproject.vtnrsc.PortPairId; +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.PortPairGroupId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.DefaultPortPairGroup; +import org.onosproject.vtnrsc.util.VtnStorageServiceTest; + +/** + * Unit tests for PortPairGroupManager class. + */ +public class PortPairGroupManagerTest { + final PortPairGroupId portPairGroupId = PortPairGroupId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortPairGroup"; + final String description = "PortPairGroup"; + final List portPairIdList = new LinkedList(); + DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder(); + PortPairGroupManager portPairGroupMgr = new PortPairGroupManager(); + PortPairGroup portPairGroup = null; + private final VtnStorageServiceTest storageService = new VtnStorageServiceTest(); + + /** + * Checks the operation of createPortPairGroup() method. + */ + @Test + public void testCreatePortPairGroup() { + // initialize port pair group manager + portPairGroupMgr.storageService = storageService; + portPairGroupMgr.activate(); + + // create port-pair-id list + PortPairId portPairId = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairIdList.add(portPairId); + portPairId = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairIdList.add(portPairId); + + // create port pair + portPairGroup = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId).setName(name) + .setDescription(description).setPortPairs(portPairIdList).build(); + assertThat(portPairGroupMgr.createPortPairGroup(portPairGroup), is(true)); + } + + /** + * Checks the operation of exists() method. + */ + @Test + public void testExists() { + testCreatePortPairGroup(); + assertThat(portPairGroupMgr.exists(portPairGroupId), is(true)); + } + + /** + * Checks the operation of getPortPairGroupCount() method. + */ + @Test + public void testGetPortPairGroupCount() { + testCreatePortPairGroup(); + assertThat(portPairGroupMgr.getPortPairGroupCount(), is(1)); + } + + /** + * Checks the operation of getPortPairGroups() method. + */ + @Test + public void testGetPortPairGroups() { + testCreatePortPairGroup(); + final Iterable portPairGroupList = portPairGroupMgr.getPortPairGroups(); + assertThat(portPairGroupList, is(notNullValue())); + assertThat(portPairGroupList.iterator().hasNext(), is(true)); + } + + /** + * Checks the operation of getPortPairGroup() method. + */ + @Test + public void testGetPortPairGroup() { + testCreatePortPairGroup(); + assertThat(portPairGroup, is(notNullValue())); + assertThat(portPairGroupMgr.getPortPairGroup(portPairGroupId), is(portPairGroup)); + } + + /** + * Checks the operation of updatePortPairGroup() method. + */ + @Test + public void testUpdatePortPairGroup() { + // create a port pair group + testCreatePortPairGroup(); + + // new updates + // create port-pair-id list + final TenantId tenantId2 = TenantId.tenantId("2"); + final String name2 = "PortPairGroup2"; + final String description2 = "PortPairGroup2"; + final List portPairIdList = new LinkedList(); + PortPairId portPairId = PortPairId.of("75555555-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairIdList.add(portPairId); + portPairId = PortPairId.of("76666666-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairIdList.add(portPairId); + + // create port pair + portPairGroup = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId2).setName(name2) + .setDescription(description2).setPortPairs(portPairIdList).build(); + assertThat(portPairGroupMgr.updatePortPairGroup(portPairGroup), is(true)); + } + + /** + * Checks the operation of removePortPairGroup() method. + */ + @Test + public void testRemovePortPairGroup() { + testCreatePortPairGroup(); + assertThat(portPairGroupMgr.removePortPairGroup(portPairGroupId), is(true)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/DefaultRouterTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/DefaultRouterTest.java new file mode 100644 index 00000000..ecc80658 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/DefaultRouterTest.java @@ -0,0 +1,114 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.router; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import java.util.Collections; + +import org.junit.Test; +import org.onosproject.vtnrsc.DefaultRouter; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.RouterGateway; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPortId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for DefaultRouter class. + */ +public class DefaultRouterTest { + + private String tenantIdStr = "123"; + private String virtualPortId = "1212"; + private String routeIdStr1 = "1"; + private String routeIdStr2 = "2"; + private String routerName = "router"; + private String tenantNetworkId = "1234567"; + + /** + * Checks that the DefaultRouter class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultRouter.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + final TenantId tenantId = TenantId.tenantId(tenantIdStr); + final VirtualPortId portId = VirtualPortId.portId(virtualPortId); + final RouterId routerId1 = RouterId.valueOf(routeIdStr1); + final RouterId routerId2 = RouterId.valueOf(routeIdStr2); + final TenantNetworkId networkId = TenantNetworkId + .networkId(tenantNetworkId); + final RouterGateway routerGateway = RouterGateway.routerGateway( + networkId, + true, + Collections + .emptySet()); + + Router r1 = new DefaultRouter(routerId1, routerName, false, + Router.Status.ACTIVE, false, + routerGateway, portId, tenantId, null); + Router r2 = new DefaultRouter(routerId1, routerName, false, + Router.Status.ACTIVE, false, + routerGateway, portId, tenantId, null); + Router r3 = new DefaultRouter(routerId2, routerName, false, + Router.Status.ACTIVE, false, + routerGateway, portId, tenantId, null); + + new EqualsTester().addEqualityGroup(r1, r2).addEqualityGroup(r3) + .testEquals(); + } + + /** + * Checks the construction of a DefaultRouter object. + */ + @Test + public void testConstruction() { + final TenantId tenantId = TenantId.tenantId(tenantIdStr); + final VirtualPortId portId = VirtualPortId.portId(virtualPortId); + final RouterId routerId = RouterId.valueOf(routeIdStr1); + final TenantNetworkId networkId = TenantNetworkId + .networkId(tenantNetworkId); + final RouterGateway routerGateway = RouterGateway.routerGateway( + networkId, + true, + Collections + .emptySet()); + + Router r1 = new DefaultRouter(routerId, routerName, false, + Router.Status.ACTIVE, false, + routerGateway, portId, tenantId, null); + assertThat(routerId, is(notNullValue())); + assertThat(routerId, is(r1.id())); + assertThat(tenantId, is(notNullValue())); + assertThat(tenantId, is(r1.tenantId())); + assertThat(routerGateway, is(notNullValue())); + assertThat(routerGateway, is(r1.externalGatewayInfo())); + } + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterInterfaceTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterInterfaceTest.java new file mode 100644 index 00000000..53ea037d --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterInterfaceTest.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.router; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.RouterInterface; +import org.onosproject.vtnrsc.SubnetId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.VirtualPortId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for RouterInterface class. + */ +public class RouterInterfaceTest { + private String tenantIdStr = "123"; + private String virtualPortId = "1212"; + private String routeIdStr1 = "1"; + private String routeIdStr2 = "2"; + private String subnetIdStr = "1234567"; + + /** + * Checks that the RouterInterface class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(RouterInterface.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + final TenantId tenantId = TenantId.tenantId(tenantIdStr); + final VirtualPortId portId = VirtualPortId.portId(virtualPortId); + final RouterId routerId1 = RouterId.valueOf(routeIdStr1); + final RouterId routerId2 = RouterId.valueOf(routeIdStr2); + final SubnetId subnet = SubnetId.subnetId(subnetIdStr); + + RouterInterface ri1 = RouterInterface.routerInterface(subnet, portId, + routerId1, + tenantId); + RouterInterface ri2 = RouterInterface.routerInterface(subnet, portId, + routerId1, + tenantId); + RouterInterface ri3 = RouterInterface.routerInterface(subnet, portId, + routerId2, + tenantId); + + new EqualsTester().addEqualityGroup(ri1, ri2).addEqualityGroup(ri3) + .testEquals(); + } + + /** + * Checks the construction of a RouterInterface object. + */ + @Test + public void testConstruction() { + final TenantId tenantId = TenantId.tenantId(tenantIdStr); + final VirtualPortId portId = VirtualPortId.portId(virtualPortId); + final RouterId routerId1 = RouterId.valueOf(routeIdStr1); + final SubnetId subnet = SubnetId.subnetId(subnetIdStr); + + RouterInterface ri1 = RouterInterface.routerInterface(subnet, portId, + routerId1, + tenantId); + assertThat(portId, is(notNullValue())); + assertThat(portId, is(ri1.portId())); + assertThat(tenantId, is(notNullValue())); + assertThat(tenantId, is(ri1.tenantId())); + assertThat(routerId1, is(notNullValue())); + assertThat(routerId1, is(ri1.routerId())); + assertThat(subnet, is(notNullValue())); + assertThat(subnet, is(ri1.subnetId())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnEventuallyConsistentMapAdapter.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnEventuallyConsistentMapAdapter.java new file mode 100644 index 00000000..0631f865 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnEventuallyConsistentMapAdapter.java @@ -0,0 +1,114 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.util; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.function.BiFunction; + +import org.onosproject.store.service.EventuallyConsistentMap; +import org.onosproject.store.service.EventuallyConsistentMapListener; + +/** + * Testing adapter for EventuallyConsistentMap. + */ +public class VtnEventuallyConsistentMapAdapter implements EventuallyConsistentMap { + @Override + public int size() { + return 0; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean containsKey(K key) { + return false; + } + + @Override + public boolean containsValue(V value) { + return false; + } + + @Override + public V get(K key) { + return null; + } + + @Override + public void put(K key, V value) { + + } + + @Override + public V remove(K key) { + return null; + } + + @Override + public void remove(K key, V value) { + + } + + @Override + public V compute(K key, BiFunction recomputeFunction) { + return null; + } + + @Override + public void putAll(Map m) { + + } + + @Override + public void clear() { + + } + + @Override + public Set keySet() { + return null; + } + + @Override + public Collection values() { + return null; + } + + @Override + public Set> entrySet() { + return null; + } + + @Override + public void addListener(EventuallyConsistentMapListener listener) { + + } + + @Override + public void removeListener(EventuallyConsistentMapListener listener) { + + } + + @Override + public void destroy() { + + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnEventuallyConsistentMapTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnEventuallyConsistentMapTest.java new file mode 100644 index 00000000..68b7d689 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnEventuallyConsistentMapTest.java @@ -0,0 +1,242 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.util; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.BiFunction; + +import org.onlab.util.KryoNamespace; +import org.onosproject.cluster.NodeId; +import org.onosproject.store.Timestamp; + +import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.*; +import org.onosproject.store.service.EventuallyConsistentMapListener; +import org.onosproject.store.service.EventuallyConsistentMapEvent; +import org.onosproject.store.service.EventuallyConsistentMapBuilder; +import org.onosproject.store.service.EventuallyConsistentMap; + +/** + * Testing version of an Eventually Consistent Map. + */ + +public final class VtnEventuallyConsistentMapTest extends VtnEventuallyConsistentMapAdapter { + + private final HashMap map; + private final String mapName; + private final List> listeners; + private final BiFunction> peerUpdateFunction; + + private VtnEventuallyConsistentMapTest(String mapName, + BiFunction> peerUpdateFunction) { + map = new HashMap<>(); + listeners = new LinkedList<>(); + this.mapName = mapName; + this.peerUpdateFunction = peerUpdateFunction; + } + + /** + * Notify all listeners of an event. + */ + private void notifyListeners(EventuallyConsistentMapEvent event) { + listeners.forEach( + listener -> listener.event(event) + ); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public boolean containsKey(K key) { + return map.containsKey(key); + } + + @Override + public boolean containsValue(V value) { + return map.containsValue(value); + } + + @Override + public V get(K key) { + return map.get(key); + } + + @Override + public void put(K key, V value) { + map.put(key, value); + EventuallyConsistentMapEvent addEvent = + new EventuallyConsistentMapEvent<>(mapName, PUT, key, value); + notifyListeners(addEvent); + if (peerUpdateFunction != null) { + peerUpdateFunction.apply(key, value); + } + } + + @Override + public V remove(K key) { + V result = map.remove(key); + if (result != null) { + EventuallyConsistentMapEvent removeEvent = + new EventuallyConsistentMapEvent<>(mapName, REMOVE, + key, map.get(key)); + notifyListeners(removeEvent); + } + return result; + } + + @Override + public void remove(K key, V value) { + boolean removed = map.remove(key, value); + if (removed) { + EventuallyConsistentMapEvent removeEvent = + new EventuallyConsistentMapEvent<>(mapName, REMOVE, key, value); + notifyListeners(removeEvent); + } + } + + @Override + public V compute(K key, BiFunction recomputeFunction) { + return map.compute(key, recomputeFunction); + } + + @Override + public void putAll(Map m) { + map.putAll(m); + } + + @Override + public void clear() { + map.clear(); + } + + @Override + public Set keySet() { + return map.keySet(); + } + + @Override + public Collection values() { + return map.values(); + } + + @Override + public Set> entrySet() { + return map.entrySet(); + } + + public static Builder builder() { + return new Builder<>(); + } + + @Override + public void addListener(EventuallyConsistentMapListener listener) { + listeners.add(listener); + } + + @Override + public void removeListener(EventuallyConsistentMapListener listener) { + listeners.remove(listener); + } + + public static class Builder implements EventuallyConsistentMapBuilder { + private String name; + private BiFunction> peerUpdateFunction; + + @Override + public EventuallyConsistentMapBuilder withName(String name) { + this.name = name; + return this; + } + + @Override + public EventuallyConsistentMapBuilder withSerializer(KryoNamespace.Builder serializerBuilder) { + return this; + } + + @Override + public EventuallyConsistentMapBuilder + withTimestampProvider(BiFunction timestampProvider) { + return this; + } + + @Override + public EventuallyConsistentMapBuilder withEventExecutor(ExecutorService executor) { + return this; + } + + @Override + public EventuallyConsistentMapBuilder withCommunicationExecutor(ExecutorService executor) { + return this; + } + + @Override + public EventuallyConsistentMapBuilder withBackgroundExecutor(ScheduledExecutorService executor) { + return this; + } + + @Override + public EventuallyConsistentMapBuilder + withPeerUpdateFunction(BiFunction> peerUpdateFunction) { + this.peerUpdateFunction = peerUpdateFunction; + return this; + } + + @Override + public EventuallyConsistentMapBuilder withTombstonesDisabled() { + return this; + } + + @Override + public EventuallyConsistentMapBuilder withAntiEntropyPeriod(long period, TimeUnit unit) { + return this; + } + + @Override + public EventuallyConsistentMapBuilder withFasterConvergence() { + return this; + } + + @Override + public EventuallyConsistentMapBuilder withPersistence() { + return this; + } + + @Override + public EventuallyConsistentMap build() { + if (name == null) { + name = "test"; + } + return new VtnEventuallyConsistentMapTest<>(name, peerUpdateFunction); + } + } + +} + diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnStorageServiceAdapter.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnStorageServiceAdapter.java new file mode 100644 index 00000000..efb1a791 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnStorageServiceAdapter.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.util; + +import org.onosproject.store.service.EventuallyConsistentMapBuilder; +import org.onosproject.store.service.ConsistentMapBuilder; +import org.onosproject.store.service.DistributedSetBuilder; +import org.onosproject.store.service.DistributedQueueBuilder; +import org.onosproject.store.service.AtomicCounterBuilder; +import org.onosproject.store.service.AtomicValueBuilder; +import org.onosproject.store.service.TransactionContextBuilder; +import org.onosproject.store.service.StorageService; + +/** + * Adapter for the storage service. + */ +public class VtnStorageServiceAdapter implements StorageService { + @Override + public EventuallyConsistentMapBuilder eventuallyConsistentMapBuilder() { + return null; + } + + @Override + public ConsistentMapBuilder consistentMapBuilder() { + return null; + } + + @Override + public DistributedSetBuilder setBuilder() { + return null; + } + + @Override + public DistributedQueueBuilder queueBuilder() { + return null; + } + + @Override + public AtomicCounterBuilder atomicCounterBuilder() { + return null; + } + + @Override + public AtomicValueBuilder atomicValueBuilder() { + return null; + } + + @Override + public TransactionContextBuilder transactionContextBuilder() { + return null; + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnStorageServiceTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnStorageServiceTest.java new file mode 100644 index 00000000..1f0f1835 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/util/VtnStorageServiceTest.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.util; + +import org.onosproject.store.service.EventuallyConsistentMapBuilder; + +public class VtnStorageServiceTest extends VtnStorageServiceAdapter { + @Override + public EventuallyConsistentMapBuilder eventuallyConsistentMapBuilder() { + return VtnEventuallyConsistentMapTest.builder(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FloatingIpWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FloatingIpWebResource.java new file mode 100644 index 00000000..f7e97d5d --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FloatingIpWebResource.java @@ -0,0 +1,285 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.resources; + +import static com.google.common.base.Preconditions.checkNotNull; +import static javax.ws.rs.core.Response.Status.BAD_REQUEST; +import static javax.ws.rs.core.Response.Status.NOT_FOUND; +import static javax.ws.rs.core.Response.Status.CREATED; +import static javax.ws.rs.core.Response.Status.CONFLICT; +import static javax.ws.rs.core.Response.Status.NO_CONTENT; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.onlab.packet.IpAddress; +import org.onlab.util.ItemNotFoundException; +import org.onosproject.rest.AbstractWebResource; +import org.onosproject.vtnrsc.DefaultFloatingIp; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.FloatingIpId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.FloatingIp.Status; +import org.onosproject.vtnrsc.floatingip.FloatingIpService; +import org.onosproject.vtnweb.web.FloatingIpCodec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Sets; + +@Path("floatingips") +public class FloatingIpWebResource extends AbstractWebResource { + private final Logger log = LoggerFactory + .getLogger(FloatingIpWebResource.class); + public static final String CREATE_FAIL = "Floating IP is failed to create!"; + public static final String UPDATE_FAIL = "Floating IP is failed to update!"; + public static final String GET_FAIL = "Floating IP is failed to get!"; + public static final String NOT_EXIST = "Floating IP does not exist!"; + public static final String DELETE_SUCCESS = "Floating IP delete success!"; + public static final String JSON_NOT_NULL = "JsonNode can not be null"; + + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response listFloatingIps() { + Collection floatingIps = get(FloatingIpService.class) + .getFloatingIps(); + ObjectNode result = new ObjectMapper().createObjectNode(); + result.set("floatingips", + new FloatingIpCodec().encode(floatingIps, this)); + return ok(result.toString()).build(); + } + + @GET + @Path("{floatingIpUUID}") + @Produces(MediaType.APPLICATION_JSON) + public Response getFloatingIp(@PathParam("floatingIpUUID") String id, + @QueryParam("fields") List fields) { + + if (!get(FloatingIpService.class).exists(FloatingIpId.of(id))) { + return Response.status(NOT_FOUND).entity(NOT_EXIST).build(); + } + FloatingIp sub = nullIsNotFound(get(FloatingIpService.class) + .getFloatingIp(FloatingIpId.of(id)), GET_FAIL); + + ObjectNode result = new ObjectMapper().createObjectNode(); + if (fields.size() > 0) { + result.set("floatingip", + new FloatingIpCodec().extracFields(sub, this, fields)); + } else { + result.set("floatingip", new FloatingIpCodec().encode(sub, this)); + } + return ok(result.toString()).build(); + } + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response createFloatingIp(final InputStream input) { + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode subnode = mapper.readTree(input); + Collection floatingIps = createOrUpdateByInputStream(subnode); + Boolean result = nullIsNotFound((get(FloatingIpService.class) + .createFloatingIps(floatingIps)), + CREATE_FAIL); + if (!result) { + return Response.status(CONFLICT).entity(CREATE_FAIL).build(); + } + return Response.status(CREATED).entity(result.toString()).build(); + + } catch (Exception e) { + return Response.status(BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @PUT + @Path("{floatingIpUUID}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response updateFloatingIp(@PathParam("floatingIpUUID") String id, + final InputStream input) { + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode subnode = mapper.readTree(input); + Collection floatingIps = createOrUpdateByInputStream(subnode); + Boolean result = nullIsNotFound(get(FloatingIpService.class) + .updateFloatingIps(floatingIps), UPDATE_FAIL); + if (!result) { + return Response.status(CONFLICT).entity(UPDATE_FAIL).build(); + } + return ok(result.toString()).build(); + } catch (Exception e) { + return Response.status(BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @Path("{floatingIpUUID}") + @DELETE + public Response deleteSingleFloatingIp(@PathParam("floatingIpUUID") String id) + throws IOException { + try { + FloatingIpId floatingIpId = FloatingIpId.of(id); + Set floatingIpIds = Sets.newHashSet(floatingIpId); + get(FloatingIpService.class).removeFloatingIps(floatingIpIds); + return Response.status(NO_CONTENT).entity(DELETE_SUCCESS).build(); + } catch (Exception e) { + return Response.status(NOT_FOUND).entity(e.getMessage()).build(); + } + } + + private Collection createOrUpdateByInputStream(JsonNode subnode) + throws Exception { + checkNotNull(subnode, JSON_NOT_NULL); + Collection floatingIps = null; + JsonNode floatingIpNodes = subnode.get("floatingips"); + if (floatingIpNodes == null) { + floatingIpNodes = subnode.get("floatingip"); + } + log.debug("floatingNodes is {}", floatingIpNodes.toString()); + + if (floatingIpNodes.isArray()) { + throw new IllegalArgumentException("only singleton requests allowed"); + } else { + floatingIps = changeJsonToSub(floatingIpNodes); + } + return floatingIps; + } + + /** + * Returns a collection of floatingIps from floatingIpNodes. + * + * @param floatingIpNodes the floatingIp json node + * @return floatingIps a collection of floatingIp + * @throws Exception when any argument is illegal + */ + public Collection changeJsonToSub(JsonNode floatingIpNodes) + throws Exception { + checkNotNull(floatingIpNodes, JSON_NOT_NULL); + Map subMap = new HashMap(); + if (!floatingIpNodes.hasNonNull("id")) { + throw new IllegalArgumentException("id should not be null"); + } else if (floatingIpNodes.get("id").asText().isEmpty()) { + throw new IllegalArgumentException("id should not be empty"); + } + FloatingIpId id = FloatingIpId.of(floatingIpNodes.get("id") + .asText()); + + if (!floatingIpNodes.hasNonNull("tenant_id")) { + throw new IllegalArgumentException("tenant_id should not be null"); + } else if (floatingIpNodes.get("tenant_id").asText().isEmpty()) { + throw new IllegalArgumentException("tenant_id should not be empty"); + } + TenantId tenantId = TenantId.tenantId(floatingIpNodes.get("tenant_id") + .asText()); + + if (!floatingIpNodes.hasNonNull("floating_network_id")) { + throw new IllegalArgumentException( + "floating_network_id should not be null"); + } else if (floatingIpNodes.get("floating_network_id").asText() + .isEmpty()) { + throw new IllegalArgumentException( + "floating_network_id should not be empty"); + } + TenantNetworkId networkId = TenantNetworkId.networkId(floatingIpNodes + .get("floating_network_id").asText()); + + VirtualPortId portId = null; + if (floatingIpNodes.hasNonNull("port_id")) { + portId = VirtualPortId.portId(floatingIpNodes.get("port_id") + .asText()); + } + + RouterId routerId = null; + if (floatingIpNodes.hasNonNull("router_id")) { + routerId = RouterId.valueOf(floatingIpNodes.get("router_id") + .asText()); + } + + IpAddress fixedIp = null; + if (floatingIpNodes.hasNonNull("fixed_ip_address")) { + fixedIp = IpAddress.valueOf(floatingIpNodes.get("fixed_ip_address") + .asText()); + } + + if (!floatingIpNodes.hasNonNull("floating_ip_address")) { + throw new IllegalArgumentException( + "floating_ip_address should not be null"); + } else if (floatingIpNodes.get("floating_ip_address").asText() + .isEmpty()) { + throw new IllegalArgumentException( + "floating_ip_address should not be empty"); + } + IpAddress floatingIp = IpAddress.valueOf(floatingIpNodes + .get("floating_ip_address").asText()); + + if (!floatingIpNodes.hasNonNull("status")) { + throw new IllegalArgumentException("status should not be null"); + } else if (floatingIpNodes.get("status").asText().isEmpty()) { + throw new IllegalArgumentException("status should not be empty"); + } + Status status = Status.valueOf(floatingIpNodes.get("status").asText()); + + DefaultFloatingIp floatingIpObj = new DefaultFloatingIp(id, tenantId, + networkId, + portId, + routerId, + floatingIp, + fixedIp, status); + subMap.put(id, floatingIpObj); + return Collections.unmodifiableCollection(subMap.values()); + } + + /** + * Returns the specified item if that items is null; otherwise throws not + * found exception. + * + * @param item item to check + * @param item type + * @param message not found message + * @return item if not null + * @throws org.onlab.util.ItemNotFoundException if item is null + */ + protected T nullIsNotFound(T item, String message) { + if (item == null) { + throw new ItemNotFoundException(message); + } + return item; + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java index b0e2f38d..08e37f96 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java @@ -15,7 +15,6 @@ */ package org.onosproject.vtnweb.resources; -import static javax.ws.rs.core.Response.Status.NOT_FOUND; import static javax.ws.rs.core.Response.Status.OK; import static org.onlab.util.Tools.nullIsNotFound; @@ -54,7 +53,6 @@ public class FlowClassifierWebResource extends AbstractWebResource { private final Logger log = LoggerFactory.getLogger(FlowClassifierWebResource.class); - final FlowClassifierService service = get(FlowClassifierService.class); public static final String FLOW_CLASSIFIER_NOT_FOUND = "Flow classifier not found"; /** @@ -65,7 +63,7 @@ public class FlowClassifierWebResource extends AbstractWebResource { @GET @Produces(MediaType.APPLICATION_JSON) public Response getFlowClassifiers() { - final Iterable flowClassifiers = service.getFlowClassifiers(); + Iterable flowClassifiers = get(FlowClassifierService.class).getFlowClassifiers(); ObjectNode result = new ObjectMapper().createObjectNode(); ArrayNode flowClassifierEntry = result.putArray("flow_classifiers"); if (flowClassifiers != null) { @@ -79,19 +77,16 @@ public class FlowClassifierWebResource extends AbstractWebResource { /** * Get details of a flow classifier. * - * @param id flow classifier id + * @param id + * flow classifier id * @return 200 OK , 404 if given identifier does not exist */ @GET @Path("{flow_id}") @Produces(MediaType.APPLICATION_JSON) public Response getFlowClassifier(@PathParam("flow_id") String id) { - - if (!service.hasFlowClassifier(FlowClassifierId.of(id))) { - return Response.status(NOT_FOUND).entity(FLOW_CLASSIFIER_NOT_FOUND).build(); - } - FlowClassifier flowClassifier = nullIsNotFound(service.getFlowClassifier(FlowClassifierId.of(id)), - FLOW_CLASSIFIER_NOT_FOUND); + FlowClassifier flowClassifier = nullIsNotFound( + get(FlowClassifierService.class).getFlowClassifier(FlowClassifierId.of(id)), FLOW_CLASSIFIER_NOT_FOUND); ObjectNode result = new ObjectMapper().createObjectNode(); result.set("flow_classifier", new FlowClassifierCodec().encode(flowClassifier, this)); @@ -102,9 +97,10 @@ public class FlowClassifierWebResource extends AbstractWebResource { /** * Creates and stores a new flow classifier. * - * @param stream flow classifier from JSON + * @param stream + * flow classifier from JSON * @return status of the request - CREATED if the JSON is correct, - * BAD_REQUEST if the JSON is invalid + * BAD_REQUEST if the JSON is invalid */ @POST @Consumes(MediaType.APPLICATION_JSON) @@ -116,7 +112,8 @@ public class FlowClassifierWebResource extends AbstractWebResource { JsonNode flow = jsonTree.get("flow_classifier"); FlowClassifier flowClassifier = new FlowClassifierCodec().decode((ObjectNode) flow, this); - Boolean issuccess = nullIsNotFound(service.createFlowClassifier(flowClassifier), FLOW_CLASSIFIER_NOT_FOUND); + Boolean issuccess = nullIsNotFound(get(FlowClassifierService.class).createFlowClassifier(flowClassifier), + FLOW_CLASSIFIER_NOT_FOUND); return Response.status(OK).entity(issuccess.toString()).build(); } catch (IOException ex) { log.error("Exception while creating flow classifier {}.", ex.toString()); @@ -127,8 +124,10 @@ public class FlowClassifierWebResource extends AbstractWebResource { /** * Update details of a flow classifier. * - * @param id flow classifier id - * @param stream InputStream + * @param id + * flow classifier id + * @param stream + * InputStream * @return 200 OK, 404 if given identifier does not exist */ @PUT @@ -141,7 +140,8 @@ public class FlowClassifierWebResource extends AbstractWebResource { JsonNode jsonTree = mapper().readTree(stream); JsonNode flow = jsonTree.get("flow_classifier"); FlowClassifier flowClassifier = new FlowClassifierCodec().decode((ObjectNode) flow, this); - Boolean result = nullIsNotFound(service.updateFlowClassifier(flowClassifier), FLOW_CLASSIFIER_NOT_FOUND); + Boolean result = nullIsNotFound(get(FlowClassifierService.class).updateFlowClassifier(flowClassifier), + FLOW_CLASSIFIER_NOT_FOUND); return Response.status(OK).entity(result.toString()).build(); } catch (IOException e) { log.error("Update flow classifier failed because of exception {}.", e.toString()); @@ -152,14 +152,16 @@ public class FlowClassifierWebResource extends AbstractWebResource { /** * Delete details of a flow classifier. * - * @param id flow classifier id + * @param id + * flow classifier id */ @Path("{flow_id}") @DELETE public void deleteFlowClassifier(@PathParam("flow_id") String id) { log.debug("Deletes flow classifier by identifier {}.", id); FlowClassifierId flowClassifierId = FlowClassifierId.of(id); - Boolean issuccess = nullIsNotFound(service.removeFlowClassifier(flowClassifierId), FLOW_CLASSIFIER_NOT_FOUND); + Boolean issuccess = nullIsNotFound(get(FlowClassifierService.class).removeFlowClassifier(flowClassifierId), + FLOW_CLASSIFIER_NOT_FOUND); } } diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/RouterWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/RouterWebResource.java new file mode 100644 index 00000000..6f80dd15 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/RouterWebResource.java @@ -0,0 +1,447 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.resources; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static javax.ws.rs.core.Response.Status.BAD_REQUEST; +import static javax.ws.rs.core.Response.Status.CONFLICT; +import static javax.ws.rs.core.Response.Status.CREATED; +import static javax.ws.rs.core.Response.Status.NOT_FOUND; +import static javax.ws.rs.core.Response.Status.NO_CONTENT; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.onlab.packet.IpAddress; +import org.onlab.util.ItemNotFoundException; +import org.onosproject.rest.AbstractWebResource; +import org.onosproject.vtnrsc.DefaultRouter; +import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.Router.Status; +import org.onosproject.vtnrsc.RouterGateway; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.RouterInterface; +import org.onosproject.vtnrsc.SubnetId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.router.RouterService; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService; +import org.onosproject.vtnweb.web.RouterCodec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +@Path("routers") +public class RouterWebResource extends AbstractWebResource { + private final Logger log = LoggerFactory.getLogger(RouterWebResource.class); + public static final String CREATE_FAIL = "Router is failed to create!"; + public static final String UPDATE_FAIL = "Router is failed to update!"; + public static final String GET_FAIL = "Router is failed to get!"; + public static final String NOT_EXIST = "Router does not exist!"; + public static final String DELETE_SUCCESS = "Router delete success!"; + public static final String JSON_NOT_NULL = "JsonNode can not be null"; + public static final String INTFACR_ADD_SUCCESS = "Interface add success"; + public static final String INTFACR_DEL_SUCCESS = "Interface delete success"; + + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response listRouters() { + Collection routers = get(RouterService.class).getRouters(); + ObjectNode result = new ObjectMapper().createObjectNode(); + result.set("routers", new RouterCodec().encode(routers, this)); + return ok(result.toString()).build(); + } + + @GET + @Path("{routerUUID}") + @Produces(MediaType.APPLICATION_JSON) + public Response getRouter(@PathParam("routerUUID") String id, + @QueryParam("fields") List fields) { + + if (!get(RouterService.class).exists(RouterId.valueOf(id))) { + return Response.status(NOT_FOUND) + .entity("The Router does not exists").build(); + } + Router sub = nullIsNotFound(get(RouterService.class) + .getRouter(RouterId.valueOf(id)), + NOT_EXIST); + + ObjectNode result = new ObjectMapper().createObjectNode(); + if (fields.size() > 0) { + result.set("router", + new RouterCodec().extracFields(sub, this, fields)); + } else { + result.set("router", new RouterCodec().encode(sub, this)); + } + return ok(result.toString()).build(); + } + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response createRouter(final InputStream input) { + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode subnode = mapper.readTree(input); + Collection routers = createOrUpdateByInputStream(subnode); + + Boolean result = nullIsNotFound((get(RouterService.class) + .createRouters(routers)), + CREATE_FAIL); + if (!result) { + return Response.status(CONFLICT).entity(CREATE_FAIL).build(); + } + return Response.status(CREATED).entity(result.toString()).build(); + + } catch (Exception e) { + return Response.status(BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @PUT + @Path("{routerUUID}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response updateRouter(@PathParam("routerUUID") String id, + final InputStream input) { + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode subnode = mapper.readTree(input); + Collection routers = createOrUpdateByInputStream(subnode); + Boolean result = nullIsNotFound(get(RouterService.class) + .updateRouters(routers), UPDATE_FAIL); + if (!result) { + return Response.status(CONFLICT).entity(UPDATE_FAIL).build(); + } + return ok(result.toString()).build(); + } catch (Exception e) { + return Response.status(BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @Path("{routerUUID}") + @DELETE + public Response deleteSingleRouter(@PathParam("routerUUID") String id) + throws IOException { + try { + RouterId routerId = RouterId.valueOf(id); + Set routerIds = Sets.newHashSet(routerId); + get(RouterService.class).removeRouters(routerIds); + return Response.status(NO_CONTENT).entity(DELETE_SUCCESS).build(); + } catch (Exception e) { + return Response.status(BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @PUT + @Path("{routerUUID}/add_router_interface") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response addRouterInterface(@PathParam("routerUUID") String id, + final InputStream input) { + if (!get(RouterService.class).exists(RouterId.valueOf(id))) { + return Response.status(NOT_FOUND).entity(NOT_EXIST).build(); + } + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode subnode = mapper.readTree(input); + if (!subnode.hasNonNull("id")) { + throw new IllegalArgumentException("id should not be null"); + } else if (subnode.get("id").asText().isEmpty()) { + throw new IllegalArgumentException("id should not be empty"); + } + RouterId routerId = RouterId.valueOf(id); + if (!subnode.hasNonNull("subnet_id")) { + throw new IllegalArgumentException("subnet_id should not be null"); + } else if (subnode.get("subnet_id").asText().isEmpty()) { + throw new IllegalArgumentException("subnet_id should not be empty"); + } + SubnetId subnetId = SubnetId.subnetId(subnode.get("subnet_id") + .asText()); + if (!subnode.hasNonNull("tenant_id")) { + throw new IllegalArgumentException("tenant_id should not be null"); + } else if (subnode.get("tenant_id").asText().isEmpty()) { + throw new IllegalArgumentException("tenant_id should not be empty"); + } + TenantId tenentId = TenantId.tenantId(subnode.get("tenant_id") + .asText()); + if (!subnode.hasNonNull("port_id")) { + throw new IllegalArgumentException("port_id should not be null"); + } else if (subnode.get("port_id").asText().isEmpty()) { + throw new IllegalArgumentException("port_id should not be empty"); + } + VirtualPortId portId = VirtualPortId.portId(subnode.get("port_id") + .asText()); + RouterInterface routerInterface = RouterInterface + .routerInterface(subnetId, portId, routerId, tenentId); + get(RouterInterfaceService.class) + .addRouterInterface(routerInterface); + return ok(INTFACR_ADD_SUCCESS).build(); + } catch (Exception e) { + return Response.status(BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @PUT + @Path("{routerUUID}/remove_router_interface") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response removeRouterInterface(@PathParam("routerUUID") String id, + final InputStream input) { + if (!get(RouterService.class).exists(RouterId.valueOf(id))) { + return Response.status(NOT_FOUND).entity(NOT_EXIST).build(); + } + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode subnode = mapper.readTree(input); + if (!subnode.hasNonNull("id")) { + throw new IllegalArgumentException("id should not be null"); + } else if (subnode.get("id").asText().isEmpty()) { + throw new IllegalArgumentException("id should not be empty"); + } + RouterId routerId = RouterId.valueOf(id); + if (!subnode.hasNonNull("subnet_id")) { + throw new IllegalArgumentException("subnet_id should not be null"); + } else if (subnode.get("subnet_id").asText().isEmpty()) { + throw new IllegalArgumentException("subnet_id should not be empty"); + } + SubnetId subnetId = SubnetId.subnetId(subnode.get("subnet_id") + .asText()); + if (!subnode.hasNonNull("port_id")) { + throw new IllegalArgumentException("port_id should not be null"); + } else if (subnode.get("port_id").asText().isEmpty()) { + throw new IllegalArgumentException("port_id should not be empty"); + } + VirtualPortId portId = VirtualPortId.portId(subnode.get("port_id") + .asText()); + if (!subnode.hasNonNull("tenant_id")) { + throw new IllegalArgumentException("tenant_id should not be null"); + } else if (subnode.get("tenant_id").asText().isEmpty()) { + throw new IllegalArgumentException("tenant_id should not be empty"); + } + TenantId tenentId = TenantId.tenantId(subnode.get("tenant_id") + .asText()); + RouterInterface routerInterface = RouterInterface + .routerInterface(subnetId, portId, routerId, tenentId); + get(RouterInterfaceService.class) + .removeRouterInterface(routerInterface); + return ok(INTFACR_DEL_SUCCESS).build(); + } catch (Exception e) { + return Response.status(BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + private Collection createOrUpdateByInputStream(JsonNode subnode) + throws Exception { + checkNotNull(subnode, JSON_NOT_NULL); + JsonNode routerNode = subnode.get("routers"); + if (routerNode == null) { + routerNode = subnode.get("router"); + } + log.debug("routerNode is {}", routerNode.toString()); + + if (routerNode.isArray()) { + throw new Exception("only singleton requests allowed"); + } else { + return changeJsonToSub(routerNode); + } + } + + /** + * Returns a collection of floatingIps from floatingIpNodes. + * + * @param routerNode the router json node + * @return routers a collection of router + * @throws Exception when any argument is illegal + */ + public Collection changeJsonToSub(JsonNode routerNode) + throws Exception { + checkNotNull(routerNode, JSON_NOT_NULL); + Map subMap = new HashMap(); + if (!routerNode.hasNonNull("id")) { + new IllegalArgumentException("id should not be null"); + } else if (routerNode.get("id").asText().isEmpty()) { + throw new IllegalArgumentException("id should not be empty"); + } + RouterId id = RouterId.valueOf(routerNode.get("id").asText()); + + if (!routerNode.hasNonNull("tenant_id")) { + throw new IllegalArgumentException("tenant_id should not be null"); + } else if (routerNode.get("tenant_id").asText().isEmpty()) { + throw new IllegalArgumentException("tenant_id should not be empty"); + } + TenantId tenantId = TenantId.tenantId(routerNode.get("tenant_id") + .asText()); + + VirtualPortId gwPortId = null; + if (routerNode.hasNonNull("gw_port_id")) { + gwPortId = VirtualPortId.portId(routerNode.get("gw_port_id") + .asText()); + } + + if (!routerNode.hasNonNull("status")) { + throw new IllegalArgumentException("status should not be null"); + } else if (routerNode.get("status").asText().isEmpty()) { + throw new IllegalArgumentException("status should not be empty"); + } + Status status = Status.valueOf(routerNode.get("status").asText()); + + String routerName = null; + if (routerNode.hasNonNull("name")) { + routerName = routerNode.get("name").asText(); + } + + boolean adminStateUp = true; + checkArgument(routerNode.get("admin_state_up").isBoolean(), + "admin_state_up should be boolean"); + if (routerNode.hasNonNull("admin_state_up")) { + adminStateUp = routerNode.get("admin_state_up").asBoolean(); + } + boolean distributed = false; + if (routerNode.hasNonNull("distributed")) { + distributed = routerNode.get("distributed").asBoolean(); + } + RouterGateway gateway = null; + if (routerNode.hasNonNull("external_gateway_info")) { + gateway = jsonNodeToGateway(routerNode.get("external_gateway_info")); + } + List routes = new ArrayList(); + DefaultRouter routerObj = new DefaultRouter(id, routerName, + adminStateUp, status, + distributed, gateway, + gwPortId, tenantId, routes); + subMap.put(id, routerObj); + return Collections.unmodifiableCollection(subMap.values()); + } + + /** + * Changes JsonNode Gateway to the Gateway. + * + * @param gateway the gateway JsonNode + * @return gateway + */ + private RouterGateway jsonNodeToGateway(JsonNode gateway) { + checkNotNull(gateway, JSON_NOT_NULL); + if (!gateway.hasNonNull("network_id")) { + throw new IllegalArgumentException("network_id should not be null"); + } else if (gateway.get("network_id").asText().isEmpty()) { + throw new IllegalArgumentException("network_id should not be empty"); + } + TenantNetworkId networkId = TenantNetworkId.networkId(gateway + .get("network_id").asText()); + + if (!gateway.hasNonNull("enable_snat")) { + throw new IllegalArgumentException("enable_snat should not be null"); + } else if (gateway.get("enable_snat").asText().isEmpty()) { + throw new IllegalArgumentException("enable_snat should not be empty"); + } + checkArgument(gateway.get("enable_snat").isBoolean(), + "enable_snat should be boolean"); + boolean enableSnat = gateway.get("enable_snat").asBoolean(); + + if (!gateway.hasNonNull("external_fixed_ips")) { + throw new IllegalArgumentException( + "external_fixed_ips should not be null"); + } else if (gateway.get("external_fixed_ips").isNull()) { + throw new IllegalArgumentException( + "external_fixed_ips should not be empty"); + } + Collection fixedIpList = jsonNodeToFixedIp(gateway + .get("external_fixed_ips")); + RouterGateway gatewayObj = RouterGateway.routerGateway(networkId, + enableSnat, + fixedIpList); + return gatewayObj; + } + + /** + * Changes JsonNode fixedIp to a collection of the fixedIp. + * + * @param fixedIp the allocationPools JsonNode + * @return a collection of fixedIp + */ + private Collection jsonNodeToFixedIp(JsonNode fixedIp) { + checkNotNull(fixedIp, JSON_NOT_NULL); + ConcurrentMap fixedIpMaps = Maps.newConcurrentMap(); + Integer i = 0; + for (JsonNode node : fixedIp) { + if (!node.hasNonNull("subnet_id")) { + throw new IllegalArgumentException("subnet_id should not be null"); + } else if (node.get("subnet_id").asText().isEmpty()) { + throw new IllegalArgumentException("subnet_id should not be empty"); + } + SubnetId subnetId = SubnetId.subnetId(node.get("subnet_id") + .asText()); + if (!node.hasNonNull("ip_address")) { + throw new IllegalArgumentException("ip_address should not be null"); + } else if (node.get("ip_address").asText().isEmpty()) { + throw new IllegalArgumentException("ip_address should not be empty"); + } + IpAddress ipAddress = IpAddress.valueOf(node.get("ip_address") + .asText()); + FixedIp fixedIpObj = FixedIp.fixedIp(subnetId, ipAddress); + + fixedIpMaps.putIfAbsent(i, fixedIpObj); + i++; + } + return Collections.unmodifiableCollection(fixedIpMaps.values()); + } + + /** + * Returns the specified item if that items is null; otherwise throws not + * found exception. + * + * @param item item to check + * @param item type + * @param message not found message + * @return item if not null + * @throws org.onlab.util.ItemNotFoundException if item is null + */ + protected T nullIsNotFound(T item, String message) { + if (item == null) { + throw new ItemNotFoundException(message); + } + return item; + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java index 2dd931ea..fd2c4790 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java @@ -98,20 +98,20 @@ public class TenantNetworkWebResource extends AbstractWebResource { if ((queryId == null || queryId.equals(network.id().toString())) && (queryName == null || queryName.equals(network.name())) && (queryadminStateUp == null || queryadminStateUp - .equals(network.adminStateUp())) + .equals(Boolean.toString(network.adminStateUp()))) && (querystate == null || querystate.equals(network.state() .toString())) - && (queryshared == null || queryshared.equals(network - .shared())) + && (queryshared == null || queryshared.equals(Boolean.toString(network + .shared()))) && (querytenantId == null || querytenantId.equals(network .tenantId().toString())) - && (routerExternal == null || routerExternal.equals(network - .routerExternal())) - && (type == null || type.equals(network.type())) + && (routerExternal == null || routerExternal.equals(Boolean.toString(network + .routerExternal()))) + && (type == null || type.equals(network.type().toString())) && (physicalNetwork == null || physicalNetwork - .equals(network.physicalNetwork())) + .equals(network.physicalNetwork().toString())) && (segmentationId == null || segmentationId.equals(network - .segmentationId()))) { + .segmentationId().toString()))) { networksMap.putIfAbsent(network.id(), network); } } @@ -269,42 +269,39 @@ public class TenantNetworkWebResource extends AbstractWebResource { TenantNetwork network = null; ConcurrentMap networksMap = Maps .newConcurrentMap(); - if (node != null) { - checkArgument(node.get("admin_state_up").isBoolean(), "admin_state_up should be boolean"); - checkArgument(node.get("shared").isBoolean(), "shared should be boolean"); - checkArgument(node.get("router:external").isBoolean(), "router:external should be boolean"); - String name = node.get("name").asText(); - boolean adminStateUp = node.get("admin_state_up").asBoolean(); - String state = node.get("status").asText(); - boolean shared = node.get("shared").asBoolean(); - String tenantId = node.get("tenant_id").asText(); - boolean routerExternal = node.get("router:external").asBoolean(); - String type = node.get("provider:network_type").asText(); - String physicalNetwork = node.get("provider:physical_network") - .asText(); - String segmentationId = node.get("provider:segmentation_id") - .asText(); - TenantNetworkId id = null; - if (flag == CREATE_NETWORK) { - id = TenantNetworkId.networkId(node.get("id").asText()); - } else if (flag == UPDATE_NETWORK) { - id = networkId; - } - network = new DefaultTenantNetwork( - id, - name, - adminStateUp, - isState(state), - shared, - TenantId.tenantId(tenantId), - routerExternal, - isType(type), - PhysicalNetwork - .physicalNetwork(physicalNetwork), - SegmentationId - .segmentationId(segmentationId)); - networksMap.putIfAbsent(id, network); + checkArgument(node.get("admin_state_up").isBoolean(), "admin_state_up should be boolean"); + checkArgument(node.get("shared").isBoolean(), "shared should be boolean"); + checkArgument(node.get("router:external").isBoolean(), "router:external should be boolean"); + String name = node.get("name").asText(); + boolean adminStateUp = node.get("admin_state_up").asBoolean(); + String state = node.get("status").asText(); + boolean shared = node.get("shared").asBoolean(); + String tenantId = node.get("tenant_id").asText(); + boolean routerExternal = node.get("router:external").asBoolean(); + String type = node.get("provider:network_type").asText(); + String physicalNetwork = node.get("provider:physical_network").asText(); + String segmentationId = node.get("provider:segmentation_id").asText(); + TenantNetworkId id = null; + if (flag.equals(CREATE_NETWORK)) { + id = TenantNetworkId.networkId(node.get("id").asText()); + } else if (flag.equals(UPDATE_NETWORK)) { + id = networkId; } + network = new DefaultTenantNetwork( + id, + name, + adminStateUp, + isState(state), + shared, + TenantId.tenantId(tenantId), + routerExternal, + isType(type), + PhysicalNetwork + .physicalNetwork(physicalNetwork), + SegmentationId + .segmentationId(segmentationId)); + networksMap.putIfAbsent(id, network); + return Collections.unmodifiableCollection(networksMap.values()); } @@ -319,38 +316,32 @@ public class TenantNetworkWebResource extends AbstractWebResource { TenantNetwork network = null; ConcurrentMap networksMap = Maps .newConcurrentMap(); - if (nodes != null) { - for (JsonNode node : nodes) { - String id = node.get("id").asText(); - String name = node.get("name").asText(); - boolean adminStateUp = node.get("admin_state_up").asBoolean(); - String state = node.get("status").asText(); - boolean shared = node.get("shared").asBoolean(); - String tenantId = node.get("tenant_id").asText(); - boolean routerExternal = node.get("router:external") - .asBoolean(); - String type = node.get("provider:network_type").asText(); - String physicalNetwork = node.get("provider:physical_network") - .asText(); - String segmentationId = node.get("provider:segmentation_id") - .asText(); - network = new DefaultTenantNetwork( - TenantNetworkId - .networkId(id), - name, - adminStateUp, - isState(state), - shared, - TenantId.tenantId(tenantId), - routerExternal, - isType(type), - PhysicalNetwork - .physicalNetwork(physicalNetwork), - SegmentationId - .segmentationId(segmentationId)); - networksMap.putIfAbsent(TenantNetworkId.networkId(id), network); - } + for (JsonNode node : nodes) { + String id = node.get("id").asText(); + String name = node.get("name").asText(); + boolean adminStateUp = node.get("admin_state_up").asBoolean(); + String state = node.get("status").asText(); + boolean shared = node.get("shared").asBoolean(); + String tenantId = node.get("tenant_id").asText(); + boolean routerExternal = node.get("router:external") + .asBoolean(); + String type = node.get("provider:network_type").asText(); + String physicalNetwork = node.get("provider:physical_network").asText(); + String segmentationId = node.get("provider:segmentation_id").asText(); + network = new DefaultTenantNetwork( + TenantNetworkId.networkId(id), + name, + adminStateUp, + isState(state), + shared, + TenantId.tenantId(tenantId), + routerExternal, + isType(type), + PhysicalNetwork.physicalNetwork(physicalNetwork), + SegmentationId.segmentationId(segmentationId)); + networksMap.putIfAbsent(TenantNetworkId.networkId(id), network); } + return Collections.unmodifiableCollection(networksMap.values()); } diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/FloatingIpCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/FloatingIpCodec.java new file mode 100644 index 00000000..ff5aebb4 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/FloatingIpCodec.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.web; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Iterator; +import java.util.List; + +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.vtnrsc.FloatingIp; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * FloatingIp JSON codec. + */ +public final class FloatingIpCodec extends JsonCodec { + @Override + public ObjectNode encode(FloatingIp floatingIp, CodecContext context) { + checkNotNull(floatingIp, "floatingIp cannot be null"); + ObjectNode result = context + .mapper() + .createObjectNode() + .put("id", floatingIp.id().floatingIpId().toString()) + .put("floating_network_id", floatingIp.networkId().toString()) + .put("router_id", + floatingIp.routerId() == null ? null : floatingIp + .routerId().routerId()) + .put("tenant_id", floatingIp.tenantId().toString()) + .put("port_id", + floatingIp.portId() == null ? null : floatingIp.portId() + .toString()) + .put("fixed_ip_address", + floatingIp.fixedIp() == null ? null : floatingIp.fixedIp() + .toString()) + .put("floating_ip_address", floatingIp.floatingIp().toString()) + .put("status", floatingIp.status().toString()); + return result; + } + + public ObjectNode extracFields(FloatingIp floatingIp, CodecContext context, + List fields) { + checkNotNull(floatingIp, "floatingIp cannot be null"); + ObjectNode result = context.mapper().createObjectNode(); + Iterator i = fields.iterator(); + while (i.hasNext()) { + String s = i.next(); + if (s.equals("floating_network_id")) { + result.put("floating_network_id", floatingIp.networkId() + .toString()); + } + if (s.equals("router_id")) { + result.put("router_id", + floatingIp.routerId() == null ? null : floatingIp + .routerId().routerId()); + } + if (s.equals("tenant_id")) { + result.put("tenant_id", floatingIp.tenantId().toString()); + } + if (s.equals("port_id")) { + result.put("port_id", + floatingIp.portId() == null ? null : floatingIp + .portId().toString()); + } + if (s.equals("id")) { + result.put("id", floatingIp.id().floatingIpId().toString()); + } + if (s.equals("fixed_ip_address")) { + result.put("fixed_ip_address", + floatingIp.fixedIp() == null ? null : floatingIp + .fixedIp().toString()); + } + if (s.equals("floating_ip_address")) { + result.put("floating_ip_address", floatingIp.floatingIp() + .toString()); + } + if (s.equals("status")) { + result.put("status", floatingIp.status().toString()); + } + } + return result; + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/RouterCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/RouterCodec.java new file mode 100644 index 00000000..61f7e955 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/RouterCodec.java @@ -0,0 +1,91 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.web; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Iterator; +import java.util.List; + +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.vtnrsc.Router; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Router JSON codec. + */ +public class RouterCodec extends JsonCodec { + @Override + public ObjectNode encode(Router router, CodecContext context) { + checkNotNull(router, "router cannot be null"); + ObjectNode result = context + .mapper() + .createObjectNode() + .put("id", router.id().routerId()) + .put("status", router.status().toString()) + .put("name", router.name().toString()) + .put("admin_state_up", router.adminStateUp()) + .put("tenant_id", router.tenantId().toString()) + .put("routes", + router.routes() == null ? null : router.routes() + .toString()); + result.set("external_gateway_info", + router.externalGatewayInfo() == null ? null + : new RouterGatewayInfoCodec() + .encode(router.externalGatewayInfo(), context)); + + return result; + } + + public ObjectNode extracFields(Router router, CodecContext context, + List fields) { + checkNotNull(router, "router cannot be null"); + ObjectNode result = context.mapper().createObjectNode(); + Iterator i = fields.iterator(); + while (i.hasNext()) { + String s = i.next(); + if (s.equals("id")) { + result.put("id", router.id().routerId()); + } + if (s.equals("status")) { + result.put("status", router.status().toString()); + } + if (s.equals("name")) { + result.put("name", router.name().toString()); + } + if (s.equals("admin_state_up")) { + result.put("admin_state_up", router.adminStateUp()); + } + if (s.equals("tenant_id")) { + result.put("tenant_id", router.tenantId().toString()); + } + if (s.equals("routes")) { + result.put("routes", router.routes() == null ? null : router + .routes().toString()); + } + if (s.equals("external_gateway_info")) { + result.set("external_gateway_info", + router.externalGatewayInfo() == null ? null + : new RouterGatewayInfoCodec() + .encode(router.externalGatewayInfo(), + context)); + } + } + return result; + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/RouterGatewayInfoCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/RouterGatewayInfoCodec.java new file mode 100644 index 00000000..cb9fb67d --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/RouterGatewayInfoCodec.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.web; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.vtnrsc.RouterGateway; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Subnet Router Gateway Info codec. + */ +public class RouterGatewayInfoCodec extends JsonCodec { + @Override + public ObjectNode encode(RouterGateway routerGateway, CodecContext context) { + checkNotNull(routerGateway, "routerGateway cannot be null"); + ObjectNode result = context.mapper().createObjectNode() + .put("network_id", routerGateway.networkId().toString()); + result.set("external_fixed_ips", new FixedIpCodec() + .encode(routerGateway.externalFixedIps(), context)); + return result; + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/vtn/vtnweb/src/main/webapp/WEB-INF/web.xml index 97337960..13b377bf 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/main/webapp/WEB-INF/web.xml +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/webapp/WEB-INF/web.xml @@ -37,6 +37,8 @@ org.onosproject.vtnweb.resources.PortChainWebResource org.onosproject.vtnweb.resources.PortPairGroupWebResource org.onosproject.vtnweb.resources.PortPairWebResource + org.onosproject.vtnweb.resources.FloatingIpWebResource + org.onosproject.vtnweb.resources.RouterWebResource 1 diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java new file mode 100644 index 00000000..be645be0 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java @@ -0,0 +1,296 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.resources; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import javax.ws.rs.core.MediaType; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.osgi.TestServiceDirectory; +import org.onlab.packet.IpPrefix; +import org.onlab.rest.BaseResource; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; + +import com.eclipsesource.json.JsonObject; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.UniformInterfaceException; +import com.sun.jersey.api.client.WebResource; +/** + * Unit tests for flow classifier REST APIs. + */ +public class FlowClassifierResourceTest extends VtnResourceTest { + + final FlowClassifierService flowClassifierService = createMock(FlowClassifierService.class); + + FlowClassifierId flowClassifierId1 = FlowClassifierId.of("4a334cd4-fe9c-4fae-af4b-321c5e2eb051"); + TenantId tenantId1 = TenantId.tenantId("1814726e2d22407b8ca76db5e567dcf1"); + VirtualPortId srcPortId1 = VirtualPortId.portId("dace4513-24fc-4fae-af4b-321c5e2eb3d1"); + VirtualPortId dstPortId1 = VirtualPortId.portId("aef3478a-4a56-2a6e-cd3a-9dee4e2ec345"); + + final MockFlowClassifier flowClassifier1 = new MockFlowClassifier(flowClassifierId1, tenantId1, "flowClassifier1", + "Mock flow classifier", "IPv4", "IP", 1001, 1500, + 5001, 6000, IpPrefix.valueOf("1.1.1.1/16"), + IpPrefix.valueOf("22.12.34.45/16"), + srcPortId1, dstPortId1); + + /** + * Mock class for a flow classifier. + */ + private static class MockFlowClassifier implements FlowClassifier { + + private final FlowClassifierId flowClassifierId; + private final TenantId tenantId; + private final String name; + private final String description; + private final String etherType; + private final String protocol; + private final int minSrcPortRange; + private final int maxSrcPortRange; + private final int minDstPortRange; + private final int maxDstPortRange; + private final IpPrefix srcIpPrefix; + private final IpPrefix dstIpPrefix; + private final VirtualPortId srcPort; + private final VirtualPortId dstPort; + + public MockFlowClassifier(FlowClassifierId flowClassifierId, TenantId tenantId, String name, + String description, String etherType, String protocol, int minSrcPortRange, + int maxSrcPortRange, int minDstPortRange, int maxDstPortRange, IpPrefix srcIpPrefix, + IpPrefix dstIpPrefix, VirtualPortId srcPort, VirtualPortId dstPort) { + this.flowClassifierId = flowClassifierId; + this.tenantId = tenantId; + this.name = name; + this.description = description; + this.etherType = etherType; + this.protocol = protocol; + this.minSrcPortRange = minSrcPortRange; + this.maxSrcPortRange = maxSrcPortRange; + this.minDstPortRange = minDstPortRange; + this.maxDstPortRange = maxDstPortRange; + this.srcIpPrefix = srcIpPrefix; + this.dstIpPrefix = dstIpPrefix; + this.srcPort = srcPort; + this.dstPort = dstPort; + } + + + @Override + public FlowClassifierId flowClassifierId() { + return flowClassifierId; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public String name() { + return name; + } + + @Override + public String description() { + return description; + } + + @Override + public String etherType() { + return etherType; + } + + @Override + public String protocol() { + return protocol; + } + + @Override + public int minSrcPortRange() { + return minSrcPortRange; + } + + @Override + public int maxSrcPortRange() { + return maxSrcPortRange; + } + + @Override + public int minDstPortRange() { + return minDstPortRange; + } + + @Override + public int maxDstPortRange() { + return maxDstPortRange; + } + + @Override + public IpPrefix srcIpPrefix() { + return srcIpPrefix; + } + + @Override + public IpPrefix dstIpPrefix() { + return dstIpPrefix; + } + + @Override + public VirtualPortId srcPort() { + return srcPort; + } + + @Override + public VirtualPortId dstPort() { + return dstPort; + } + + @Override + public boolean exactMatch(FlowClassifier flowClassifier) { + return this.equals(flowClassifier) && + Objects.equals(this.flowClassifierId, flowClassifier.flowClassifierId()) && + Objects.equals(this.tenantId, flowClassifier.tenantId()); + } + } + + /** + * Sets up the global values for all the tests. + */ + @Before + public void setUpTest() { + ServiceDirectory testDirectory = new TestServiceDirectory().add(FlowClassifierService.class, + flowClassifierService); + BaseResource.setServiceDirectory(testDirectory); + + } + + /** + * Cleans up. + */ + @After + public void tearDownTest() { + } + + /** + * Tests the result of the rest api GET when there are no flow classifiers. + */ + @Test + public void testFlowClassifiersEmpty() { + + expect(flowClassifierService.getFlowClassifiers()).andReturn(null).anyTimes(); + replay(flowClassifierService); + final WebResource rs = resource(); + final String response = rs.path("flow_classifiers").get(String.class); + assertThat(response, is("{\"flow_classifiers\":[]}")); + } + + /** + * Tests the result of a rest api GET for flow classifier id. + */ + @Test + public void testGetFlowClassifierId() { + + final Set flowClassifiers = new HashSet<>(); + flowClassifiers.add(flowClassifier1); + + expect(flowClassifierService.exists(anyObject())).andReturn(true).anyTimes(); + expect(flowClassifierService.getFlowClassifier(anyObject())).andReturn(flowClassifier1).anyTimes(); + replay(flowClassifierService); + + final WebResource rs = resource(); + final String response = rs.path("flow_classifiers/4a334cd4-fe9c-4fae-af4b-321c5e2eb051").get(String.class); + final JsonObject result = JsonObject.readFrom(response); + assertThat(result, notNullValue()); + } + + /** + * Tests that a fetch of a non-existent flow classifier object throws an exception. + */ + @Test + public void testBadGet() { + expect(flowClassifierService.getFlowClassifier(anyObject())) + .andReturn(null).anyTimes(); + replay(flowClassifierService); + WebResource rs = resource(); + try { + rs.path("flow_classifiers/78dcd363-fc23-aeb6-f44b-56dc5aafb3ae").get(String.class); + fail("Fetch of non-existent flow classifier did not throw an exception"); + } catch (UniformInterfaceException ex) { + assertThat(ex.getMessage(), + containsString("returned a response status of")); + } + } + + /** + * Tests creating a flow classifier with POST. + */ + @Test + public void testPost() { + + expect(flowClassifierService.createFlowClassifier(anyObject())) + .andReturn(true).anyTimes(); + replay(flowClassifierService); + + WebResource rs = resource(); + InputStream jsonStream = FlowClassifierResourceTest.class.getResourceAsStream("post-FlowClassifier.json"); + + ClientResponse response = rs.path("flow_classifiers") + .type(MediaType.APPLICATION_JSON_TYPE) + .post(ClientResponse.class, jsonStream); + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK)); + } + + /** + * Tests deleting a flow classifier. + */ + @Test + public void testDelete() { + expect(flowClassifierService.removeFlowClassifier(anyObject())) + .andReturn(true).anyTimes(); + replay(flowClassifierService); + + WebResource rs = resource(); + + String location = "flow_classifiers/4a334cd4-fe9c-4fae-af4b-321c5e2eb051"; + + ClientResponse deleteResponse = rs.path(location) + .type(MediaType.APPLICATION_JSON_TYPE) + .delete(ClientResponse.class); + assertThat(deleteResponse.getStatus(), + is(HttpURLConnection.HTTP_NO_CONTENT)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java new file mode 100644 index 00000000..271904cc --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java @@ -0,0 +1,232 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.resources; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import javax.ws.rs.core.MediaType; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.osgi.TestServiceDirectory; +import org.onlab.rest.BaseResource; +import org.onosproject.vtnrsc.PortPair; +import org.onosproject.vtnrsc.PortPairId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.portpair.PortPairService; + +import com.eclipsesource.json.JsonObject; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.UniformInterfaceException; +import com.sun.jersey.api.client.WebResource; +/** + * Unit tests for port pair REST APIs. + */ +public class PortPairResourceTest extends VtnResourceTest { + + final PortPairService portPairService = createMock(PortPairService.class); + + PortPairId portPairId1 = PortPairId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + TenantId tenantId1 = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5"); + + final MockPortPair portPair1 = new MockPortPair(portPairId1, tenantId1, "portPair1", + "Mock port pair", "dace4513-24fc-4fae-af4b-321c5e2eb3d1", + "aef3478a-4a56-2a6e-cd3a-9dee4e2ec345"); + + /** + * Mock class for a port pair. + */ + private static class MockPortPair implements PortPair { + + private final PortPairId portPairId; + private final TenantId tenantId; + private final String name; + private final String description; + private final String ingress; + private final String egress; + + public MockPortPair(PortPairId portPairId, TenantId tenantId, + String name, String description, + String ingress, String egress) { + + this.portPairId = portPairId; + this.tenantId = tenantId; + this.name = name; + this.description = description; + this.ingress = ingress; + this.egress = egress; + } + + @Override + public PortPairId portPairId() { + return portPairId; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public String name() { + return name; + } + + @Override + public String description() { + return description; + } + + @Override + public String ingress() { + return ingress; + } + + @Override + public String egress() { + return egress; + } + + @Override + public boolean exactMatch(PortPair portPair) { + return this.equals(portPair) && + Objects.equals(this.portPairId, portPair.portPairId()) && + Objects.equals(this.tenantId, portPair.tenantId()); + } + } + + /** + * Sets up the global values for all the tests. + */ + @Before + public void setUpTest() { + ServiceDirectory testDirectory = new TestServiceDirectory().add(PortPairService.class, portPairService); + BaseResource.setServiceDirectory(testDirectory); + + } + + /** + * Cleans up. + */ + @After + public void tearDownTest() { + } + + /** + * Tests the result of the rest api GET when there are no port pairs. + */ + @Test + public void testPortPairsEmpty() { + + expect(portPairService.getPortPairs()).andReturn(null).anyTimes(); + replay(portPairService); + final WebResource rs = resource(); + final String response = rs.path("port_pairs").get(String.class); + assertThat(response, is("{\"port_pairs\":[]}")); + } + + /** + * Tests the result of a rest api GET for port pair id. + */ + @Test + public void testGetPortPairId() { + + final Set portPairs = new HashSet<>(); + portPairs.add(portPair1); + + expect(portPairService.exists(anyObject())).andReturn(true).anyTimes(); + expect(portPairService.getPortPair(anyObject())).andReturn(portPair1).anyTimes(); + replay(portPairService); + + final WebResource rs = resource(); + final String response = rs.path("port_pairs/78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae").get(String.class); + final JsonObject result = JsonObject.readFrom(response); + assertThat(result, notNullValue()); + } + + /** + * Tests that a fetch of a non-existent port pair object throws an exception. + */ + @Test + public void testBadGet() { + expect(portPairService.getPortPair(anyObject())) + .andReturn(null).anyTimes(); + replay(portPairService); + WebResource rs = resource(); + try { + rs.path("port_pairs/78dcd363-fc23-aeb6-f44b-56dc5aafb3ae").get(String.class); + fail("Fetch of non-existent port pair did not throw an exception"); + } catch (UniformInterfaceException ex) { + assertThat(ex.getMessage(), + containsString("returned a response status of")); + } + } + + /** + * Tests creating a port pair with POST. + */ + @Test + public void testPost() { + + expect(portPairService.createPortPair(anyObject())) + .andReturn(true).anyTimes(); + replay(portPairService); + + WebResource rs = resource(); + InputStream jsonStream = PortPairResourceTest.class.getResourceAsStream("post-PortPair.json"); + + ClientResponse response = rs.path("port_pairs") + .type(MediaType.APPLICATION_JSON_TYPE) + .post(ClientResponse.class, jsonStream); + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK)); + } + + /** + * Tests deleting a port pair. + */ + @Test + public void testDelete() { + expect(portPairService.removePortPair(anyObject())) + .andReturn(true).anyTimes(); + replay(portPairService); + + WebResource rs = resource(); + + String location = "port_pairs/78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"; + + ClientResponse deleteResponse = rs.path(location) + .type(MediaType.APPLICATION_JSON_TYPE) + .delete(ClientResponse.class); + assertThat(deleteResponse.getStatus(), + is(HttpURLConnection.HTTP_NO_CONTENT)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/VtnResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/VtnResourceTest.java new file mode 100644 index 00000000..4b95844d --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/VtnResourceTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.resources; + +import java.io.IOException; +import java.net.ServerSocket; + +import com.sun.jersey.test.framework.AppDescriptor; +import com.sun.jersey.test.framework.JerseyTest; +import com.sun.jersey.test.framework.WebAppDescriptor; + +/** + * Base class for VTN REST API tests. Performs common configuration operations. + */ +public class VtnResourceTest extends JerseyTest { + + /** + * Assigns an available port for the test. + * + * @param defaultPort If a port cannot be determined, this one is used. + * @return free port + */ + @Override + public int getPort(int defaultPort) { + try { + ServerSocket socket = new ServerSocket(0); + socket.setReuseAddress(true); + int port = socket.getLocalPort(); + socket.close(); + return port; + } catch (IOException ioe) { + return defaultPort; + } + } + + @Override + public AppDescriptor configure() { + return new WebAppDescriptor.Builder("org.onosproject.vtnweb.resources").build(); + } + +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/FlowClassifierCodecTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/FlowClassifierCodecTest.java new file mode 100644 index 00000000..be36aa83 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/FlowClassifierCodecTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.web; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Before; +import org.junit.Test; +import org.onosproject.codec.JsonCodec; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.TenantId; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Flow classifier codec unit tests. + */ +public class FlowClassifierCodecTest { + + SfcCodecContext context; + JsonCodec flowClassifierCodec; + /** + * Sets up for each test. Creates a context and fetches the flow classifier + * codec. + */ + @Before + public void setUp() { + context = new SfcCodecContext(); + flowClassifierCodec = context.codec(FlowClassifier.class); + assertThat(flowClassifierCodec, notNullValue()); + } + + /** + * Reads in a flow classifier from the given resource and decodes it. + * + * @param resourceName resource to use to read the JSON for the flow classifier + * @return decoded flow classifier + * @throws IOException if processing the resource fails + */ + private FlowClassifier getFlowClassifier(String resourceName) throws IOException { + InputStream jsonStream = FlowClassifierCodecTest.class + .getResourceAsStream(resourceName); + ObjectMapper mapper = new ObjectMapper(); + JsonNode json = mapper.readTree(jsonStream); + assertThat(json, notNullValue()); + FlowClassifier flowClassifier = flowClassifierCodec.decode((ObjectNode) json, context); + assertThat(flowClassifier, notNullValue()); + return flowClassifier; + } + + /** + * Checks that a simple flow classifier decodes properly. + * + * @throws IOException if the resource cannot be processed + */ + @Test + public void codecFlowClassifierTest() throws IOException { + + FlowClassifier flowClassifier = getFlowClassifier("flowClassifier.json"); + + assertThat(flowClassifier, notNullValue()); + + FlowClassifierId flowClassifierId = FlowClassifierId.of("4a334cd4-fe9c-4fae-af4b-321c5e2eb051"); + TenantId tenantId = TenantId.tenantId("1814726e2d22407b8ca76db5e567dcf1"); + + assertThat(flowClassifier.flowClassifierId().toString(), is(flowClassifierId.toString())); + assertThat(flowClassifier.name(), is("flow1")); + assertThat(flowClassifier.tenantId().toString(), is(tenantId.toString())); + assertThat(flowClassifier.description(), is("flow classifier")); + assertThat(flowClassifier.protocol(), is("tcp")); + assertThat(flowClassifier.minSrcPortRange(), is(22)); + assertThat(flowClassifier.maxSrcPortRange(), is(4000)); + assertThat(flowClassifier.minDstPortRange(), is(80)); + assertThat(flowClassifier.maxDstPortRange(), is(80)); + + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-FlowClassifier.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-FlowClassifier.json new file mode 100644 index 00000000..6e72e8fd --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-FlowClassifier.json @@ -0,0 +1,14 @@ +{"flow_classifier": { + "id": "4a334cd4-fe9c-4fae-af4b-321c5e2eb051", + "name": "flow1", + "tenant_id": "1814726e2d22407b8ca76db5e567dcf1", + "description": "flow classifier", + "ethertype": "IPv4", + "protocol": "tcp", + "source_port_range_min": 22, "source_port_range_max": 4000, + "destination_port_range_min": 80, "destination_port_range_max": 80, + "source_ip_prefix": "1.1.1.1/16" , "destination_ip_prefix": "22.12.34.45/16", + "logical_destination_port": "dace4513-24fc-4fae-af4b-321c5e2eb3d1", + "logical_source_port": "aef3478a-4a56-2a6e-cd3a-9dee4e2ec345" + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPair.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPair.json new file mode 100644 index 00000000..2a774e31 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPair.json @@ -0,0 +1,9 @@ +{"port_pair": { + "id": "78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae", + "name": "PP1", + "tenant_id": "d382007aa9904763a801f68ecf065cf5", + "description": "SF-A", + "ingress": "dace4513-24fc-4fae-af4b-321c5e2eb3d1", + "egress": "aef3478a-4a56-2a6e-cd3a-9dee4e2ec345" + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/flowClassifier.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/flowClassifier.json new file mode 100644 index 00000000..0fc0b74e --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/flowClassifier.json @@ -0,0 +1,11 @@ +{ + "id": "4a334cd4-fe9c-4fae-af4b-321c5e2eb051", + "name": "flow1", + "tenant_id": "1814726e2d22407b8ca76db5e567dcf1", + "description": "flow classifier", + "ethertype": "IPv4", + "protocol": "tcp", + "source_port_range_min": 22, "source_port_range_max": 4000, + "destination_port_range_min": 80, "destination_port_range_max": 80, + "source_ip_prefix": "1.1.1.1/16" , "destination_ip_prefix": "22.12.34.45/16" + } diff --git a/framework/src/onos/apps/xos-integration/features.xml b/framework/src/onos/apps/xos-integration/features.xml index a7b14569..6b08b637 100644 --- a/framework/src/onos/apps/xos-integration/features.xml +++ b/framework/src/onos/apps/xos-integration/features.xml @@ -15,7 +15,6 @@ ~ limitations under the License. --> - mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features mvn:com.sun.jersey/jersey-client/1.19 diff --git a/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/OnosXosIntegrationManager.java b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/OnosXosIntegrationManager.java new file mode 100644 index 00000000..32f2a680 --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/OnosXosIntegrationManager.java @@ -0,0 +1,545 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.xosintegration; + +import com.eclipsesource.json.JsonArray; +import com.eclipsesource.json.JsonObject; +import com.google.common.collect.Maps; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientHandlerException; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Modified; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.VlanId; +import org.onlab.util.Tools; +import org.onosproject.cfg.ComponentConfigService; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; + +import java.util.Dictionary; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static com.google.common.base.Strings.isNullOrEmpty; +import static com.google.common.net.MediaType.JSON_UTF_8; +import static java.net.HttpURLConnection.HTTP_CREATED; +import static java.net.HttpURLConnection.HTTP_NO_CONTENT; +import static java.net.HttpURLConnection.HTTP_OK; +import static org.slf4j.LoggerFactory.getLogger; + + +/** + * XOS interface application. + */ +@Component(immediate = true) +@Service +public class OnosXosIntegrationManager implements VoltTenantService { + private static final String XOS_SERVER_ADDRESS_PROPERTY_NAME = + "xosServerAddress"; + private static final String XOS_SERVER_PORT_PROPERTY_NAME = + "xosServerPort"; + private static final String XOS_PROVIDER_SERVICE_PROPERTY_NAME = + "xosProviderService"; + + private static final String TEST_XOS_SERVER_ADDRESS = "10.254.1.22"; + private static final int TEST_XOS_SERVER_PORT = 8000; + private static final String XOS_TENANT_BASE_URI = "/xoslib/volttenant/"; + private static final int TEST_XOS_PROVIDER_SERVICE = 1; + + private static final int PRIORITY = 50000; + private static final DeviceId FABRIC_DEVICE_ID = DeviceId.deviceId("of:5e3e486e73000187"); + private static final PortNumber FABRIC_OLT_CONNECT_POINT = PortNumber.portNumber(2); + private static final PortNumber FABRIC_VCPE_CONNECT_POINT = PortNumber.portNumber(3); + private static final String FABRIC_CONTROLLER_ADDRESS = "10.0.3.136"; + private static final int FABRIC_SERVER_PORT = 8181; + private static final String FABRIC_BASE_URI = "/onos/cordfabric/vlans/add"; + + private static final DeviceId OLT_DEVICE_ID = DeviceId.deviceId("of:90e2ba82f97791e9"); + private static final int OLT_UPLINK_PORT = 129; + + private static final ConnectPoint FABRIC_PORT = new ConnectPoint( + DeviceId.deviceId("of:000090e2ba82f974"), + PortNumber.portNumber(2)); + + private final Logger log = getLogger(getClass()); + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ComponentConfigService cfgService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FlowObjectiveService flowObjectiveService; + + @Property(name = XOS_SERVER_ADDRESS_PROPERTY_NAME, + value = TEST_XOS_SERVER_ADDRESS, + label = "XOS Server address") + protected String xosServerAddress = TEST_XOS_SERVER_ADDRESS; + + @Property(name = XOS_SERVER_PORT_PROPERTY_NAME, + intValue = TEST_XOS_SERVER_PORT, + label = "XOS Server port") + protected int xosServerPort = TEST_XOS_SERVER_PORT; + + @Property(name = XOS_PROVIDER_SERVICE_PROPERTY_NAME, + intValue = TEST_XOS_PROVIDER_SERVICE, + label = "XOS Provider Service") + protected int xosProviderService = TEST_XOS_PROVIDER_SERVICE; + + private ApplicationId appId; + private Map nodeToPort; + private Map portToVlan; + private Map portToSsid; + + @Activate + public void activate(ComponentContext context) { + log.info("XOS app is starting"); + cfgService.registerProperties(getClass()); + appId = coreService.registerApplication("org.onosproject.xosintegration"); + + setupMap(); + + readComponentConfiguration(context); + + log.info("XOS({}) started", appId.id()); + } + + @Deactivate + public void deactivate() { + cfgService.unregisterProperties(getClass(), false); + log.info("XOS({}) stopped", appId.id()); + } + + @Modified + public void modified(ComponentContext context) { + readComponentConfiguration(context); + } + + private void setupMap() { + nodeToPort = Maps.newHashMap(); + + nodeToPort.put("cordcompute01.onlab.us", new ConnectPoint(FABRIC_DEVICE_ID, + PortNumber.portNumber(4))); + + nodeToPort.put("cordcompute02.onlab.us", new ConnectPoint(FABRIC_DEVICE_ID, + PortNumber.portNumber(3))); + + portToVlan = Maps.newHashMap(); + portToVlan.putIfAbsent(1L, (short) 201); + portToVlan.putIfAbsent(6L, (short) 401); + + portToSsid = Maps.newHashMap(); + portToSsid.put(new ConnectPoint(OLT_DEVICE_ID, PortNumber.portNumber(1)), "0"); + portToSsid.put(new ConnectPoint(FABRIC_DEVICE_ID, PortNumber.portNumber(6)), "1"); + } + + /** + * Converts a JSON representation of a tenant into a tenant object. + * + * @param jsonTenant JSON object representing the tenant + * @return volt tenant object + */ + private VoltTenant jsonToTenant(JsonObject jsonTenant) { + return VoltTenant.builder() + .withHumanReadableName(jsonTenant.get("humanReadableName").asString()) + .withId(jsonTenant.get("id").asInt()) + .withProviderService(jsonTenant.get("provider_service").asInt()) + .withServiceSpecificId(jsonTenant.get("service_specific_id").asString()) + .withVlanId(jsonTenant.get("vlan_id").asString()) + .build(); + } + + /** + * Converts a tenant object into a JSON string. + * + * @param tenant volt tenant object to convert + * @return JSON string for the tenant + */ + private String tenantToJson(VoltTenant tenant) { + return "{" + + "\"humanReadableName\": \"" + tenant.humanReadableName() + "\"," + + "\"id\": \"" + tenant.id() + "\"," + + "\"provider_service\": \"" + tenant.providerService() + "\"," + + "\"service_specific_id\": \"" + tenant.serviceSpecificId() + "\"," + + "\"vlan_id\": \"" + tenant.vlanId() + "\"" + + "}"; + } + + /** + * Gets a client web resource builder for the base XOS REST API + * with no additional URI. + * + * @return web resource builder + * @deprecated in Cardinal Release + */ + @Deprecated + private WebResource.Builder getClientBuilder() { + return getClientBuilder(""); + } + + /** + * Gets a client web resource builder for the base XOS REST API + * with an optional additional URI. + * + * @return web resource builder + * @deprecated in Cardinal Release + */ + @Deprecated + private WebResource.Builder getClientBuilder(String uri) { + String baseUrl = "http://" + xosServerAddress + ":" + + Integer.toString(xosServerPort); + Client client = Client.create(); + client.addFilter(new HTTPBasicAuthFilter("padmin@vicci.org", "letmein")); + WebResource resource = client.resource(baseUrl + + XOS_TENANT_BASE_URI + uri); + return resource.accept(JSON_UTF_8.toString()) + .type(JSON_UTF_8.toString()); + } + + /** + * Performs a REST GET operation on the base XOS REST URI. + * + * @return JSON string fetched by the GET operation + * @deprecated in Cardinal Release + */ + @Deprecated + private String getRest() { + return getRest(""); + } + + /** + * Performs a REST GET operation on the base XOS REST URI with + * an optional additional URI. + * + * @return JSON string fetched by the GET operation + * @deprecated in Cardinal Release + */ + @Deprecated + private String getRest(String uri) { + WebResource.Builder builder = getClientBuilder(uri); + ClientResponse response = builder.get(ClientResponse.class); + + if (response.getStatus() != HTTP_OK) { + log.info("REST GET request returned error code {}", + response.getStatus()); + } + String jsonString = response.getEntity(String.class); + log.info("JSON read:\n{}", jsonString); + + return jsonString; + } + + /** + * Performs a REST POST operation of a json string on the base + * XOS REST URI with an optional additional URI. + * + * @param json JSON string to post + * @deprecated in Cardinal Release + */ + @Deprecated + private String postRest(String json) { + WebResource.Builder builder = getClientBuilder(); + ClientResponse response; + + try { + response = builder.post(ClientResponse.class, json); + } catch (ClientHandlerException e) { + log.warn("Unable to contact REST server: {}", e.getMessage()); + return "{ 'error' : 'oops no one home' }"; + } + + if (response.getStatus() != HTTP_CREATED) { + log.info("REST POST request returned error code {}", + response.getStatus()); + } + return response.getEntity(String.class); + } + + /** + * Performs a REST DELETE operation on the base + * XOS REST URI with an optional additional URI. + * + * @param uri optional additional URI + * @deprecated in Cardinal Release + */ + @Deprecated + private void deleteRest(String uri) { + WebResource.Builder builder = getClientBuilder(uri); + ClientResponse response = builder.delete(ClientResponse.class); + + if (response.getStatus() != HTTP_NO_CONTENT) { + log.info("REST DELETE request returned error code {}", + response.getStatus()); + } + } + + /** + * Deletes the tenant with the given ID. + * + * @param tenantId ID of tenant to delete + */ + private void deleteTenant(long tenantId) { + deleteRest(Long.toString(tenantId)); + } + + @Override + public Set getAllTenants() { + String jsonString = getRest(); + + JsonArray voltTenantItems = JsonArray.readFrom(jsonString); + + return IntStream.range(0, voltTenantItems.size()) + .mapToObj(index -> jsonToTenant(voltTenantItems.get(index).asObject())) + .collect(Collectors.toSet()); + } + + @Override + public void removeTenant(long id) { + deleteTenant(id); + } + + @Override + public VoltTenant addTenant(VoltTenant newTenant) { + long providerServiceId = newTenant.providerService(); + if (providerServiceId == -1) { + providerServiceId = xosProviderService; + } + + PortNumber onuPort = newTenant.port().port(); + VlanId subscriberVlan = VlanId.vlanId(portToVlan.get(onuPort.toLong())); + + VoltTenant tenantToCreate = VoltTenant.builder() + .withProviderService(providerServiceId) + .withServiceSpecificId(portToSsid.get(newTenant.port())) + .withVlanId(String.valueOf(subscriberVlan.toShort())) + .withPort(newTenant.port()) + .build(); + String json = tenantToJson(tenantToCreate); + + + provisionVlanOnPort(OLT_DEVICE_ID, OLT_UPLINK_PORT, onuPort, subscriberVlan.toShort()); + + String retJson = postRest(json); + + fetchCpeLocation(tenantToCreate, retJson); + + return newTenant; + } + + private void fetchCpeLocation(VoltTenant newTenant, String jsonString) { + JsonObject json = JsonObject.readFrom(jsonString); + + if (json.get("computeNodeName") != null) { + ConnectPoint point = nodeToPort.get(json.get("computeNodeName").asString()); + //ConnectPoint fromPoint = newTenant.port(); + ConnectPoint oltPort = new ConnectPoint(FABRIC_DEVICE_ID, FABRIC_OLT_CONNECT_POINT); + + provisionFabric(VlanId.vlanId(Short.parseShort(newTenant.vlanId())), + point, oltPort); + } + + } + + @Override + public VoltTenant getTenant(long id) { + String jsonString = getRest(Long.toString(id)); + JsonObject jsonTenant = JsonObject.readFrom(jsonString); + if (jsonTenant.get("id") != null) { + return jsonToTenant(jsonTenant); + } else { + return null; + } + } + + private void provisionVlanOnPort(DeviceId deviceId, int uplinkPort, PortNumber p, short vlanId) { + + TrafficSelector upstream = DefaultTrafficSelector.builder() + .matchVlanId(VlanId.ANY) + .matchInPort(p) + .build(); + + TrafficSelector downstream = DefaultTrafficSelector.builder() + .matchVlanId(VlanId.vlanId(vlanId)) + .matchInPort(PortNumber.portNumber(uplinkPort)) + .build(); + + TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder() + .setVlanId(VlanId.vlanId(vlanId)) + .setOutput(PortNumber.portNumber(uplinkPort)) + .build(); + + TrafficTreatment downstreamTreatment = DefaultTrafficTreatment.builder() + .popVlan() + .setOutput(p) + .build(); + + + ForwardingObjective upFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(upstream) + .fromApp(appId) + .withTreatment(upstreamTreatment) + .add(); + + ForwardingObjective downFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(downstream) + .fromApp(appId) + .withTreatment(downstreamTreatment) + .add(); + + flowObjectiveService.forward(deviceId, upFwd); + flowObjectiveService.forward(deviceId, downFwd); + + } + + private void provisionDataPlane(VoltTenant tenant) { + VlanId vlan = VlanId.vlanId(Short.parseShort(tenant.vlanId())); + + TrafficSelector fromGateway = DefaultTrafficSelector.builder() + .matchInPhyPort(tenant.port().port()) + .build(); + + TrafficSelector fromFabric = DefaultTrafficSelector.builder() + .matchInPhyPort(FABRIC_PORT.port()) + .matchVlanId(vlan) + .build(); + + TrafficTreatment toFabric = DefaultTrafficTreatment.builder() + .pushVlan() + .setVlanId(vlan) + .setOutput(FABRIC_PORT.port()) + .build(); + + TrafficTreatment toGateway = DefaultTrafficTreatment.builder() + .popVlan() + .setOutput(tenant.port().port()) + .build(); + + ForwardingObjective forwardToFabric = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .makePermanent() + .fromApp(appId) + .withSelector(fromGateway) + .withTreatment(toFabric) + .add(); + + ForwardingObjective forwardToGateway = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .makePermanent() + .fromApp(appId) + .withSelector(fromFabric) + .withTreatment(toGateway) + .add(); + + flowObjectiveService.forward(FABRIC_PORT.deviceId(), forwardToFabric); + flowObjectiveService.forward(FABRIC_PORT.deviceId(), forwardToGateway); + } + + private void provisionFabric(VlanId vlanId, ConnectPoint point, ConnectPoint fromPoint) { + + long vlan = vlanId.toShort(); + + JsonObject node = new JsonObject(); + node.add("vlan", vlan); + if (vlan == 201) { + node.add("iptv", true); + } else { + node.add("iptv", false); + } + JsonArray array = new JsonArray(); + JsonObject cp1 = new JsonObject(); + JsonObject cp2 = new JsonObject(); + cp1.add("device", point.deviceId().toString()); + cp1.add("port", point.port().toLong()); + cp2.add("device", fromPoint.deviceId().toString()); + cp2.add("port", fromPoint.port().toLong()); + array.add(cp1); + array.add(cp2); + node.add("ports", array); + + + String baseUrl = "http://" + FABRIC_CONTROLLER_ADDRESS + ":" + + Integer.toString(FABRIC_SERVER_PORT); + Client client = Client.create(); + WebResource resource = client.resource(baseUrl + FABRIC_BASE_URI); + WebResource.Builder builder = resource.accept(JSON_UTF_8.toString()) + .type(JSON_UTF_8.toString()); + + try { + builder.post(ClientResponse.class, node.toString()); + } catch (ClientHandlerException e) { + log.warn("Unable to contact fabric REST server: {}", e.getMessage()); + return; + } + } + + /** + * Extracts properties from the component configuration context. + * + * @param context the component context + */ + private void readComponentConfiguration(ComponentContext context) { + Dictionary properties = context.getProperties(); + + String newXosServerAddress = + Tools.get(properties, XOS_SERVER_ADDRESS_PROPERTY_NAME); + if (!isNullOrEmpty(newXosServerAddress)) { + xosServerAddress = newXosServerAddress; + } + + String newXosServerPortString = + Tools.get(properties, XOS_SERVER_PORT_PROPERTY_NAME); + if (!isNullOrEmpty(newXosServerPortString)) { + xosServerPort = Integer.parseInt(newXosServerPortString); + } + + String newXosProviderServiceString = + Tools.get(properties, XOS_PROVIDER_SERVICE_PROPERTY_NAME); + if (!isNullOrEmpty(newXosProviderServiceString)) { + xosProviderService = Integer.parseInt(newXosProviderServiceString); + } + } +} + + diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPCfg.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java similarity index 96% rename from framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPCfg.java rename to framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java index 46165d87..6f64d2bb 100755 --- a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPCfg.java +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpCfg.java @@ -20,7 +20,7 @@ import java.util.TreeMap; /** * Abstraction of an BGP configuration. Manages the BGP configuration from CLI to the BGP controller. */ -public interface BGPCfg { +public interface BgpCfg { enum State { /** @@ -233,7 +233,7 @@ public interface BGPCfg { * * @return return the tree map with IP as key and BGPPeerCfg as object */ - TreeMap displayPeers(); + TreeMap displayPeers(); /** * Return the BGP Peer information with this matching IP. @@ -242,7 +242,7 @@ public interface BGPCfg { * * @return BGPPeerCfg object */ - BGPPeerCfg displayPeers(String routerid); + BgpPeerCfg displayPeers(String routerid); /** * Check if this BGP peer is configured. @@ -267,7 +267,7 @@ public interface BGPCfg { * * @return return the tree map with IP as key and BGPPeerCfg as object */ - TreeMap getPeerTree(); + TreeMap getPeerTree(); /** * Set the current connection state information. @@ -275,7 +275,7 @@ public interface BGPCfg { * @param routerid router IP address in string format * @param state state information */ - void setPeerConnState(String routerid, BGPPeerCfg.State state); + void setPeerConnState(String routerid, BgpPeerCfg.State state); /** * Check if the peer can be connected or not. @@ -293,5 +293,5 @@ public interface BGPCfg { * * @return state information */ - BGPPeerCfg.State getPeerConnState(String routerid); + BgpPeerCfg.State getPeerConnState(String routerid); } diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpConnectPeer.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpConnectPeer.java new file mode 100755 index 00000000..8f33ee87 --- /dev/null +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpConnectPeer.java @@ -0,0 +1,28 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.onosproject.bgp.controller; + +/** + * Abstraction of an BGP connect peer, initiate remote connection to BGP peer on configuration. + */ +public interface BgpConnectPeer { + /** + * Initiate bgp peer connection. + */ + void connectPeer(); + + /** + * End bgp peer connection. + */ + void disconnectPeer(); +} diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java similarity index 73% rename from framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java rename to framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java index 9d44041e..cc87eb32 100755 --- a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPController.java +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java @@ -19,21 +19,21 @@ package org.onosproject.bgp.controller; import java.util.Map; import java.util.Set; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPMessage; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpMessage; /** * Abstraction of an BGP controller. Serves as a one stop shop for obtaining BGP devices and (un)register listeners on * bgp events */ -public interface BGPController { +public interface BgpController { /** * Returns list of bgp peers connected to this BGP controller. * * @return Iterable of BGPPeer elements */ - Iterable getPeers(); + Iterable getPeers(); /** * Returns the actual bgp peer for the given ip address. @@ -41,7 +41,7 @@ public interface BGPController { * @param bgpId the id of the bgp peer to fetch * @return the interface to this bgp peer */ - BGPPeer getPeer(BGPId bgpId); + BgpPeer getPeer(BgpId bgpId); /** * Register a listener for BGP message events. @@ -57,36 +57,22 @@ public interface BGPController { */ void removeListener(BgpNodeListener listener); - /** - * Register a listener for BGP message events. - * - * @param listener the listener to notify - */ - void addLinkListener(BgpLinkListener listener); - - /** - * Unregister a listener. - * - * @param listener the listener to unregister - */ - void removeLinkListener(BgpLinkListener listener); - /** * Send a message to a particular bgp peer. * * @param bgpId the id of the peer to send message. * @param msg the message to send */ - void writeMsg(BGPId bgpId, BGPMessage msg); + void writeMsg(BgpId bgpId, BgpMessage msg); /** * Process a message and notify the appropriate listeners. * * @param bgpId id of the peer the message arrived on * @param msg the message to process. - * @throws BGPParseException on data processing error + * @throws BgpParseException on data processing error */ - void processBGPPacket(BGPId bgpId, BGPMessage msg) throws BGPParseException; + void processBGPPacket(BgpId bgpId, BgpMessage msg) throws BgpParseException; /** * Close all connected BGP peers. @@ -99,7 +85,7 @@ public interface BGPController { * * @return configuration object */ - BGPCfg getConfig(); + BgpCfg getConfig(); /** * Get the BGP connected peers to this controller. @@ -120,7 +106,7 @@ public interface BGPController { * * @return connectedPeers connected peers */ - Map connectedPeers(); + Map connectedPeers(); /** * Return BGP node listener. @@ -128,11 +114,4 @@ public interface BGPController { * @return node listener */ Set listener(); - - /** - * Return BGP link listener. - * - * @return link listener - */ - Set linkListener(); } diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpDpid.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpDpid.java new file mode 100755 index 00000000..ed04dc94 --- /dev/null +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpDpid.java @@ -0,0 +1,130 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onosproject.bgp.controller; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The class representing a network bgp device id. This class is immutable. + */ +public final class BgpDpid { + private static final Logger log = LoggerFactory.getLogger(BgpDpid.class); + + private static final String SCHEME = "bgp"; + private static final long UNKNOWN = 0; + private StringBuilder stringBuilder; + public static final int NODE_DESCRIPTOR_LOCAL = 1; + public static final int NODE_DESCRIPTOR_REMOTE = 2; + + /** + * Initialize bgp id to generate URI. + * + * @param linkNlri node Nlri. + * @param nodeDescriptorType node descriptor type, local/remote + */ + public BgpDpid(final BgpLinkLsNlriVer4 linkNlri, int nodeDescriptorType) { + this.stringBuilder = new StringBuilder("bgpls://"); + + if (linkNlri.getRouteDistinguisher() != null) { + this.stringBuilder.append(linkNlri.getRouteDistinguisher().getRouteDistinguisher()).append(':'); + } + + try { + this.stringBuilder.append(linkNlri.getProtocolId()).append(':').append(linkNlri.getIdentifier()) + .append('/'); + + if (nodeDescriptorType == NODE_DESCRIPTOR_LOCAL) { + add(linkNlri.localNodeDescriptors()); + } else if (nodeDescriptorType == NODE_DESCRIPTOR_REMOTE) { + add(linkNlri.remoteNodeDescriptors()); + } + } catch (BgpParseException e) { + log.info("Exception BgpId string: " + e.toString()); + } + + } + + /** + * Initialize bgp id to generate URI. + * + * @param nodeNlri node Nlri. + */ + public BgpDpid(final BgpNodeLSNlriVer4 nodeNlri) { + this.stringBuilder = new StringBuilder("bgpls://"); + + if (nodeNlri.getRouteDistinguisher() != null) { + this.stringBuilder.append(nodeNlri.getRouteDistinguisher().getRouteDistinguisher()).append(':'); + } + + try { + + this.stringBuilder.append(nodeNlri.getProtocolId()).append(':').append(nodeNlri.getIdentifier()) + .append('/'); + + add(nodeNlri.getLocalNodeDescriptors()); + + } catch (BgpParseException e) { + log.info("Exception node string: " + e.toString()); + } + } + + BgpDpid add(final Object value) { + if (value != null) { + this.stringBuilder.append('&').append('=').append(value.toString()); + } + return this; + } + + @Override + public String toString() { + return this.stringBuilder.toString(); + } + + /** + * Produces bgp URI. + * + * @param value string to get URI + * @return bgp URI, otherwise null + */ + public static URI uri(String value) { + try { + return new URI(SCHEME, value, null); + } catch (URISyntaxException e) { + log.info("Exception BgpId URI: " + e.toString()); + } + return null; + } + + /** + * Returns bgpDpid created from the given device URI. + * + * @param uri device URI + * @return object of BgpDpid + */ + public static BgpDpid bgpDpid(URI uri) { + checkArgument(uri.getScheme().equals(SCHEME), "Unsupported URI scheme"); + + // TODO: return BgpDpid generated from uri + return null; + } +} diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPId.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpId.java similarity index 87% rename from framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPId.java rename to framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpId.java index 636e72f3..7a6c625d 100755 --- a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPId.java +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpId.java @@ -27,7 +27,7 @@ import static com.google.common.base.Preconditions.checkArgument; * The class representing a network peer bgp ip. * This class is immutable. */ -public final class BGPId { +public final class BgpId { private static final String SCHEME = "bgp"; private static final long UNKNOWN = 0; @@ -36,7 +36,7 @@ public final class BGPId { /** * Private constructor. */ - private BGPId(IpAddress ipAddress) { + private BgpId(IpAddress ipAddress) { this.ipAddress = ipAddress; } @@ -46,8 +46,8 @@ public final class BGPId { * @param ipAddress IP address * @return object of BGPId */ - public static BGPId bgpId(IpAddress ipAddress) { - return new BGPId(ipAddress); + public static BgpId bgpId(IpAddress ipAddress) { + return new BgpId(ipAddress); } /** @@ -71,11 +71,11 @@ public final class BGPId { @Override public boolean equals(Object other) { - if (!(other instanceof BGPId)) { + if (!(other instanceof BgpId)) { return false; } - BGPId otherBGPid = (BGPId) other; + BgpId otherBGPid = (BgpId) other; return Objects.equals(ipAddress, otherBGPid.ipAddress); } @@ -90,9 +90,9 @@ public final class BGPId { * @param uri device URI * @return object of BGPId */ - public static BGPId bgpId(URI uri) { + public static BgpId bgpId(URI uri) { checkArgument(uri.getScheme().equals(SCHEME), "Unsupported URI scheme"); - return new BGPId(IpAddress.valueOf(uri.getSchemeSpecificPart())); + return new BgpId(IpAddress.valueOf(uri.getSchemeSpecificPart())); } /** @@ -101,7 +101,7 @@ public final class BGPId { * @param bgpId device bgpId * @return device URI */ - public static URI uri(BGPId bgpId) { + public static URI uri(BgpId bgpId) { return uri(bgpId.ipAddress()); } diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpLinkListener.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpLinkListener.java new file mode 100755 index 00000000..8b34e314 --- /dev/null +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpLinkListener.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.onosproject.bgp.controller; + +import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4; + +/** + * Allows for providers interested in Link events to be notified. + */ +public interface BgpLinkListener { + + /** + * Notify that got a packet of link from network and need do processing. + * + * @param linkNlri bgp link + */ + void addLink(BgpLinkLsNlriVer4 linkNlri); + + /** + * Notify that got a packet of link from network and need do processing. + * + * @param linkNlri bgp link + */ + void deleteLink(BgpLinkLsNlriVer4 linkNlri); +} diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpLocalRib.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpLocalRib.java new file mode 100755 index 00000000..636c1c85 --- /dev/null +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpLocalRib.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onosproject.bgp.controller; + +import org.onosproject.bgpio.protocol.BgpLSNlri; +import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails; +import org.onosproject.bgpio.types.RouteDistinguisher; + +/** + * Abstraction of BGP local RIB. + */ +public interface BgpLocalRib { + + /** + * Add NLRI to local RIB. + * + * @param sessionInfo session info + * @param nlri network layer reach info + * @param details nlri details + */ + void add(BgpSessionInfo sessionInfo, BgpLSNlri nlri, PathAttrNlriDetails details); + + /** + * Removes NLRI identifier if it exists. + * + * @param nlri info + */ + void delete(BgpLSNlri nlri); + + /** + * Update NLRI identifier mapped with route distinguisher if it exists in tree otherwise add NLRI infomation mapped + * to respective route distinguisher. + * + * @param sessionInfo BGP session info + * @param nlri info + * @param details has pathattribute, protocol id and identifier + * @param routeDistinguisher unique for each VPN + */ + void add(BgpSessionInfo sessionInfo, BgpLSNlri nlri, PathAttrNlriDetails details, + RouteDistinguisher routeDistinguisher); + + /** + * Removes VPN NLRI identifier mapped to route distinguisher if it exists. + * + * @param nlri info + * @param routeDistinguisher unique for each VPN + */ + void delete(BgpLSNlri nlri, RouteDistinguisher routeDistinguisher); +} diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpNodeListener.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpNodeListener.java new file mode 100755 index 00000000..726d931b --- /dev/null +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpNodeListener.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.onosproject.bgp.controller; + +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4; + +/** + * Allows for providers interested in node events to be notified. + */ +public interface BgpNodeListener { + + /** + * Notifies that the node was added. + * + * @param nodeNlri node rechability info + */ + void addNode(BgpNodeLSNlriVer4 nodeNlri); + + /** + * Notifies that the node was removed. + * + * @param nodeNlri node rechability info + */ + void deleteNode(BgpNodeLSNlriVer4 nodeNlri); +} diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPacketStats.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPacketStats.java similarity index 97% rename from framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPacketStats.java rename to framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPacketStats.java index 95f83a2d..8fd3c688 100755 --- a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPacketStats.java +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPacketStats.java @@ -21,7 +21,7 @@ package org.onosproject.bgp.controller; * to the event if blocked has been called. This packet context can be used to react to the packet in event with a * packet out. */ -public interface BGPPacketStats { +public interface BgpPacketStats { /** * Returns the count for no of packets sent out. * diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeer.java old mode 100755 new mode 100644 similarity index 79% rename from framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java rename to framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeer.java index aafaf06e..9f4d47da --- a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeer.java +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeer.java @@ -16,14 +16,16 @@ package org.onosproject.bgp.controller; import java.util.List; import org.jboss.netty.channel.Channel; -import org.onosproject.bgpio.protocol.BGPFactory; -import org.onosproject.bgpio.protocol.BGPMessage; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpFactory; +import org.onosproject.bgpio.protocol.BgpMessage; +import org.onosproject.bgpio.types.BgpValueType; /** * Represents the peer side of an BGP peer. * */ -public interface BGPPeer { +public interface BgpPeer { /** * Sets the associated Netty channel for this bgp peer. @@ -58,21 +60,21 @@ public interface BGPPeer { * * @param msg the message to write */ - void sendMessage(BGPMessage msg); + void sendMessage(BgpMessage msg); /** * Writes the BGPMessage list to the peer. * * @param msgs the messages to be written */ - void sendMessage(List msgs); + void sendMessage(List msgs); /** * Provides the factory for BGP version. * * @return BGP version specific factory. */ - BGPFactory factory(); + BgpFactory factory(); /** * Checks if the bgp peer is still connected. @@ -94,6 +96,14 @@ public interface BGPPeer { */ String channelId(); + /** + * Maintaining Adj-RIB-In separately for each peer. + * + * @param pathAttr list of Bgp path attributes + * @throws BgpParseException while building Adj-Rib-In + */ + void buildAdjRibIn(List pathAttr) throws BgpParseException; + /** * Return the BGP session info. * diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeerCfg.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerCfg.java similarity index 99% rename from framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeerCfg.java rename to framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerCfg.java index e7c5d9b4..2fb970fc 100755 --- a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BGPPeerCfg.java +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerCfg.java @@ -18,7 +18,7 @@ package org.onosproject.bgp.controller; /** * BGP Peer configuration information. */ -public interface BGPPeerCfg { +public interface BgpPeerCfg { enum State { diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerManager.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerManager.java index d2230967..895cc145 100755 --- a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerManager.java +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpPeerManager.java @@ -26,7 +26,7 @@ public interface BgpPeerManager { * * @return false if peer already exist, otherwise true */ - public boolean addConnectedPeer(BGPId bgpId, BGPPeer bgpPeer); + public boolean addConnectedPeer(BgpId bgpId, BgpPeer bgpPeer); /** * Validate wheather peer is connected. @@ -35,14 +35,14 @@ public interface BgpPeerManager { * * @return true if peer exist, otherwise false */ - public boolean isPeerConnected(BGPId bgpId); + public boolean isPeerConnected(BgpId bgpId); /** * Remove connected peer. * * @param bgpId BGP ID */ - public void removeConnectedPeer(BGPId bgpId); + public void removeConnectedPeer(BgpId bgpId); /** * Gets connected peer. @@ -50,5 +50,5 @@ public interface BgpPeerManager { * @param bgpId BGP ID * @return BGPPeer the connected peer, otherwise null */ - public BGPPeer getPeer(BGPId bgpId); + public BgpPeer getPeer(BgpId bgpId); } diff --git a/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpSessionInfo.java b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpSessionInfo.java new file mode 100755 index 00000000..a21a23d2 --- /dev/null +++ b/framework/src/onos/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpSessionInfo.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onosproject.bgp.controller; + +import org.onosproject.bgpio.protocol.BgpVersion; + +/** + * Abstraction of an BGP session info. Maintian session parameters obtained during session creation. + */ +public interface BgpSessionInfo { + /** + * Gets the bgp session type iBGP/eBGP. + * + * @return isiBGPSession, true if session is of type internal, otherwise false. + */ + boolean isIbgpSession(); + + /** + * Gets the negotiated hold time for the session. + * + * @return negotiated hold time. + */ + short negotiatedholdTime(); + + /** + * Gets the BGP ID of BGP peer. + * + * @return bgp ID. + */ + BgpId remoteBgpId(); + + /** + * Gets the BGP version of peer. + * + * @return bgp version. + */ + BgpVersion remoteBgpVersion(); + + /** + * Gets the BGP remote bgp AS number. + * + * @return remoteBgpASNum peer AS number. + */ + long remoteBgpASNum(); + + /** + * Gets the BGP peer hold time. + * + * @return bgp hold time. + */ + short remoteBgpHoldTime(); + + /** + * Gets the BGP version for this bgp peer. + * + * @return bgp identifier. + */ + int remoteBgpIdentifier(); +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/exceptions/BGPParseException.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/exceptions/BgpParseException.java similarity index 88% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/exceptions/BGPParseException.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/exceptions/BgpParseException.java index 62427a44..d0890320 100755 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/exceptions/BGPParseException.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/exceptions/BgpParseException.java @@ -21,7 +21,7 @@ import org.jboss.netty.buffer.ChannelBuffer; /** * Custom Exception for BGP IO. */ -public class BGPParseException extends Exception { +public class BgpParseException extends Exception { private static final long serialVersionUID = 1L; private byte errorCode; @@ -31,7 +31,7 @@ public class BGPParseException extends Exception { /** * Default constructor to create a new exception. */ - public BGPParseException() { + public BgpParseException() { super(); } @@ -41,7 +41,7 @@ public class BGPParseException extends Exception { * @param message the detail of exception in string * @param cause underlying cause of the error */ - public BGPParseException(final String message, final Throwable cause) { + public BgpParseException(final String message, final Throwable cause) { super(message, cause); } @@ -50,7 +50,7 @@ public class BGPParseException extends Exception { * * @param message the detail of exception in string */ - public BGPParseException(final String message) { + public BgpParseException(final String message) { super(message); } @@ -59,7 +59,7 @@ public class BGPParseException extends Exception { * * @param cause underlying cause of the error */ - public BGPParseException(final Throwable cause) { + public BgpParseException(final Throwable cause) { super(cause); } @@ -70,7 +70,7 @@ public class BGPParseException extends Exception { * @param errorSubCode error subcode of BGP message * @param data error data of BGP message */ - public BGPParseException(final byte errorCode, final byte errorSubCode, final ChannelBuffer data) { + public BgpParseException(final byte errorCode, final byte errorSubCode, final ChannelBuffer data) { super(); this.errorCode = errorCode; this.errorSubCode = errorSubCode; diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPFactories.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpFactories.java similarity index 65% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPFactories.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpFactories.java index 71b9cbff..eb18c7d1 100755 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPFactories.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpFactories.java @@ -17,22 +17,22 @@ package org.onosproject.bgpio.protocol; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.ver4.BGPFactoryVer4; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.ver4.BgpFactoryVer4; +import org.onosproject.bgpio.types.BgpHeader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Abstraction to provide the version for BGP. */ -public final class BGPFactories { +public final class BgpFactories { - protected static final Logger log = LoggerFactory.getLogger(BGPFactories.class); + protected static final Logger log = LoggerFactory.getLogger(BgpFactories.class); private static final GenericReader GENERIC_READER = new GenericReader(); - private BGPFactories() { + private BgpFactories() { } /** @@ -41,12 +41,12 @@ public final class BGPFactories { * @param version BGP version * @return BGP version */ - public static BGPFactory getFactory(BGPVersion version) { + public static BgpFactory getFactory(BgpVersion version) { switch (version) { case BGP_4: - return BGPFactoryVer4.INSTANCE; + return BgpFactoryVer4.INSTANCE; default: - throw new IllegalArgumentException("[BGPFactory:]Unknown version: " + version); + throw new IllegalArgumentException("[BgpFactory:]Unknown version: " + version); } } @@ -54,19 +54,19 @@ public final class BGPFactories { * Reader class for reading BGP messages from channel buffer. * */ - private static class GenericReader implements BGPMessageReader { + private static class GenericReader implements BgpMessageReader { @Override - public BGPMessage readFrom(ChannelBuffer bb, BGPHeader bgpHeader) - throws BGPParseException { - BGPFactory factory; + public BgpMessage readFrom(ChannelBuffer bb, BgpHeader bgpHeader) + throws BgpParseException { + BgpFactory factory; if (!bb.readable()) { log.error("Empty message received"); - throw new BGPParseException("Empty message received"); + throw new BgpParseException("Empty message received"); } // TODO: Currently only BGP version 4 is supported - factory = org.onosproject.bgpio.protocol.ver4.BGPFactoryVer4.INSTANCE; + factory = org.onosproject.bgpio.protocol.ver4.BgpFactoryVer4.INSTANCE; return factory.getReader().readFrom(bb, bgpHeader); } } @@ -76,7 +76,7 @@ public final class BGPFactories { * * @return bgp message generic reader */ - public static BGPMessageReader getGenericReader() { + public static BgpMessageReader getGenericReader() { return GENERIC_READER; } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPFactory.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpFactory.java similarity index 83% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPFactory.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpFactory.java index cf6bf008..11a85ff8 100755 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPFactory.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpFactory.java @@ -21,40 +21,40 @@ package org.onosproject.bgpio.protocol; * and objects. * */ -public interface BGPFactory { +public interface BgpFactory { /** * Gets the builder object for a open message. * * @return builder object for open message */ - BGPOpenMsg.Builder openMessageBuilder(); + BgpOpenMsg.Builder openMessageBuilder(); /** * Gets the builder object for a keepalive message. * * @return builder object for keepalive message */ - BGPKeepaliveMsg.Builder keepaliveMessageBuilder(); + BgpKeepaliveMsg.Builder keepaliveMessageBuilder(); /** * Gets the builder object for a notification message. * * @return builder object for notification message. */ - BGPNotificationMsg.Builder notificationMessageBuilder(); + BgpNotificationMsg.Builder notificationMessageBuilder(); /** * Gets the BGP message reader. * * @return BGP message reader */ - BGPMessageReader getReader(); + BgpMessageReader getReader(); /** * Returns BGP version. * * @return BGP version */ - BGPVersion getVersion(); + BgpVersion getVersion(); } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsg.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpKeepaliveMsg.java similarity index 76% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsg.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpKeepaliveMsg.java index ae773889..0cb776a0 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsg.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpKeepaliveMsg.java @@ -16,33 +16,33 @@ package org.onosproject.bgpio.protocol; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.types.BgpHeader; /** * Abstraction of an entity providing BGP Keepalive Message. */ -public interface BGPKeepaliveMsg extends BGPMessage { +public interface BgpKeepaliveMsg extends BgpMessage { @Override - BGPVersion getVersion(); + BgpVersion getVersion(); @Override - BGPType getType(); + BgpType getType(); @Override void writeTo(ChannelBuffer channelBuffer); @Override - BGPHeader getHeader(); + BgpHeader getHeader(); /** * Builder interface with get and set functions to build Keepalive message. */ - interface Builder extends BGPMessage.Builder { + interface Builder extends BgpMessage.Builder { @Override - BGPKeepaliveMsg build(); + BgpKeepaliveMsg build(); @Override - Builder setHeader(BGPHeader bgpMsgHeader); + Builder setHeader(BgpHeader bgpMsgHeader); } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPLSNlri.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpLSNlri.java similarity index 81% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPLSNlri.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpLSNlri.java index 189edb88..dd8857a7 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPLSNlri.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpLSNlri.java @@ -15,14 +15,14 @@ */ package org.onosproject.bgpio.protocol; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSNlriVer4.PROTOCOLTYPE; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType; import org.onosproject.bgpio.types.RouteDistinguisher; /** * Abstraction of an entity providing BGP-LS NLRI. */ -public interface BGPLSNlri { +public interface BgpLSNlri { /** * Returns NlriType of BGP-LS NLRI. * @@ -41,9 +41,9 @@ public interface BGPLSNlri { * Returns Protocol Id in Nlri. * * @return Protocol Id in Nlri - * @throws BGPParseException while getting protocol ID + * @throws BgpParseException while getting protocol ID */ - PROTOCOLTYPE getProtocolId() throws BGPParseException; + ProtocolType getProtocolId() throws BgpParseException; /** * Returns Route distinguisher in Nlri. diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpLinkLsNlri.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpLinkLsNlri.java index dab7a3d2..3924a13b 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpLinkLsNlri.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpLinkLsNlri.java @@ -17,13 +17,13 @@ package org.onosproject.bgpio.protocol; import java.util.List; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.protocol.linkstate.NodeDescriptors; /** * Abstraction of an entity providing BGP-LS Link NLRI. */ -public interface BgpLinkLsNlri extends BGPLSNlri { +public interface BgpLinkLsNlri extends BgpLSNlri { /** * Returns local node descriptors. * @@ -43,5 +43,5 @@ public interface BgpLinkLsNlri extends BGPLSNlri { * * @return link descriptors */ - List linkDescriptors(); + List linkDescriptors(); } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessage.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpMessage.java similarity index 76% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessage.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpMessage.java index 309ef435..f1e1b96f 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessage.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpMessage.java @@ -17,36 +17,36 @@ package org.onosproject.bgpio.protocol; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpHeader; /** * Abstraction of an entity providing BGP Messages. */ -public interface BGPMessage extends Writeable { +public interface BgpMessage extends Writeable { /** * Returns BGP Header of BGP Message. * * @return BGP Header of BGP Message */ - BGPHeader getHeader(); + BgpHeader getHeader(); /** * Returns version of BGP Message. * * @return version of BGP Message */ - BGPVersion getVersion(); + BgpVersion getVersion(); /** * Returns BGP Type of BGP Message. * * @return BGP Type of BGP Message */ - BGPType getType(); + BgpType getType(); @Override - void writeTo(ChannelBuffer cb) throws BGPParseException; + void writeTo(ChannelBuffer cb) throws BgpParseException; /** * Builder interface with get and set functions to build BGP Message. @@ -56,9 +56,9 @@ public interface BGPMessage extends Writeable { * Builds BGP Message. * * @return BGP Message - * @throws BGPParseException while building bgp message + * @throws BgpParseException while building bgp message */ - BGPMessage build() throws BGPParseException; + BgpMessage build() throws BgpParseException; /** * Sets BgpHeader and return its builder. @@ -66,6 +66,6 @@ public interface BGPMessage extends Writeable { * @param bgpMsgHeader BGP Message Header * @return builder by setting BGP message header */ - Builder setHeader(BGPHeader bgpMsgHeader); + Builder setHeader(BgpHeader bgpMsgHeader); } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessageReader.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpMessageReader.java similarity index 78% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessageReader.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpMessageReader.java index 18b8f58d..b8318b29 100755 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessageReader.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpMessageReader.java @@ -16,13 +16,13 @@ package org.onosproject.bgpio.protocol; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpHeader; /** * Abstraction of an entity providing BGP Message Reader. */ -public interface BGPMessageReader { +public interface BgpMessageReader { /** * Reads the Objects in the BGP Message and Returns BGP Message. @@ -30,7 +30,7 @@ public interface BGPMessageReader { * @param cb Channel Buffer * @param bgpHeader BGP message header * @return BGP Message - * @throws BGPParseException while parsing BGP message. + * @throws BgpParseException while parsing BGP message. */ - T readFrom(ChannelBuffer cb, BGPHeader bgpHeader) throws BGPParseException; + T readFrom(ChannelBuffer cb, BgpHeader bgpHeader) throws BgpParseException; } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessageWriter.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpMessageWriter.java similarity index 83% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessageWriter.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpMessageWriter.java index 11f161c4..bb75b5ea 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessageWriter.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpMessageWriter.java @@ -17,20 +17,20 @@ package org.onosproject.bgpio.protocol; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; /** * Abstraction of an entity providing BGP Message Writer. */ -public interface BGPMessageWriter { +public interface BgpMessageWriter { /** * Writes the Objects of the BGP Message into Channel Buffer. * * @param cb Channel Buffer * @param message BGP Message - * @throws BGPParseException + * @throws BgpParseException * While writing message */ - void write(ChannelBuffer cb, T message) throws BGPParseException; + void write(ChannelBuffer cb, T message) throws BgpParseException; } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNodeLSNlri.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpNodeLSNlri.java similarity index 83% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNodeLSNlri.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpNodeLSNlri.java index b6e4a3a0..13ef5cc5 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNodeLSNlri.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpNodeLSNlri.java @@ -15,16 +15,16 @@ */ package org.onosproject.bgpio.protocol; -import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSIdentifier; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSIdentifier; /** * Abstraction of an entity providing BGP-LS Node NLRI. */ -public interface BGPNodeLSNlri extends BGPLSNlri { +public interface BgpNodeLSNlri extends BgpLSNlri { /** * Returns local node descriptors. * * @return local node descriptors */ - BGPNodeLSIdentifier getLocalNodeDescriptors(); + BgpNodeLSIdentifier getLocalNodeDescriptors(); } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNotificationMsg.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpNotificationMsg.java similarity index 90% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNotificationMsg.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpNotificationMsg.java index a1d9d578..e3361aa7 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNotificationMsg.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpNotificationMsg.java @@ -15,12 +15,12 @@ */ package org.onosproject.bgpio.protocol; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; /** * Abstraction of an entity providing BGP notification message. */ -public interface BGPNotificationMsg extends BGPMessage { +public interface BgpNotificationMsg extends BgpMessage { /** * Returns errorCode in notification message. * @@ -45,10 +45,10 @@ public interface BGPNotificationMsg extends BGPMessage { /** * Builder interface with get and set functions to build notification message. */ - public interface Builder extends BGPMessage.Builder { + public interface Builder extends BgpMessage.Builder { @Override - BGPNotificationMsg build() throws BGPParseException; + BgpNotificationMsg build() throws BgpParseException; /** * Sets errorCode in notification message and return its builder. diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPOpenMsg.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java similarity index 84% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPOpenMsg.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java index bf5d05f4..94ec2235 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPOpenMsg.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpOpenMsg.java @@ -17,23 +17,23 @@ package org.onosproject.bgpio.protocol; import java.util.LinkedList; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPHeader; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpHeader; +import org.onosproject.bgpio.types.BgpValueType; /** * Abstraction of an entity providing BGP Open Message. */ -public interface BGPOpenMsg extends BGPMessage { +public interface BgpOpenMsg extends BgpMessage { @Override - BGPHeader getHeader(); + BgpHeader getHeader(); @Override - BGPVersion getVersion(); + BgpVersion getVersion(); @Override - BGPType getType(); + BgpType getType(); /** * Returns hold time of Open Message. @@ -61,15 +61,15 @@ public interface BGPOpenMsg extends BGPMessage { * * @return capabilities of Open Message */ - LinkedList getCapabilityTlv(); + LinkedList getCapabilityTlv(); /** * Builder interface with get and set functions to build Open message. */ - interface Builder extends BGPMessage.Builder { + interface Builder extends BgpMessage.Builder { @Override - BGPOpenMsg build() throws BGPParseException; + BgpOpenMsg build() throws BgpParseException; /** * Sets hold time in Open Message and return its builder. @@ -101,7 +101,7 @@ public interface BGPOpenMsg extends BGPMessage { * @param capabilityTlv capabilities in open message * @return builder by setting capabilities */ - Builder setCapabilityTlv(LinkedList capabilityTlv); + Builder setCapabilityTlv(LinkedList capabilityTlv); /** * Sets isLargeAsCapabilityTlvSet and return its builder. @@ -122,6 +122,6 @@ public interface BGPOpenMsg extends BGPMessage { Builder setLsCapabilityTlv(boolean isLsCapabilitySet); @Override - Builder setHeader(BGPHeader bgpMsgHeader); + Builder setHeader(BgpHeader bgpMsgHeader); } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPPrefixLSNlri.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpPrefixLSNlri.java similarity index 85% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPPrefixLSNlri.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpPrefixLSNlri.java index 2c331a2e..54bcdba3 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPPrefixLSNlri.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpPrefixLSNlri.java @@ -15,15 +15,15 @@ */ package org.onosproject.bgpio.protocol; -import java.util.LinkedList; +import java.util.List; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.protocol.linkstate.NodeDescriptors; /** * Abstraction of an entity providing BGP-LS Prefix NLRI. */ -public interface BGPPrefixLSNlri extends BGPLSNlri { +public interface BgpPrefixLSNlri extends BgpLSNlri { /** * Returns local node descriptors. * @@ -36,5 +36,5 @@ public interface BGPPrefixLSNlri extends BGPLSNlri { * * @return list of Prefix descriptor */ - LinkedList getPrefixdescriptor(); + List getPrefixdescriptor(); } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPType.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpType.java similarity index 96% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPType.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpType.java index d3349156..b90721d5 100755 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPType.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpType.java @@ -19,7 +19,7 @@ package org.onosproject.bgpio.protocol; /** * Enum to Provide the Different types of BGP messages. */ -public enum BGPType { +public enum BgpType { NONE(0), OPEN(1), UPDATE(2), NOTIFICATION(3), KEEP_ALIVE(4); @@ -30,7 +30,7 @@ public enum BGPType { * * @param val type of BGP message */ - BGPType(int val) { + BgpType(int val) { value = val; } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpUpdateMsg.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpUpdateMsg.java index 969936c8..d79a4236 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpUpdateMsg.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpUpdateMsg.java @@ -24,7 +24,7 @@ import org.onosproject.bgpio.protocol.ver4.BgpPathAttributes; /** * Abstraction of an entity providing BGP Update Message. */ -public interface BgpUpdateMsg extends BGPMessage { +public interface BgpUpdateMsg extends BgpMessage { /** * Returns path attributes in BGP Update Message. * diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPVersion.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpVersion.java similarity index 94% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPVersion.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpVersion.java index 97bc7dce..b1f037f4 100755 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPVersion.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BgpVersion.java @@ -19,7 +19,7 @@ package org.onosproject.bgpio.protocol; /** * Enum to provide BGP Message Version. */ -public enum BGPVersion { +public enum BgpVersion { BGP_4(4); @@ -30,7 +30,7 @@ public enum BGPVersion { * * @param packetVersion version of BGP */ - BGPVersion(final int packetVersion) { + BgpVersion(final int packetVersion) { this.packetVersion = packetVersion; } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/Writeable.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/Writeable.java index 72df7f32..1c6f7fc2 100755 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/Writeable.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/Writeable.java @@ -17,7 +17,7 @@ package org.onosproject.bgpio.protocol; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; /** * Abstraction of an entity providing functionality to write byte streams of @@ -29,7 +29,7 @@ public interface Writeable { * Writes byte streams of messages to channel buffer. * * @param cb channelBuffer - * @throws BGPParseException when error occurs while writing BGP message to channel buffer + * @throws BgpParseException when error occurs while writing BGP message to channel buffer */ - void writeTo(ChannelBuffer cb) throws BGPParseException; + void writeTo(ChannelBuffer cb) throws BgpParseException; } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPLinkLSIdentifier.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLSIdentifier.java old mode 100755 new mode 100644 similarity index 62% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPLinkLSIdentifier.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLSIdentifier.java index ffea74db..3967a221 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPLinkLSIdentifier.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLSIdentifier.java @@ -18,16 +18,18 @@ package org.onosproject.bgpio.protocol.linkstate; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.types.IPv4AddressTlv; import org.onosproject.bgpio.types.IPv6AddressTlv; import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv; import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId; +import org.onosproject.bgpio.util.Constants; import org.onosproject.bgpio.util.UnSupportedAttribute; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,22 +40,21 @@ import com.google.common.base.Preconditions; /** * Implementation of local node descriptors, remote node descriptors and link descriptors. */ -public class BGPLinkLSIdentifier { - private static final Logger log = LoggerFactory.getLogger(BGPLinkLSIdentifier.class); +public class BgpLinkLSIdentifier implements Comparable { + private static final Logger log = LoggerFactory.getLogger(BgpLinkLSIdentifier.class); public static final short IPV4_INTERFACE_ADDRESS_TYPE = 259; public static final short IPV4_NEIGHBOR_ADDRESS_TYPE = 260; public static final short IPV6_INTERFACE_ADDRESS_TYPE = 261; public static final short IPV6_NEIGHBOR_ADDRESS_TYPE = 262; - public static final int TYPE_AND_LEN = 4; private NodeDescriptors localNodeDescriptors; private NodeDescriptors remoteNodeDescriptors; - private List linkDescriptor; + private List linkDescriptor; /** * Initialize fields. */ - public BGPLinkLSIdentifier() { + public BgpLinkLSIdentifier() { this.localNodeDescriptors = null; this.remoteNodeDescriptors = null; this.linkDescriptor = null; @@ -66,8 +67,8 @@ public class BGPLinkLSIdentifier { * @param remoteNodeDescriptors remote node descriptors * @param linkDescriptor link descriptors */ - public BGPLinkLSIdentifier(NodeDescriptors localNodeDescriptors, NodeDescriptors remoteNodeDescriptors, - LinkedList linkDescriptor) { + public BgpLinkLSIdentifier(NodeDescriptors localNodeDescriptors, NodeDescriptors remoteNodeDescriptors, + LinkedList linkDescriptor) { this.localNodeDescriptors = Preconditions.checkNotNull(localNodeDescriptors); this.remoteNodeDescriptors = Preconditions.checkNotNull(remoteNodeDescriptors); this.linkDescriptor = Preconditions.checkNotNull(linkDescriptor); @@ -79,9 +80,9 @@ public class BGPLinkLSIdentifier { * @param cb ChannelBuffer * @param protocolId in linkstate nlri * @return object of BGPLinkLSIdentifier - * @throws BGPParseException while parsing link identifier + * @throws BgpParseException while parsing link identifier */ - public static BGPLinkLSIdentifier parseLinkIdendifier(ChannelBuffer cb, byte protocolId) throws BGPParseException { + public static BgpLinkLSIdentifier parseLinkIdendifier(ChannelBuffer cb, byte protocolId) throws BgpParseException { //Parse local node descriptor NodeDescriptors localNodeDescriptors = new NodeDescriptors(); localNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.LOCAL_NODE_DES_TYPE, protocolId); @@ -91,9 +92,9 @@ public class BGPLinkLSIdentifier { remoteNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.REMOTE_NODE_DES_TYPE, protocolId); //Parse link descriptor - LinkedList linkDescriptor = new LinkedList<>(); + LinkedList linkDescriptor = new LinkedList<>(); linkDescriptor = parseLinkDescriptors(cb); - return new BGPLinkLSIdentifier(localNodeDescriptors, remoteNodeDescriptors, linkDescriptor); + return new BgpLinkLSIdentifier(localNodeDescriptors, remoteNodeDescriptors, linkDescriptor); } /** @@ -103,16 +104,17 @@ public class BGPLinkLSIdentifier { * @param desType descriptor type * @param protocolId protocol identifier * @return object of NodeDescriptors - * @throws BGPParseException while parsing Local/Remote node descriptors + * @throws BgpParseException while parsing Local/Remote node descriptors */ public static NodeDescriptors parseNodeDescriptors(ChannelBuffer cb, short desType, byte protocolId) - throws BGPParseException { - ChannelBuffer tempBuf = cb; + throws BgpParseException { + log.debug("parse Node descriptors"); + ChannelBuffer tempBuf = cb.copy(); short type = cb.readShort(); short length = cb.readShort(); if (cb.readableBytes() < length) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, - tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, + tempBuf.readBytes(cb.readableBytes() + Constants.TYPE_AND_LEN_AS_SHORT)); } NodeDescriptors nodeIdentifier = new NodeDescriptors(); ChannelBuffer tempCb = cb.readBytes(length); @@ -120,7 +122,7 @@ public class BGPLinkLSIdentifier { if (type == desType) { nodeIdentifier = NodeDescriptors.read(tempCb, length, desType, protocolId); } else { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.MALFORMED_ATTRIBUTE_LIST, null); } return nodeIdentifier; } @@ -130,20 +132,20 @@ public class BGPLinkLSIdentifier { * * @param cb ChannelBuffer * @return list of link descriptors - * @throws BGPParseException while parsing link descriptors + * @throws BgpParseException while parsing link descriptors */ - public static LinkedList parseLinkDescriptors(ChannelBuffer cb) throws BGPParseException { - LinkedList linkDescriptor = new LinkedList<>(); - BGPValueType tlv = null; + public static LinkedList parseLinkDescriptors(ChannelBuffer cb) throws BgpParseException { + LinkedList linkDescriptor = new LinkedList<>(); + BgpValueType tlv = null; int count = 0; while (cb.readableBytes() > 0) { - ChannelBuffer tempBuf = cb; + ChannelBuffer tempBuf = cb.copy(); short type = cb.readShort(); short length = cb.readShort(); if (cb.readableBytes() < length) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, - tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, + tempBuf.readBytes(cb.readableBytes() + Constants.TYPE_AND_LEN_AS_SHORT)); } ChannelBuffer tempCb = cb.readBytes(length); switch (type) { @@ -168,9 +170,9 @@ public class BGPLinkLSIdentifier { //MultiTopologyId TLV cannot repeat more than once if (count > 1) { //length + 4 implies data contains type, length and value - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length - + TYPE_AND_LEN)); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length + + Constants.TYPE_AND_LEN_AS_SHORT)); } break; default: @@ -204,7 +206,7 @@ public class BGPLinkLSIdentifier { * * @return link descriptors */ - public List linkDescriptors() { + public List linkDescriptors() { return this.linkDescriptor; } @@ -218,21 +220,25 @@ public class BGPLinkLSIdentifier { if (this == obj) { return true; } - if (obj instanceof BGPLinkLSIdentifier) { + if (obj instanceof BgpLinkLSIdentifier) { int countObjSubTlv = 0; int countOtherSubTlv = 0; boolean isCommonSubTlv = true; - BGPLinkLSIdentifier other = (BGPLinkLSIdentifier) obj; - Iterator objListIterator = other.linkDescriptor.iterator(); + BgpLinkLSIdentifier other = (BgpLinkLSIdentifier) obj; + Iterator objListIterator = other.linkDescriptor.iterator(); countOtherSubTlv = other.linkDescriptor.size(); countObjSubTlv = linkDescriptor.size(); if (countObjSubTlv != countOtherSubTlv) { return false; } else { while (objListIterator.hasNext() && isCommonSubTlv) { - BGPValueType subTlv = objListIterator.next(); - isCommonSubTlv = Objects.equals(linkDescriptor.contains(subTlv), - other.linkDescriptor.contains(subTlv)); + BgpValueType subTlv = objListIterator.next(); + if (linkDescriptor.contains(subTlv) && other.linkDescriptor.contains(subTlv)) { + isCommonSubTlv = Objects.equals(linkDescriptor.get(linkDescriptor.indexOf(subTlv)), + other.linkDescriptor.get(other.linkDescriptor.indexOf(subTlv))); + } else { + isCommonSubTlv = false; + } } return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors) && Objects.equals(this.remoteNodeDescriptors, other.remoteNodeDescriptors); @@ -249,4 +255,42 @@ public class BGPLinkLSIdentifier { .add("linkDescriptor", linkDescriptor) .toString(); } + + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + int result = this.localNodeDescriptors.compareTo(((BgpLinkLSIdentifier) o).localNodeDescriptors); + if (result != 0) { + return result; + } else if (this.remoteNodeDescriptors.compareTo(((BgpLinkLSIdentifier) o).remoteNodeDescriptors) != 0) { + return this.remoteNodeDescriptors.compareTo(((BgpLinkLSIdentifier) o).remoteNodeDescriptors); + } else { + int countOtherSubTlv = ((BgpLinkLSIdentifier) o).linkDescriptor.size(); + int countObjSubTlv = linkDescriptor.size(); + if (countOtherSubTlv != countObjSubTlv) { + if (countOtherSubTlv > countObjSubTlv) { + return 1; + } else { + return -1; + } + } + ListIterator listIterator = linkDescriptor.listIterator(); + ListIterator listIteratorOther = ((BgpLinkLSIdentifier) o).linkDescriptor.listIterator(); + while (listIterator.hasNext()) { + BgpValueType tlv = listIterator.next(); + BgpValueType tlv1 = listIteratorOther.next(); + if (linkDescriptor.contains(tlv) && ((BgpLinkLSIdentifier) o).linkDescriptor.contains(tlv1)) { + int res = linkDescriptor.get(linkDescriptor.indexOf(tlv)).compareTo( + ((BgpLinkLSIdentifier) o).linkDescriptor.get(((BgpLinkLSIdentifier) o).linkDescriptor + .indexOf(tlv1))); + if (res != 0) { + return res; + } + } + } + } + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLsNlriVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLsNlriVer4.java new file mode 100755 index 00000000..01d369e4 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpLinkLsNlriVer4.java @@ -0,0 +1,210 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.protocol.linkstate; + +import java.util.List; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpLinkLsNlri; +import org.onosproject.bgpio.protocol.NlriType; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.types.RouteDistinguisher; +import org.onosproject.bgpio.util.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of Link LS NLRI. + */ +public class BgpLinkLsNlriVer4 implements BgpLinkLsNlri { + + /* + * REFERENCE : draft-ietf-idr-ls-distribution-11 + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+ + | Protocol-ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identifier | + | (64 bits) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Local Node Descriptors (variable) // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Remote Node Descriptors (variable) // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Link Descriptors (variable) // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure : The Link NLRI format + */ + private static final Logger log = LoggerFactory.getLogger(BgpLinkLsNlriVer4.class); + public static final int LINK_NLRITYPE = 2; + + private BgpLinkLSIdentifier linkLSIdentifier; + private byte protocolId; + private long identifier; + private RouteDistinguisher routeDistinguisher; + private boolean isVpn; + + /** + * Initialize fields. + */ + public BgpLinkLsNlriVer4() { + this.protocolId = 0; + this.identifier = 0; + this.linkLSIdentifier = null; + this.routeDistinguisher = null; + this.isVpn = false; + } + + /** + * Constructor to initialize parameters for BGP LinkLSNlri. + * + * @param protocolId protocol Id + * @param identifier field in BGP LinkLSNlri + * @param linkLSIdentifier link LS identifier + * @param routeDistinguisher route distinguisher from message + * @param isVpn vpn info availability in message + */ + public BgpLinkLsNlriVer4(byte protocolId, long identifier, BgpLinkLSIdentifier linkLSIdentifier, + RouteDistinguisher routeDistinguisher, boolean isVpn) { + this.protocolId = protocolId; + this.identifier = identifier; + this.linkLSIdentifier = linkLSIdentifier; + this.routeDistinguisher = routeDistinguisher; + this.isVpn = isVpn; + } + + /** + * Reads from channelBuffer and parses Link LS Nlri. + * + * @param cb ChannelBuffer + * @param afi Address Family Identifier + * @param safi Subsequent Address Family Identifier + * @return object of this class + * @throws BgpParseException while parsing Link LS NLRI + */ + public static BgpLinkLsNlriVer4 read(ChannelBuffer cb, short afi, byte safi) throws BgpParseException { + boolean isVpn = false; + RouteDistinguisher routeDistinguisher = null; + if ((afi == Constants.AFI_VALUE) && (safi == Constants.VPN_SAFI_VALUE)) { + routeDistinguisher = new RouteDistinguisher(); + routeDistinguisher = RouteDistinguisher.read(cb); + isVpn = true; + } else { + isVpn = false; + } + byte protocolId = cb.readByte(); + long identifier = cb.readLong(); + + BgpLinkLSIdentifier linkLSIdentifier = new BgpLinkLSIdentifier(); + linkLSIdentifier = BgpLinkLSIdentifier.parseLinkIdendifier(cb, protocolId); + return new BgpLinkLsNlriVer4(protocolId, identifier, linkLSIdentifier, routeDistinguisher, isVpn); + } + + @Override + public NlriType getNlriType() { + return NlriType.LINK; + } + + @Override + public long getIdentifier() { + return this.identifier; + } + + /** + * Set the link LS identifier. + * + * @param linkLSIdentifier link LS identifier to set + */ + public void setLinkLSIdentifier(BgpLinkLSIdentifier linkLSIdentifier) { + this.linkLSIdentifier = linkLSIdentifier; + } + + @Override + public ProtocolType getProtocolId() throws BgpParseException { + switch (protocolId) { + case Constants.ISIS_LEVELONE: + return ProtocolType.ISIS_LEVEL_ONE; + case Constants.ISIS_LEVELTWO: + return ProtocolType.ISIS_LEVEL_TWO; + case Constants.OSPFV2: + return ProtocolType.OSPF_V2; + case Constants.DIRECT: + return ProtocolType.DIRECT; + case Constants.STATIC_CONFIGURATION: + return ProtocolType.STATIC_CONFIGURATION; + case Constants.OSPFV3: + return ProtocolType.OSPF_V3; + default: + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); + } + } + + @Override + public NodeDescriptors localNodeDescriptors() { + return this.linkLSIdentifier.localNodeDescriptors(); + } + + @Override + public NodeDescriptors remoteNodeDescriptors() { + return this.linkLSIdentifier.remoteNodeDescriptors(); + } + + /** + * Returns whether VPN is present or not. + * + * @return whether VPN is present or not + */ + public boolean isVpnPresent() { + return this.isVpn; + } + + @Override + public RouteDistinguisher getRouteDistinguisher() { + return this.routeDistinguisher; + } + + /** + * Returns link identifier. + * + * @return link identifier + */ + public BgpLinkLSIdentifier getLinkIdentifier() { + return this.linkLSIdentifier; + } + + @Override + public List linkDescriptors() { + return this.linkLSIdentifier.linkDescriptors(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues() + .add("protocolId", protocolId) + .add("identifier", identifier) + .add("RouteDistinguisher ", routeDistinguisher) + .add("linkLSIdentifier", linkLSIdentifier) + .toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSIdentifier.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpNodeLSIdentifier.java similarity index 69% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSIdentifier.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpNodeLSIdentifier.java index 603bf6ec..6c2c96d9 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSIdentifier.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpNodeLSIdentifier.java @@ -18,8 +18,8 @@ package org.onosproject.bgpio.protocol.linkstate; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; import org.onosproject.bgpio.util.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,15 +29,15 @@ import com.google.common.base.MoreObjects; /** * Implementation of Node Identifier which includes local node descriptor/remote node descriptors. */ -public class BGPNodeLSIdentifier { +public class BgpNodeLSIdentifier implements Comparable { - protected static final Logger log = LoggerFactory.getLogger(BGPNodeLSIdentifier.class); + private static final Logger log = LoggerFactory.getLogger(BgpNodeLSIdentifier.class); private NodeDescriptors nodeDescriptors; /** * Resets fields. */ - public BGPNodeLSIdentifier() { + public BgpNodeLSIdentifier() { this.nodeDescriptors = null; } @@ -46,7 +46,7 @@ public class BGPNodeLSIdentifier { * * @param nodeDescriptors local/remote node descriptor */ - public BGPNodeLSIdentifier(NodeDescriptors nodeDescriptors) { + public BgpNodeLSIdentifier(NodeDescriptors nodeDescriptors) { this.nodeDescriptors = nodeDescriptors; } @@ -56,15 +56,16 @@ public class BGPNodeLSIdentifier { * @param cb ChannelBuffer * @param protocolId protocol identifier * @return object of this BGPNodeLSIdentifier - * @throws BGPParseException while parsing local node descriptors + * @throws BgpParseException while parsing local node descriptors */ - public static BGPNodeLSIdentifier parseLocalNodeDescriptors(ChannelBuffer cb, byte protocolId) - throws BGPParseException { - ChannelBuffer tempBuf = cb; + public static BgpNodeLSIdentifier parseLocalNodeDescriptors(ChannelBuffer cb, byte protocolId) + throws BgpParseException { + log.debug("parse Local node descriptor"); + ChannelBuffer tempBuf = cb.copy(); short type = cb.readShort(); short length = cb.readShort(); if (cb.readableBytes() < length) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(cb.readableBytes() + Constants.TYPE_AND_LEN)); } NodeDescriptors nodeDescriptors = new NodeDescriptors(); @@ -73,9 +74,9 @@ public class BGPNodeLSIdentifier { if (type == NodeDescriptors.LOCAL_NODE_DES_TYPE) { nodeDescriptors = NodeDescriptors.read(tempCb, length, type, protocolId); } else { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.MALFORMED_ATTRIBUTE_LIST, null); } - return new BGPNodeLSIdentifier(nodeDescriptors); + return new BgpNodeLSIdentifier(nodeDescriptors); } /** @@ -92,8 +93,8 @@ public class BGPNodeLSIdentifier { if (this == obj) { return true; } - if (obj instanceof BGPNodeLSIdentifier) { - BGPNodeLSIdentifier other = (BGPNodeLSIdentifier) obj; + if (obj instanceof BgpNodeLSIdentifier) { + BgpNodeLSIdentifier other = (BgpNodeLSIdentifier) obj; return Objects.equals(nodeDescriptors, other.nodeDescriptors); } return false; @@ -110,4 +111,12 @@ public class BGPNodeLSIdentifier { .add("NodeDescriptors", nodeDescriptors) .toString(); } + + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + return this.nodeDescriptors.compareTo(((BgpNodeLSIdentifier) o).nodeDescriptors); + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSNlriVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpNodeLSNlriVer4.java similarity index 78% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSNlriVer4.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpNodeLSNlriVer4.java index 54837ee8..b27096cf 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSNlriVer4.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpNodeLSNlriVer4.java @@ -16,10 +16,10 @@ package org.onosproject.bgpio.protocol.linkstate; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPNodeLSNlri; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpNodeLSNlri; import org.onosproject.bgpio.protocol.NlriType; -import org.onosproject.bgpio.types.BGPErrorType; +import org.onosproject.bgpio.types.BgpErrorType; import org.onosproject.bgpio.types.RouteDistinguisher; import org.onosproject.bgpio.util.Constants; import org.slf4j.Logger; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implementation of Node LS NLRI. */ -public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { +public class BgpNodeLSNlriVer4 implements BgpNodeLSNlri { /* *REFERENCE : draft-ietf-idr-ls-distribution-11 @@ -48,21 +48,21 @@ public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { Figure : The Node NLRI format */ - protected static final Logger log = LoggerFactory.getLogger(BGPNodeLSNlriVer4.class); + protected static final Logger log = LoggerFactory.getLogger(BgpNodeLSNlriVer4.class); public static final int NODE_NLRITYPE = 1; public static final int IDENTIFIER_LENGTH = 16; private long identifier; private byte protocolId; - private BGPNodeLSIdentifier localNodeDescriptors; + private BgpNodeLSIdentifier localNodeDescriptors; private RouteDistinguisher routeDistinguisher; private boolean isVpn; /** * Enum to provide PROTOCOLTYPE. */ - public enum PROTOCOLTYPE { - ISIS_LevelOne(1), ISIS_LevelTwo(2), OSPFv2(3), Direct(4), Static_Configuration(5), OSPFv3(6); + public enum ProtocolType { + ISIS_LEVEL_ONE(1), ISIS_LEVEL_TWO(2), OSPF_V2(3), DIRECT(4), STATIC_CONFIGURATION(5), OSPF_V3(6); int value; /** @@ -70,7 +70,7 @@ public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { * * @param val protocol type */ - PROTOCOLTYPE(int val) { + ProtocolType(int val) { value = val; } @@ -87,7 +87,7 @@ public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { /** * Reset fields. */ - public BGPNodeLSNlriVer4() { + public BgpNodeLSNlriVer4() { this.identifier = 0; this.protocolId = 0; this.localNodeDescriptors = null; @@ -104,7 +104,7 @@ public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { * @param isVpn true if VPN info is present * @param routeDistinguisher unique for each VPN */ - BGPNodeLSNlriVer4(long identifier, byte protocolId, BGPNodeLSIdentifier localNodeDescriptors, boolean isVpn, + public BgpNodeLSNlriVer4(long identifier, byte protocolId, BgpNodeLSIdentifier localNodeDescriptors, boolean isVpn, RouteDistinguisher routeDistinguisher) { this.identifier = identifier; this.protocolId = protocolId; @@ -120,9 +120,9 @@ public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { * @param afi Address Family Identifier * @param safi Subsequent Address Family Identifier * @return object of this class - * @throws BGPParseException while parsing node descriptors + * @throws BgpParseException while parsing node descriptors */ - public static BGPNodeLSNlriVer4 read(ChannelBuffer cb, short afi, byte safi) throws BGPParseException { + public static BgpNodeLSNlriVer4 read(ChannelBuffer cb, short afi, byte safi) throws BgpParseException { boolean isVpn = false; RouteDistinguisher routeDistinguisher = null; if ((afi == Constants.AFI_VALUE) && (safi == Constants.VPN_SAFI_VALUE)) { @@ -136,9 +136,9 @@ public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { long identifier = cb.readLong(); // Parse Local Node Descriptors - BGPNodeLSIdentifier localNodeDescriptors = new BGPNodeLSIdentifier(); - localNodeDescriptors = BGPNodeLSIdentifier.parseLocalNodeDescriptors(cb, protocolId); - return new BGPNodeLSNlriVer4(identifier, protocolId, localNodeDescriptors, isVpn, routeDistinguisher); + BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(); + localNodeDescriptors = BgpNodeLSIdentifier.parseLocalNodeDescriptors(cb, protocolId); + return new BgpNodeLSNlriVer4(identifier, protocolId, localNodeDescriptors, isVpn, routeDistinguisher); } @Override @@ -147,7 +147,7 @@ public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { } @Override - public BGPNodeLSIdentifier getLocalNodeDescriptors() { + public BgpNodeLSIdentifier getLocalNodeDescriptors() { return this.localNodeDescriptors; } @@ -175,27 +175,27 @@ public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { * * @param localNodeDescriptors node LS identifier to set */ - public void setNodeLSIdentifier(BGPNodeLSIdentifier localNodeDescriptors) { + public void setNodeLSIdentifier(BgpNodeLSIdentifier localNodeDescriptors) { this.localNodeDescriptors = localNodeDescriptors; } @Override - public PROTOCOLTYPE getProtocolId() throws BGPParseException { + public ProtocolType getProtocolId() throws BgpParseException { switch (protocolId) { case Constants.ISIS_LEVELONE: - return PROTOCOLTYPE.ISIS_LevelOne; + return ProtocolType.ISIS_LEVEL_ONE; case Constants.ISIS_LEVELTWO: - return PROTOCOLTYPE.ISIS_LevelTwo; + return ProtocolType.ISIS_LEVEL_TWO; case Constants.OSPFV2: - return PROTOCOLTYPE.OSPFv2; + return ProtocolType.OSPF_V2; case Constants.DIRECT: - return PROTOCOLTYPE.Direct; + return ProtocolType.DIRECT; case Constants.STATIC_CONFIGURATION: - return PROTOCOLTYPE.Static_Configuration; + return ProtocolType.STATIC_CONFIGURATION; case Constants.OSPFV3: - return PROTOCOLTYPE.OSPFv3; + return ProtocolType.OSPF_V3; default: - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixIPv4LSNlriVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpPrefixIPv4LSNlriVer4.java similarity index 78% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixIPv4LSNlriVer4.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpPrefixIPv4LSNlriVer4.java index 6d6f48b1..49cb74bd 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixIPv4LSNlriVer4.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpPrefixIPv4LSNlriVer4.java @@ -15,14 +15,14 @@ */ package org.onosproject.bgpio.protocol.linkstate; -import java.util.LinkedList; +import java.util.List; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPPrefixLSNlri; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpPrefixLSNlri; import org.onosproject.bgpio.protocol.NlriType; -import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSNlriVer4.PROTOCOLTYPE; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.types.RouteDistinguisher; import org.onosproject.bgpio.util.Constants; import org.slf4j.Logger; @@ -33,7 +33,7 @@ import com.google.common.base.MoreObjects; /** * Implementation of Prefix IPV4 LS NLRI. */ -public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { +public class BgpPrefixIPv4LSNlriVer4 implements BgpPrefixLSNlri { /* * REFERENCE : draft-ietf-idr-ls-distribution-11 @@ -53,7 +53,7 @@ public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { Figure : The IPv4/IPv6 Topology Prefix NLRI format */ - protected static final Logger log = LoggerFactory.getLogger(BGPPrefixIPv4LSNlriVer4.class); + protected static final Logger log = LoggerFactory.getLogger(BgpPrefixIPv4LSNlriVer4.class); public static final int PREFIX_IPV4_NLRITYPE = 3; public static final int IDENTIFIER_LENGTH = 16; @@ -61,12 +61,12 @@ public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { private byte protocolId; private RouteDistinguisher routeDistinguisher; private boolean isVpn; - private BGPPrefixLSIdentifier bgpPrefixLSIdentifier; + private BgpPrefixLSIdentifier bgpPrefixLSIdentifier; /** * Resets parameters. */ - public BGPPrefixIPv4LSNlriVer4() { + public BgpPrefixIPv4LSNlriVer4() { this.identifier = 0; this.protocolId = 0; this.bgpPrefixLSIdentifier = null; @@ -83,7 +83,7 @@ public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { * @param routeDistinguisher RouteDistinguisher * @param isVpn vpn availability in message */ - public BGPPrefixIPv4LSNlriVer4(long identifier, byte protocolId, BGPPrefixLSIdentifier bgpPrefixLSIdentifier, + public BgpPrefixIPv4LSNlriVer4(long identifier, byte protocolId, BgpPrefixLSIdentifier bgpPrefixLSIdentifier, RouteDistinguisher routeDistinguisher, boolean isVpn) { this.identifier = identifier; this.protocolId = protocolId; @@ -99,9 +99,9 @@ public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { * @param afi Address family identifier * @param safi Subsequent address family identifier * @return object of BGPPrefixIPv4LSNlriVer4 - * @throws BGPParseException while parsing Prefix LS Nlri + * @throws BgpParseException while parsing Prefix LS Nlri */ - public static BGPPrefixIPv4LSNlriVer4 read(ChannelBuffer cb, short afi, byte safi) throws BGPParseException { + public static BgpPrefixIPv4LSNlriVer4 read(ChannelBuffer cb, short afi, byte safi) throws BgpParseException { boolean isVpn = false; RouteDistinguisher routeDistinguisher = null; @@ -115,9 +115,9 @@ public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { byte protocolId = cb.readByte(); long identifier = cb.readLong(); - BGPPrefixLSIdentifier bgpPrefixLSIdentifier = new BGPPrefixLSIdentifier(); - bgpPrefixLSIdentifier = BGPPrefixLSIdentifier.parsePrefixIdendifier(cb, protocolId); - return new BGPPrefixIPv4LSNlriVer4(identifier, protocolId, bgpPrefixLSIdentifier, routeDistinguisher, isVpn); + BgpPrefixLSIdentifier bgpPrefixLSIdentifier = new BgpPrefixLSIdentifier(); + bgpPrefixLSIdentifier = BgpPrefixLSIdentifier.parsePrefixIdendifier(cb, protocolId); + return new BgpPrefixIPv4LSNlriVer4(identifier, protocolId, bgpPrefixLSIdentifier, routeDistinguisher, isVpn); } @Override @@ -140,27 +140,27 @@ public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { * * @param bgpPrefixLSIdentifier prefix identifier to set */ - public void setPrefixLSIdentifier(BGPPrefixLSIdentifier bgpPrefixLSIdentifier) { + public void setPrefixLSIdentifier(BgpPrefixLSIdentifier bgpPrefixLSIdentifier) { this.bgpPrefixLSIdentifier = bgpPrefixLSIdentifier; } @Override - public PROTOCOLTYPE getProtocolId() throws BGPParseException { + public ProtocolType getProtocolId() throws BgpParseException { switch (protocolId) { case Constants.ISIS_LEVELONE: - return PROTOCOLTYPE.ISIS_LevelOne; + return ProtocolType.ISIS_LEVEL_ONE; case Constants.ISIS_LEVELTWO: - return PROTOCOLTYPE.ISIS_LevelTwo; + return ProtocolType.ISIS_LEVEL_TWO; case Constants.OSPFV2: - return PROTOCOLTYPE.OSPFv2; + return ProtocolType.OSPF_V2; case Constants.DIRECT: - return PROTOCOLTYPE.Direct; + return ProtocolType.DIRECT; case Constants.STATIC_CONFIGURATION: - return PROTOCOLTYPE.Static_Configuration; + return ProtocolType.STATIC_CONFIGURATION; case Constants.OSPFV3: - return PROTOCOLTYPE.OSPFv3; + return ProtocolType.OSPF_V3; default: - throw new BGPParseException("protocol id not valid"); + throw new BgpParseException("protocol id not valid"); } } @@ -178,7 +178,7 @@ public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { * * @return Prefix Identifier */ - public BGPPrefixLSIdentifier getPrefixIdentifier() { + public BgpPrefixLSIdentifier getPrefixIdentifier() { return this.bgpPrefixLSIdentifier; } @@ -188,7 +188,7 @@ public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { } @Override - public LinkedList getPrefixdescriptor() { + public List getPrefixdescriptor() { return this.bgpPrefixLSIdentifier.getPrefixdescriptor(); } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixLSIdentifier.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpPrefixLSIdentifier.java similarity index 60% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixLSIdentifier.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpPrefixLSIdentifier.java index 23f41794..d3beaaee 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixLSIdentifier.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BgpPrefixLSIdentifier.java @@ -18,12 +18,14 @@ package org.onosproject.bgpio.protocol.linkstate; import java.util.Iterator; import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.types.IPReachabilityInformationTlv; import org.onosproject.bgpio.types.OSPFRouteTypeTlv; import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId; @@ -36,17 +38,17 @@ import com.google.common.base.MoreObjects; /** * Provides Implementation of Local node descriptors and prefix descriptors. */ -public class BGPPrefixLSIdentifier { +public class BgpPrefixLSIdentifier implements Comparable { - protected static final Logger log = LoggerFactory.getLogger(BGPPrefixLSIdentifier.class); + protected static final Logger log = LoggerFactory.getLogger(BgpPrefixLSIdentifier.class); public static final int TYPE_AND_LEN = 4; private NodeDescriptors localNodeDescriptors; - private LinkedList prefixDescriptor; + private List prefixDescriptor; /** * Resets parameters. */ - public BGPPrefixLSIdentifier() { + public BgpPrefixLSIdentifier() { this.localNodeDescriptors = null; this.prefixDescriptor = null; } @@ -57,7 +59,7 @@ public class BGPPrefixLSIdentifier { * @param localNodeDescriptors Local node descriptors * @param prefixDescriptor Prefix Descriptors */ - public BGPPrefixLSIdentifier(NodeDescriptors localNodeDescriptors, LinkedList prefixDescriptor) { + public BgpPrefixLSIdentifier(NodeDescriptors localNodeDescriptors, List prefixDescriptor) { this.localNodeDescriptors = localNodeDescriptors; this.prefixDescriptor = prefixDescriptor; } @@ -68,18 +70,18 @@ public class BGPPrefixLSIdentifier { * @param cb ChannelBuffer * @param protocolId protocol ID * @return object of this class - * @throws BGPParseException while parsing Prefix Identifier + * @throws BgpParseException while parsing Prefix Identifier */ - public static BGPPrefixLSIdentifier parsePrefixIdendifier(ChannelBuffer cb, byte protocolId) - throws BGPParseException { + public static BgpPrefixLSIdentifier parsePrefixIdendifier(ChannelBuffer cb, byte protocolId) + throws BgpParseException { //Parse Local Node descriptor NodeDescriptors localNodeDescriptors = new NodeDescriptors(); localNodeDescriptors = parseLocalNodeDescriptors(cb, protocolId); //Parse Prefix descriptor - LinkedList prefixDescriptor = new LinkedList<>(); + List prefixDescriptor = new LinkedList<>(); prefixDescriptor = parsePrefixDescriptors(cb); - return new BGPPrefixLSIdentifier(localNodeDescriptors, prefixDescriptor); + return new BgpPrefixLSIdentifier(localNodeDescriptors, prefixDescriptor); } /** @@ -88,16 +90,16 @@ public class BGPPrefixLSIdentifier { * @param cb ChannelBuffer * @param protocolId protocol identifier * @return LocalNodeDescriptors - * @throws BGPParseException while parsing local node descriptors + * @throws BgpParseException while parsing local node descriptors */ public static NodeDescriptors parseLocalNodeDescriptors(ChannelBuffer cb, byte protocolId) - throws BGPParseException { - ChannelBuffer tempBuf = cb; + throws BgpParseException { + ChannelBuffer tempBuf = cb.copy(); short type = cb.readShort(); short length = cb.readShort(); if (cb.readableBytes() < length) { //length + 4 implies data contains type, length and value - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); } NodeDescriptors localNodeDescriptors = new NodeDescriptors(); @@ -106,8 +108,8 @@ public class BGPPrefixLSIdentifier { if (type == NodeDescriptors.LOCAL_NODE_DES_TYPE) { localNodeDescriptors = NodeDescriptors.read(tempCb, length, type, protocolId); } else { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.MALFORMED_ATTRIBUTE_LIST, null); } return localNodeDescriptors; } @@ -117,22 +119,22 @@ public class BGPPrefixLSIdentifier { * * @param cb ChannelBuffer * @return list of prefix descriptors - * @throws BGPParseException while parsing list of prefix descriptors + * @throws BgpParseException while parsing list of prefix descriptors */ - public static LinkedList parsePrefixDescriptors(ChannelBuffer cb) throws BGPParseException { - LinkedList prefixDescriptor = new LinkedList<>(); - BGPValueType tlv = null; + public static List parsePrefixDescriptors(ChannelBuffer cb) throws BgpParseException { + LinkedList prefixDescriptor = new LinkedList<>(); + BgpValueType tlv = null; boolean isIpReachInfo = false; ChannelBuffer tempCb; int count = 0; while (cb.readableBytes() > 0) { - ChannelBuffer tempBuf = cb; + ChannelBuffer tempBuf = cb.copy(); short type = cb.readShort(); short length = cb.readShort(); if (cb.readableBytes() < length) { //length + 4 implies data contains type, length and value - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); } tempCb = cb.readBytes(length); @@ -149,8 +151,8 @@ public class BGPPrefixLSIdentifier { count = count + 1; if (count > 1) { //length + 4 implies data contains type, length and value - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length + TYPE_AND_LEN)); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length + TYPE_AND_LEN)); } break; default: @@ -160,7 +162,7 @@ public class BGPPrefixLSIdentifier { } if (!isIpReachInfo) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, null); } return prefixDescriptor; @@ -180,7 +182,7 @@ public class BGPPrefixLSIdentifier { * * @return Prefix descriptors */ - public LinkedList getPrefixdescriptor() { + public List getPrefixdescriptor() { return this.prefixDescriptor; } @@ -195,22 +197,26 @@ public class BGPPrefixLSIdentifier { return true; } - if (obj instanceof BGPPrefixLSIdentifier) { + if (obj instanceof BgpPrefixLSIdentifier) { int countObjSubTlv = 0; int countOtherSubTlv = 0; boolean isCommonSubTlv = true; - BGPPrefixLSIdentifier other = (BGPPrefixLSIdentifier) obj; + BgpPrefixLSIdentifier other = (BgpPrefixLSIdentifier) obj; - Iterator objListIterator = other.prefixDescriptor.iterator(); + Iterator objListIterator = other.prefixDescriptor.iterator(); countOtherSubTlv = other.prefixDescriptor.size(); countObjSubTlv = prefixDescriptor.size(); if (countObjSubTlv != countOtherSubTlv) { return false; } else { while (objListIterator.hasNext() && isCommonSubTlv) { - BGPValueType subTlv = objListIterator.next(); - isCommonSubTlv = Objects.equals(prefixDescriptor.contains(subTlv), - other.prefixDescriptor.contains(subTlv)); + BgpValueType subTlv = objListIterator.next(); + if (prefixDescriptor.contains(subTlv) && other.prefixDescriptor.contains(subTlv)) { + isCommonSubTlv = Objects.equals(prefixDescriptor.get(prefixDescriptor.indexOf(subTlv)), + other.prefixDescriptor.get(other.prefixDescriptor.indexOf(subTlv))); + } else { + isCommonSubTlv = false; + } } return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors); } @@ -225,4 +231,41 @@ public class BGPPrefixLSIdentifier { .add("prefixDescriptor", prefixDescriptor) .toString(); } + + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + int result = this.localNodeDescriptors.compareTo(((BgpPrefixLSIdentifier) o).localNodeDescriptors); + if (result != 0) { + return result; + } else { + int countOtherSubTlv = ((BgpPrefixLSIdentifier) o).prefixDescriptor.size(); + int countObjSubTlv = prefixDescriptor.size(); + if (countOtherSubTlv != countObjSubTlv) { + if (countOtherSubTlv > countObjSubTlv) { + return 1; + } else { + return -1; + } + } + + ListIterator listIterator = prefixDescriptor.listIterator(); + ListIterator listIteratorOther = ((BgpPrefixLSIdentifier) o).prefixDescriptor.listIterator(); + while (listIterator.hasNext()) { + BgpValueType tlv = listIterator.next(); + BgpValueType tlv1 = listIteratorOther.next(); + if (prefixDescriptor.contains(tlv) && ((BgpPrefixLSIdentifier) o).prefixDescriptor.contains(tlv1)) { + int res = prefixDescriptor.get(prefixDescriptor.indexOf(tlv)).compareTo( + ((BgpPrefixLSIdentifier) o).prefixDescriptor + .get(((BgpPrefixLSIdentifier) o).prefixDescriptor.indexOf(tlv1))); + if (res != 0) { + return res; + } + } + } + } + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/NodeDescriptors.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/NodeDescriptors.java index 74637c7e..7fb1b316 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/NodeDescriptors.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/NodeDescriptors.java @@ -18,15 +18,17 @@ package org.onosproject.bgpio.protocol.linkstate; import java.util.Iterator; import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; import org.onosproject.bgpio.types.AreaIDTlv; import org.onosproject.bgpio.types.AutonomousSystemTlv; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPLSIdentifierTlv; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpLSIdentifierTlv; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.types.IsIsNonPseudonode; import org.onosproject.bgpio.types.IsIsPseudonode; import org.onosproject.bgpio.types.OSPFNonPseudonode; @@ -57,7 +59,7 @@ public class NodeDescriptors { Figure : Local or Remote Node Descriptors TLV format */ - protected static final Logger log = LoggerFactory.getLogger(NodeDescriptors.class); + private static final Logger log = LoggerFactory.getLogger(NodeDescriptors.class); public static final short LOCAL_NODE_DES_TYPE = 256; public static final short REMOTE_NODE_DES_TYPE = 257; @@ -71,7 +73,7 @@ public class NodeDescriptors { public static final int ISISPSEUDONODE_LEN = 7; public static final int OSPFNONPSEUDONODE_LEN = 4; public static final int OSPFPSEUDONODE_LEN = 8; - private LinkedList subTlvs; + private List subTlvs; private short deslength; private short desType; @@ -91,7 +93,7 @@ public class NodeDescriptors { * @param deslength Descriptors length * @param desType local node descriptor or remote node descriptor type */ - public NodeDescriptors(LinkedList subTlvs, short deslength, short desType) { + public NodeDescriptors(List subTlvs, short deslength, short desType) { this.subTlvs = subTlvs; this.deslength = deslength; this.desType = desType; @@ -102,7 +104,7 @@ public class NodeDescriptors { * * @return subTlvs list of subTlvs */ - public LinkedList getSubTlvs() { + public List getSubTlvs() { return subTlvs; } @@ -122,15 +124,20 @@ public class NodeDescriptors { int countOtherSubTlv = 0; boolean isCommonSubTlv = true; NodeDescriptors other = (NodeDescriptors) obj; - Iterator objListIterator = other.subTlvs.iterator(); + Iterator objListIterator = other.subTlvs.iterator(); countOtherSubTlv = other.subTlvs.size(); countObjSubTlv = subTlvs.size(); if (countObjSubTlv != countOtherSubTlv) { return false; } else { while (objListIterator.hasNext() && isCommonSubTlv) { - BGPValueType subTlv = objListIterator.next(); - isCommonSubTlv = Objects.equals(subTlvs.contains(subTlv), other.subTlvs.contains(subTlv)); + BgpValueType subTlv = objListIterator.next(); + if (subTlvs.contains(subTlv) && other.subTlvs.contains(subTlv)) { + isCommonSubTlv = Objects.equals(subTlvs.get(subTlvs.indexOf(subTlv)), + other.subTlvs.get(other.subTlvs.indexOf(subTlv))); + } else { + isCommonSubTlv = false; + } } return isCommonSubTlv; } @@ -146,20 +153,20 @@ public class NodeDescriptors { * @param desType local node descriptor or remote node descriptor type * @param protocolId protocol ID * @return object of NodeDescriptors - * @throws BGPParseException while parsing node descriptors + * @throws BgpParseException while parsing node descriptors */ public static NodeDescriptors read(ChannelBuffer cb, short desLength, short desType, byte protocolId) - throws BGPParseException { - LinkedList subTlvs; - subTlvs = new LinkedList<>(); - BGPValueType tlv = null; + throws BgpParseException { + log.debug("Read NodeDescriptor"); + List subTlvs = new LinkedList<>(); + BgpValueType tlv = null; while (cb.readableBytes() > 0) { - ChannelBuffer tempBuf = cb; + ChannelBuffer tempBuf = cb.copy(); short type = cb.readShort(); short length = cb.readShort(); if (cb.readableBytes() < length) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); } ChannelBuffer tempCb = cb.readBytes(length); @@ -167,8 +174,8 @@ public class NodeDescriptors { case AutonomousSystemTlv.TYPE: tlv = AutonomousSystemTlv.read(tempCb); break; - case BGPLSIdentifierTlv.TYPE: - tlv = BGPLSIdentifierTlv.read(tempCb); + case BgpLSIdentifierTlv.TYPE: + tlv = BgpLSIdentifierTlv.read(tempCb); break; case AreaIDTlv.TYPE: tlv = AreaIDTlv.read(tempCb); @@ -222,4 +229,34 @@ public class NodeDescriptors { .add("subTlvs", subTlvs) .toString(); } + + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + ListIterator listIterator = subTlvs.listIterator(); + ListIterator listIteratorOther = ((NodeDescriptors) o).subTlvs.listIterator(); + int countOtherSubTlv = ((NodeDescriptors) o).subTlvs.size(); + int countObjSubTlv = subTlvs.size(); + if (countOtherSubTlv != countObjSubTlv) { + if (countOtherSubTlv > countObjSubTlv) { + return 1; + } else { + return -1; + } + } else { + while (listIterator.hasNext()) { + BgpValueType tlv = listIterator.next(); + BgpValueType tlv1 = listIteratorOther.next(); + if (subTlvs.contains(tlv) && ((NodeDescriptors) o).subTlvs.contains(tlv1)) { + int result = subTlvs.get(subTlvs.indexOf(tlv)).compareTo( + ((NodeDescriptors) o).subTlvs.get(((NodeDescriptors) o).subTlvs.indexOf(tlv1))); + if (result != 0) { + return result; + } + } + } + } + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/PathAttrNlriDetails.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/PathAttrNlriDetails.java new file mode 100755 index 00000000..9578ccfe --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/PathAttrNlriDetails.java @@ -0,0 +1,135 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.protocol.linkstate; + +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType; +import org.onosproject.bgpio.types.BgpValueType; + +import com.google.common.base.MoreObjects; + +/** + * This Class stores path Attributes, protocol ID and Identifier of LinkState NLRI. + */ +public class PathAttrNlriDetails { + private List pathAttributes; + private ProtocolType protocolID; + private long identifier; + + /** + * Sets path attribute with specified path attribute. + * + * @param pathAttributes in update message + */ + public void setPathAttribute(List pathAttributes) { + this.pathAttributes = pathAttributes; + } + + /** + * Returns path attributes. + * + * @return path attributes + */ + public List pathAttributes() { + return this.pathAttributes; + } + + /** + * Sets protocolID with specified protocolID. + * + * @param protocolID in linkstate nlri + */ + public void setProtocolID(ProtocolType protocolID) { + this.protocolID = protocolID; + } + + /** + * Returns protocolID. + * + * @return protocolID + */ + public ProtocolType protocolID() { + return this.protocolID; + } + + /** + * Sets identifier with specified identifier. + * + * @param identifier in linkstate nlri + */ + public void setIdentifier(long identifier) { + this.identifier = identifier; + } + + /** + * Returns Identifier. + * + * @return Identifier + */ + public long identifier() { + return this.identifier; + } + + @Override + public int hashCode() { + return Objects.hash(pathAttributes, protocolID, identifier); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof PathAttrNlriDetails) { + int countObjSubTlv = 0; + int countOtherSubTlv = 0; + boolean isCommonSubTlv = true; + PathAttrNlriDetails other = (PathAttrNlriDetails) obj; + Iterator objListIterator = other.pathAttributes.iterator(); + countOtherSubTlv = other.pathAttributes.size(); + countObjSubTlv = pathAttributes.size(); + if (countObjSubTlv != countOtherSubTlv) { + return false; + } else { + while (objListIterator.hasNext() && isCommonSubTlv) { + BgpValueType subTlv = objListIterator.next(); + if (pathAttributes.contains(subTlv) && other.pathAttributes.contains(subTlv)) { + isCommonSubTlv = Objects.equals(pathAttributes.get(pathAttributes.indexOf(subTlv)), + other.pathAttributes.get(other.pathAttributes.indexOf(subTlv))); + } else { + isCommonSubTlv = false; + } + } + return isCommonSubTlv && Objects.equals(identifier, other.identifier) + && Objects.equals(protocolID, other.protocolID); + } + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("identifier", identifier) + .add("protocolID", protocolID) + .add("pathAttributes", pathAttributes) + .toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/PathAttrNlriDetailsLocalRib.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/PathAttrNlriDetailsLocalRib.java new file mode 100755 index 00000000..4172ae46 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/PathAttrNlriDetailsLocalRib.java @@ -0,0 +1,122 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.onosproject.bgpio.protocol.linkstate; + +import java.util.Objects; + +import org.onlab.packet.IpAddress; +import com.google.common.base.MoreObjects; + +/** + * This Class stores path Attributes, protocol ID and Identifier of LinkState nlri. + */ +public class PathAttrNlriDetailsLocalRib { + + private IpAddress localRibIpAddress; + private long localRibAsNum; + private int localRibIdentifier; + private boolean isLocalRibIbgpSession; + private PathAttrNlriDetails localRibNlridetails; + + /** + * Constructor to initialize parameter. + * + * @param localRibIpAddress peer ip address + * @param localRibIdentifier peer identifier + * @param localRibAsNum peer As number + * @param isLocalRibIbgpSession flag to indicate is Ibgp session + * @param localRibNlridetails Nlri details + * + */ + public PathAttrNlriDetailsLocalRib(IpAddress localRibIpAddress, int localRibIdentifier, long localRibAsNum, + boolean isLocalRibIbgpSession, PathAttrNlriDetails localRibNlridetails) { + this.localRibIpAddress = localRibIpAddress; + this.localRibAsNum = localRibAsNum; + this.localRibIdentifier = localRibIdentifier; + this.isLocalRibIbgpSession = isLocalRibIbgpSession; + this.localRibNlridetails = localRibNlridetails; + } + + /** + * Gets the Ipaddress updated in local rib. + * + * @return localRibIpAddress ip address + */ + public IpAddress localRibIpAddress() { + return localRibIpAddress; + } + + /** + * Gets the autonomous system number updated in local rib. + * + * @return localRibAsNum autonomous system number + */ + public long localRibAsNum() { + return localRibAsNum; + } + + /** + * Gets the indetifier updated in local rib. + * + * @return localRibIdentifier identifier + */ + public int localRibIdentifier() { + return localRibIdentifier; + } + + /** + * Gets the bgp session type updated in local rib. + * + * @return isLocalRibIbgpSession session type + */ + public boolean isLocalRibIbgpSession() { + return isLocalRibIbgpSession; + } + + /** + * Returns local RIB Nlri details. + * + * @return localRibNlridetails Nlri details in local rib + */ + public PathAttrNlriDetails localRibNlridetails() { + return this.localRibNlridetails; + } + + @Override + public int hashCode() { + return Objects.hash(localRibIpAddress, localRibIdentifier, localRibAsNum, isLocalRibIbgpSession, + localRibNlridetails.hashCode()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof PathAttrNlriDetailsLocalRib) { + PathAttrNlriDetailsLocalRib other = (PathAttrNlriDetailsLocalRib) obj; + return Objects.equals(localRibIpAddress, other.localRibIpAddress) + && Objects.equals(localRibIdentifier, other.localRibIdentifier) + && Objects.equals(localRibAsNum, other.localRibAsNum) + && Objects.equals(isLocalRibIbgpSession, other.isLocalRibIbgpSession) + && Objects.equals(localRibNlridetails, other.localRibNlridetails); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).add("peerIdentifier", localRibIdentifier) + .add("localRibpathAttributes", localRibNlridetails.pathAttributes()).toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPFactoryVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPFactoryVer4.java deleted file mode 100755 index 32af3854..00000000 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPFactoryVer4.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bgpio.protocol.ver4; - -import org.onosproject.bgpio.protocol.BGPFactory; -import org.onosproject.bgpio.protocol.BGPKeepaliveMsg; -import org.onosproject.bgpio.protocol.BGPMessage; -import org.onosproject.bgpio.protocol.BGPMessageReader; -import org.onosproject.bgpio.protocol.BGPNotificationMsg; -import org.onosproject.bgpio.protocol.BGPOpenMsg; -import org.onosproject.bgpio.protocol.BGPVersion; - -/** - * Provides BGP Factory and returns builder classes for all objects and messages. - */ -public class BGPFactoryVer4 implements BGPFactory { - - public static final BGPFactoryVer4 INSTANCE = new BGPFactoryVer4(); - - @Override - public BGPOpenMsg.Builder openMessageBuilder() { - return new BGPOpenMsgVer4.Builder(); - } - - @Override - public BGPKeepaliveMsg.Builder keepaliveMessageBuilder() { - return new BGPKeepaliveMsgVer4.Builder(); - } - - @Override - public BGPNotificationMsg.Builder notificationMessageBuilder() { - return new BGPNotificationMsgVer4.Builder(); - } - - @Override - public BGPMessageReader getReader() { - return BGPMessageVer4.READER; - } - - @Override - public BGPVersion getVersion() { - return BGPVersion.BGP_4; - } -} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpFactoryVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpFactoryVer4.java new file mode 100755 index 00000000..c57832b6 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpFactoryVer4.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.bgpio.protocol.ver4; + +import org.onosproject.bgpio.protocol.BgpFactory; +import org.onosproject.bgpio.protocol.BgpKeepaliveMsg; +import org.onosproject.bgpio.protocol.BgpMessage; +import org.onosproject.bgpio.protocol.BgpMessageReader; +import org.onosproject.bgpio.protocol.BgpNotificationMsg; +import org.onosproject.bgpio.protocol.BgpOpenMsg; +import org.onosproject.bgpio.protocol.BgpVersion; + +/** + * Provides BGP Factory and returns builder classes for all objects and messages. + */ +public class BgpFactoryVer4 implements BgpFactory { + + public static final BgpFactoryVer4 INSTANCE = new BgpFactoryVer4(); + + @Override + public BgpOpenMsg.Builder openMessageBuilder() { + return new BgpOpenMsgVer4.Builder(); + } + + @Override + public BgpKeepaliveMsg.Builder keepaliveMessageBuilder() { + return new BgpKeepaliveMsgVer4.Builder(); + } + + @Override + public BgpNotificationMsg.Builder notificationMessageBuilder() { + return new BgpNotificationMsgVer4.Builder(); + } + + @Override + public BgpMessageReader getReader() { + return BgpMessageVer4.READER; + } + + @Override + public BgpVersion getVersion() { + return BgpVersion.BGP_4; + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpKeepaliveMsgVer4.java similarity index 73% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpKeepaliveMsgVer4.java index 10e6bb95..2c141586 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPKeepaliveMsgVer4.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpKeepaliveMsgVer4.java @@ -16,13 +16,13 @@ package org.onosproject.bgpio.protocol.ver4; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPKeepaliveMsg; -import org.onosproject.bgpio.protocol.BGPMessageReader; -import org.onosproject.bgpio.protocol.BGPMessageWriter; -import org.onosproject.bgpio.types.BGPHeader; -import org.onosproject.bgpio.protocol.BGPType; -import org.onosproject.bgpio.protocol.BGPVersion; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpKeepaliveMsg; +import org.onosproject.bgpio.protocol.BgpMessageReader; +import org.onosproject.bgpio.protocol.BgpMessageWriter; +import org.onosproject.bgpio.types.BgpHeader; +import org.onosproject.bgpio.protocol.BgpType; +import org.onosproject.bgpio.protocol.BgpVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,7 +31,7 @@ import com.google.common.base.MoreObjects; /** * Provides BGP keep alive message. */ -class BGPKeepaliveMsgVer4 implements BGPKeepaliveMsg { +public class BgpKeepaliveMsgVer4 implements BgpKeepaliveMsg { /* ::= @@ -56,56 +56,56 @@ class BGPKeepaliveMsgVer4 implements BGPKeepaliveMsg { */ protected static final Logger log = LoggerFactory - .getLogger(BGPKeepaliveMsgVer4.class); + .getLogger(BgpKeepaliveMsgVer4.class); - private BGPHeader bgpMsgHeader; + private BgpHeader bgpMsgHeader; public static final byte PACKET_VERSION = 4; public static final int PACKET_MINIMUM_LENGTH = 19; public static final int MARKER_LENGTH = 16; - public static final BGPType MSG_TYPE = BGPType.KEEP_ALIVE; + public static final BgpType MSG_TYPE = BgpType.KEEP_ALIVE; public static byte[] marker = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}; - public static final BGPKeepaliveMsgVer4.Reader READER = new Reader(); + public static final BgpKeepaliveMsgVer4.Reader READER = new Reader(); /** * Reader class for reading BGP keepalive message from channel buffer. */ - static class Reader implements BGPMessageReader { + static class Reader implements BgpMessageReader { @Override - public BGPKeepaliveMsg readFrom(ChannelBuffer cb, BGPHeader bgpHeader) - throws BGPParseException { + public BgpKeepaliveMsg readFrom(ChannelBuffer cb, BgpHeader bgpHeader) + throws BgpParseException { /* bgpHeader is not required in case of keepalive message and Header is already read and no other fields except header in keepalive message.*/ - return new BGPKeepaliveMsgVer4(); + return new BgpKeepaliveMsgVer4(); } } /** * Default constructor. */ - BGPKeepaliveMsgVer4() { + public BgpKeepaliveMsgVer4() { } /** * Builder class for BGP keepalive message. */ - static class Builder implements BGPKeepaliveMsg.Builder { - BGPHeader bgpMsgHeader; + static class Builder implements BgpKeepaliveMsg.Builder { + BgpHeader bgpMsgHeader; @Override - public Builder setHeader(BGPHeader bgpMsgHeader) { + public Builder setHeader(BgpHeader bgpMsgHeader) { this.bgpMsgHeader = bgpMsgHeader; return this; } @Override - public BGPKeepaliveMsg build() { - return new BGPKeepaliveMsgVer4(); + public BgpKeepaliveMsg build() { + return new BgpKeepaliveMsgVer4(); } } @@ -119,10 +119,10 @@ class BGPKeepaliveMsgVer4 implements BGPKeepaliveMsg { /** * Writer class for writing the BGP keepalive message to channel buffer. */ - static class Writer implements BGPMessageWriter { + static class Writer implements BgpMessageWriter { @Override - public void write(ChannelBuffer cb, BGPKeepaliveMsgVer4 message) { + public void write(ChannelBuffer cb, BgpKeepaliveMsgVer4 message) { // write marker cb.writeBytes(marker, 0, MARKER_LENGTH); @@ -136,17 +136,17 @@ class BGPKeepaliveMsgVer4 implements BGPKeepaliveMsg { } @Override - public BGPVersion getVersion() { - return BGPVersion.BGP_4; + public BgpVersion getVersion() { + return BgpVersion.BGP_4; } @Override - public BGPType getType() { + public BgpType getType() { return MSG_TYPE; } @Override - public BGPHeader getHeader() { + public BgpHeader getHeader() { return this.bgpMsgHeader; } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPMessageVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpMessageVer4.java similarity index 61% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPMessageVer4.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpMessageVer4.java index d45e3de1..1c05dae4 100755 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPMessageVer4.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpMessageVer4.java @@ -17,12 +17,12 @@ package org.onosproject.bgpio.protocol.ver4; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPFactories; -import org.onosproject.bgpio.protocol.BGPMessage; -import org.onosproject.bgpio.protocol.BGPMessageReader; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpFactories; +import org.onosproject.bgpio.protocol.BgpMessage; +import org.onosproject.bgpio.protocol.BgpMessageReader; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpHeader; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,9 +30,9 @@ import org.slf4j.LoggerFactory; /** * Provides BGP messages. */ -public abstract class BGPMessageVer4 { +public abstract class BgpMessageVer4 { - protected static final Logger log = LoggerFactory.getLogger(BGPFactories.class); + protected static final Logger log = LoggerFactory.getLogger(BgpFactories.class); static final byte OPEN_MSG_TYPE = 0x1; static final byte KEEPALIVE_MSG_TYPE = 0x4; @@ -42,41 +42,42 @@ public abstract class BGPMessageVer4 { static final int HEADER_AND_MSG_LEN = 18; static final int MAXIMUM_PACKET_LENGTH = 4096; - public static final BGPMessageVer4.Reader READER = new Reader(); + public static final BgpMessageVer4.Reader READER = new Reader(); /** * Reader class for reading BGP messages from channel buffer. * */ - static class Reader implements BGPMessageReader { + static class Reader implements BgpMessageReader { @Override - public BGPMessage readFrom(ChannelBuffer cb, BGPHeader bgpHeader) - throws BGPParseException { + public BgpMessage readFrom(ChannelBuffer cb, BgpHeader bgpHeader) + throws BgpParseException { if (cb.readableBytes() < MINIMUM_COMMON_HEADER_LENGTH) { log.error("Packet should have minimum length."); - Validation.validateLen(BGPErrorType.MESSAGE_HEADER_ERROR, BGPErrorType.BAD_MESSAGE_LENGTH, + Validation.validateLen(BgpErrorType.MESSAGE_HEADER_ERROR, BgpErrorType.BAD_MESSAGE_LENGTH, cb.readableBytes()); } if (cb.readableBytes() > MAXIMUM_PACKET_LENGTH) { log.error("Packet length should not exceed {}.", MAXIMUM_PACKET_LENGTH); - Validation.validateLen(BGPErrorType.MESSAGE_HEADER_ERROR, BGPErrorType.BAD_MESSAGE_LENGTH, + Validation.validateLen(BgpErrorType.MESSAGE_HEADER_ERROR, BgpErrorType.BAD_MESSAGE_LENGTH, cb.readableBytes()); } try { // fixed value property version == 4 - byte[] marker = new byte[BGPHeader.MARKER_LENGTH]; - cb.readBytes(marker, 0, BGPHeader.MARKER_LENGTH); + byte[] marker = new byte[BgpHeader.MARKER_LENGTH]; + cb.readBytes(marker, 0, BgpHeader.MARKER_LENGTH); bgpHeader.setMarker(marker); - for (int i = 0; i < BGPHeader.MARKER_LENGTH; i++) { + for (int i = 0; i < BgpHeader.MARKER_LENGTH; i++) { if (marker[i] != (byte) 0xff) { - throw new BGPParseException(BGPErrorType.MESSAGE_HEADER_ERROR, - BGPErrorType.CONNECTION_NOT_SYNCHRONIZED, null); + throw new BgpParseException(BgpErrorType.MESSAGE_HEADER_ERROR, + BgpErrorType.CONNECTION_NOT_SYNCHRONIZED, null); } } short length = cb.readShort(); - if (length != (cb.readableBytes() + HEADER_AND_MSG_LEN)) { - Validation.validateLen(BGPErrorType.MESSAGE_HEADER_ERROR, BGPErrorType.BAD_MESSAGE_LENGTH, length); + if (length > cb.readableBytes() + HEADER_AND_MSG_LEN) { + Validation.validateLen(BgpErrorType.MESSAGE_HEADER_ERROR, + BgpErrorType.BAD_MESSAGE_LENGTH, length); } bgpHeader.setLength(length); byte type = cb.readByte(); @@ -87,22 +88,23 @@ public abstract class BGPMessageVer4 { switch (type) { case OPEN_MSG_TYPE: log.debug("OPEN MESSAGE is received"); - return BGPOpenMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader); + return BgpOpenMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader); case KEEPALIVE_MSG_TYPE: log.debug("KEEPALIVE MESSAGE is received"); - return BGPKeepaliveMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader); + return BgpKeepaliveMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader); case UPDATE_MSG_TYPE: log.debug("UPDATE MESSAGE is received"); - // TODO: Update message version 4 + return BgpUpdateMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader); case NOTIFICATION_MSG_TYPE: log.debug("NOTIFICATION MESSAGE is received"); - return BGPNotificationMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader); + return BgpNotificationMsgVer4.READER.readFrom(cb.readBytes(len), bgpHeader); default: - Validation.validateType(BGPErrorType.MESSAGE_HEADER_ERROR, BGPErrorType.BAD_MESSAGE_TYPE, type); + Validation.validateType(BgpErrorType.MESSAGE_HEADER_ERROR, BgpErrorType.BAD_MESSAGE_TYPE, type); return null; } } catch (IndexOutOfBoundsException e) { - throw new BGPParseException(BGPErrorType.MESSAGE_HEADER_ERROR, BGPErrorType.BAD_MESSAGE_LENGTH, null); + throw new BgpParseException(BgpErrorType.MESSAGE_HEADER_ERROR, + BgpErrorType.BAD_MESSAGE_LENGTH, null); } } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpNotificationMsgVer4.java similarity index 74% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpNotificationMsgVer4.java index 3bddd375..d25db24e 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPNotificationMsgVer4.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpNotificationMsgVer4.java @@ -16,14 +16,14 @@ package org.onosproject.bgpio.protocol.ver4; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPMessageReader; -import org.onosproject.bgpio.protocol.BGPMessageWriter; -import org.onosproject.bgpio.protocol.BGPNotificationMsg; -import org.onosproject.bgpio.protocol.BGPType; -import org.onosproject.bgpio.protocol.BGPVersion; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpMessageReader; +import org.onosproject.bgpio.protocol.BgpMessageWriter; +import org.onosproject.bgpio.protocol.BgpNotificationMsg; +import org.onosproject.bgpio.protocol.BgpType; +import org.onosproject.bgpio.protocol.BgpVersion; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpHeader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +33,7 @@ import com.google.common.base.MoreObjects; * A NOTIFICATION message is sent when an error condition is detected. The BGP connection is closed immediately after it * is sent. */ -class BGPNotificationMsgVer4 implements BGPNotificationMsg { +class BgpNotificationMsgVer4 implements BgpNotificationMsg { /* 0 1 2 3 @@ -44,32 +44,32 @@ class BGPNotificationMsgVer4 implements BGPNotificationMsg { REFERENCE : RFC 4271 */ - private static final Logger log = LoggerFactory.getLogger(BGPNotificationMsgVer4.class); + private static final Logger log = LoggerFactory.getLogger(BgpNotificationMsgVer4.class); static final byte PACKET_VERSION = 4; //BGPHeader(19) + Error code(1) + Error subcode(1) static final int TOTAL_MESSAGE_MIN_LENGTH = 21; static final int PACKET_MINIMUM_LENGTH = 2; - static final BGPType MSG_TYPE = BGPType.NOTIFICATION; + static final BgpType MSG_TYPE = BgpType.NOTIFICATION; static final byte DEFAULT_ERRORSUBCODE = 0; static final byte[] MARKER = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; static final byte MESSAGE_TYPE = 3; - static final BGPHeader DEFAULT_MESSAGE_HEADER = new BGPHeader(MARKER, BGPHeader.DEFAULT_HEADER_LENGTH, + static final BgpHeader DEFAULT_MESSAGE_HEADER = new BgpHeader(MARKER, BgpHeader.DEFAULT_HEADER_LENGTH, MESSAGE_TYPE); private byte errorCode; private byte errorSubCode; private byte[] data; - private BGPHeader bgpHeader; - public static final BGPNotificationMsgVer4.Reader READER = new Reader(); + private BgpHeader bgpHeader; + public static final BgpNotificationMsgVer4.Reader READER = new Reader(); /** * Initialize fields. */ - public BGPNotificationMsgVer4() { + public BgpNotificationMsgVer4() { this.bgpHeader = null; this.data = null; this.errorCode = 0; @@ -84,7 +84,7 @@ class BGPNotificationMsgVer4 implements BGPNotificationMsg { * @param errorSubCode error subcode * @param data field */ - public BGPNotificationMsgVer4(BGPHeader bgpHeader, byte errorCode, byte errorSubCode, byte[] data) { + public BgpNotificationMsgVer4(BgpHeader bgpHeader, byte errorCode, byte errorSubCode, byte[] data) { this.bgpHeader = bgpHeader; this.data = data; this.errorCode = errorCode; @@ -94,13 +94,13 @@ class BGPNotificationMsgVer4 implements BGPNotificationMsg { /** * Reader reads BGP Notification Message from the channel buffer. */ - static class Reader implements BGPMessageReader { + static class Reader implements BgpMessageReader { @Override - public BGPNotificationMsg readFrom(ChannelBuffer cb, BGPHeader bgpHeader) throws BGPParseException { + public BgpNotificationMsg readFrom(ChannelBuffer cb, BgpHeader bgpHeader) throws BgpParseException { byte errorCode; byte errorSubCode; if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) { - throw new BGPParseException("Not enough readable bytes"); + throw new BgpParseException("Not enough readable bytes"); } errorCode = cb.readByte(); errorSubCode = cb.readByte(); @@ -108,31 +108,31 @@ class BGPNotificationMsgVer4 implements BGPNotificationMsg { int dataLength = bgpHeader.getLength() - TOTAL_MESSAGE_MIN_LENGTH; byte[] data = new byte[dataLength]; cb.readBytes(data, 0, dataLength); - return new BGPNotificationMsgVer4(bgpHeader, errorCode, errorSubCode, data); + return new BgpNotificationMsgVer4(bgpHeader, errorCode, errorSubCode, data); } } /** * Builder class for BGP notification message. */ - static class Builder implements BGPNotificationMsg.Builder { + static class Builder implements BgpNotificationMsg.Builder { private byte errorCode; private byte errorSubCode; private byte[] data; - private BGPHeader bgpHeader; + private BgpHeader bgpHeader; private boolean isErrorCodeSet = false; private boolean isErrorSubCodeSet = false; private boolean isBGPHeaderSet = false; @Override - public BGPNotificationMsg build() throws BGPParseException { - BGPHeader bgpHeader = this.isBGPHeaderSet ? this.bgpHeader : DEFAULT_MESSAGE_HEADER; + public BgpNotificationMsg build() throws BgpParseException { + BgpHeader bgpHeader = this.isBGPHeaderSet ? this.bgpHeader : DEFAULT_MESSAGE_HEADER; if (!this.isErrorCodeSet) { - throw new BGPParseException("Error code must be present"); + throw new BgpParseException("Error code must be present"); } byte errorSubCode = this.isErrorSubCodeSet ? this.errorSubCode : DEFAULT_ERRORSUBCODE; - return new BGPNotificationMsgVer4(bgpHeader, this.errorCode, errorSubCode, this.data); + return new BgpNotificationMsgVer4(bgpHeader, this.errorCode, errorSubCode, this.data); } @Override @@ -151,29 +151,31 @@ class BGPNotificationMsgVer4 implements BGPNotificationMsg { @Override public Builder setData(byte[] data) { - this.data = data; + if (data != null) { + this.data = data; + } return this; } @Override - public Builder setHeader(BGPHeader bgpMsgHeader) { + public Builder setHeader(BgpHeader bgpMsgHeader) { this.bgpHeader = bgpMsgHeader; return this; } } @Override - public BGPVersion getVersion() { - return BGPVersion.BGP_4; + public BgpVersion getVersion() { + return BgpVersion.BGP_4; } @Override - public BGPType getType() { - return BGPType.NOTIFICATION; + public BgpType getType() { + return BgpType.NOTIFICATION; } @Override - public void writeTo(ChannelBuffer cb) throws BGPParseException { + public void writeTo(ChannelBuffer cb) throws BgpParseException { WRITER.write(cb, this); } @@ -182,13 +184,13 @@ class BGPNotificationMsgVer4 implements BGPNotificationMsg { /** * Writer writes BGP notification message to channel buffer. */ - static class Writer implements BGPMessageWriter { + static class Writer implements BgpMessageWriter { @Override - public void write(ChannelBuffer cb, BGPNotificationMsgVer4 message) throws BGPParseException { + public void write(ChannelBuffer cb, BgpNotificationMsgVer4 message) throws BgpParseException { int msgStartIndex = cb.writerIndex(); int headerLenIndex = message.bgpHeader.write(cb); if (headerLenIndex <= 0) { - throw new BGPParseException(BGPErrorType.MESSAGE_HEADER_ERROR, (byte) 0, null); + throw new BgpParseException(BgpErrorType.MESSAGE_HEADER_ERROR, (byte) 0, null); } cb.writeByte(message.errorCode); cb.writeByte(message.errorSubCode); @@ -244,7 +246,7 @@ class BGPNotificationMsgVer4 implements BGPNotificationMsg { } @Override - public BGPHeader getHeader() { + public BgpHeader getHeader() { return this.bgpHeader; } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java similarity index 79% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java index fccbf5f7..359eec25 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BGPOpenMsgVer4.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpOpenMsgVer4.java @@ -19,15 +19,15 @@ import java.util.LinkedList; import java.util.ListIterator; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPMessageReader; -import org.onosproject.bgpio.protocol.BGPMessageWriter; -import org.onosproject.bgpio.protocol.BGPOpenMsg; -import org.onosproject.bgpio.protocol.BGPType; -import org.onosproject.bgpio.protocol.BGPVersion; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPHeader; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpMessageReader; +import org.onosproject.bgpio.protocol.BgpMessageWriter; +import org.onosproject.bgpio.protocol.BgpOpenMsg; +import org.onosproject.bgpio.protocol.BgpType; +import org.onosproject.bgpio.protocol.BgpVersion; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpHeader; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv; import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv; import org.onosproject.bgpio.util.Validation; @@ -39,7 +39,7 @@ import com.google.common.base.MoreObjects; /** * Provides BGP open message. */ -public class BGPOpenMsgVer4 implements BGPOpenMsg { +public class BgpOpenMsgVer4 implements BgpOpenMsg { /* 0 1 2 3 @@ -61,7 +61,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { REFERENCE : RFC 4271 */ - protected static final Logger log = LoggerFactory.getLogger(BGPOpenMsgVer4.class); + protected static final Logger log = LoggerFactory.getLogger(BgpOpenMsgVer4.class); public static final byte PACKET_VERSION = 4; public static final int OPEN_MSG_MINIMUM_LENGTH = 10; @@ -70,7 +70,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { public static final int DEFAULT_HOLD_TIME = 120; public static final short AS_TRANS = 23456; public static final int OPT_PARA_TYPE_CAPABILITY = 2; - public static final BGPType MSG_TYPE = BGPType.OPEN; + public static final BgpType MSG_TYPE = BgpType.OPEN; public static final short AFI = 16388; public static final byte SAFI = 71; public static final byte RES = 0; @@ -78,22 +78,22 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { public static final byte[] MARKER = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}; - public static final BGPHeader DEFAULT_OPEN_HEADER = new BGPHeader(MARKER, + public static final BgpHeader DEFAULT_OPEN_HEADER = new BgpHeader(MARKER, (short) OPEN_MSG_MINIMUM_LENGTH, (byte) 0X01); - private BGPHeader bgpMsgHeader; + private BgpHeader bgpMsgHeader; private byte version; private short asNumber; private short holdTime; private int bgpId; private boolean isLargeAsCapabilitySet; - private LinkedList capabilityTlv; + private LinkedList capabilityTlv; - public static final BGPOpenMsgVer4.Reader READER = new Reader(); + public static final BgpOpenMsgVer4.Reader READER = new Reader(); /** * reset variables. */ - public BGPOpenMsgVer4() { + public BgpOpenMsgVer4() { this.bgpMsgHeader = null; this.version = 0; this.holdTime = 0; @@ -112,8 +112,8 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { * @param bgpId BGP identifier in open message * @param capabilityTlv capabilities in open message */ - public BGPOpenMsgVer4(BGPHeader bgpMsgHeader, byte version, short asNumber, short holdTime, - int bgpId, LinkedList capabilityTlv) { + public BgpOpenMsgVer4(BgpHeader bgpMsgHeader, byte version, short asNumber, short holdTime, + int bgpId, LinkedList capabilityTlv) { this.bgpMsgHeader = bgpMsgHeader; this.version = version; this.asNumber = asNumber; @@ -123,17 +123,17 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { } @Override - public BGPHeader getHeader() { + public BgpHeader getHeader() { return this.bgpMsgHeader; } @Override - public BGPVersion getVersion() { - return BGPVersion.BGP_4; + public BgpVersion getVersion() { + return BgpVersion.BGP_4; } @Override - public BGPType getType() { + public BgpType getType() { return MSG_TYPE; } @@ -153,17 +153,17 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { } @Override - public LinkedList getCapabilityTlv() { + public LinkedList getCapabilityTlv() { return this.capabilityTlv; } /** * Reader class for reading BGP open message from channel buffer. */ - public static class Reader implements BGPMessageReader { + public static class Reader implements BgpMessageReader { @Override - public BGPOpenMsg readFrom(ChannelBuffer cb, BGPHeader bgpHeader) throws BGPParseException { + public BgpOpenMsg readFrom(ChannelBuffer cb, BgpHeader bgpHeader) throws BgpParseException { byte version; short holdTime; @@ -172,11 +172,11 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { byte optParaLen = 0; byte optParaType; byte capParaLen = 0; - LinkedList capabilityTlv = new LinkedList<>(); + LinkedList capabilityTlv = new LinkedList<>(); if (cb.readableBytes() < OPEN_MSG_MINIMUM_LENGTH) { log.error("[readFrom] Invalid length: Packet size is less than the minimum length "); - Validation.validateLen(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_MESSAGE_LENGTH, + Validation.validateLen(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.BAD_MESSAGE_LENGTH, cb.readableBytes()); } @@ -184,8 +184,8 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { version = cb.readByte(); if (version != PACKET_VERSION) { log.error("[readFrom] Invalid version: " + version); - throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, - BGPErrorType.UNSUPPORTED_VERSION_NUMBER, null); + throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, + BgpErrorType.UNSUPPORTED_VERSION_NUMBER, null); } // Read AS number @@ -209,7 +209,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { capParaLen = cb.readByte(); if (cb.readableBytes() < capParaLen) { - throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, (byte) 0, null); + throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, (byte) 0, null); } ChannelBuffer capaCb = cb.readBytes(capParaLen); @@ -218,11 +218,11 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { if ((optParaType == OPT_PARA_TYPE_CAPABILITY) && (capParaLen != 0)) { capabilityTlv = parseCapabilityTlv(capaCb); } else { - throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, - BGPErrorType.UNSUPPORTED_OPTIONAL_PARAMETER, null); + throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, + BgpErrorType.UNSUPPORTED_OPTIONAL_PARAMETER, null); } } - return new BGPOpenMsgVer4(bgpHeader, version, asNumber, holdTime, bgpId, capabilityTlv); + return new BgpOpenMsgVer4(bgpHeader, version, asNumber, holdTime, bgpId, capabilityTlv); } } @@ -231,14 +231,14 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { * * @param cb of type channel buffer * @return capabilityTlv of open message - * @throws BGPParseException while parsing capabilities + * @throws BgpParseException while parsing capabilities */ - protected static LinkedList parseCapabilityTlv(ChannelBuffer cb) throws BGPParseException { + protected static LinkedList parseCapabilityTlv(ChannelBuffer cb) throws BgpParseException { - LinkedList capabilityTlv = new LinkedList<>(); + LinkedList capabilityTlv = new LinkedList<>(); while (cb.readableBytes() > 0) { - BGPValueType tlv; + BgpValueType tlv; short type = cb.readByte(); short length = cb.readByte(); @@ -246,10 +246,10 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { case FourOctetAsNumCapabilityTlv.TYPE: log.debug("FourOctetAsNumCapabilityTlv"); if (FourOctetAsNumCapabilityTlv.LENGTH != length) { - throw new BGPParseException("Invalid length received for FourOctetAsNumCapabilityTlv."); + throw new BgpParseException("Invalid length received for FourOctetAsNumCapabilityTlv."); } if (length > cb.readableBytes()) { - throw new BGPParseException("Four octet as num tlv length" + throw new BgpParseException("Four octet as num tlv length" + " is more than readableBytes."); } int as4Num = cb.readInt(); @@ -258,10 +258,10 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { case MultiProtocolExtnCapabilityTlv.TYPE: log.debug("MultiProtocolExtnCapabilityTlv"); if (MultiProtocolExtnCapabilityTlv.LENGTH != length) { - throw new BGPParseException("Invalid length received for MultiProtocolExtnCapabilityTlv."); + throw new BgpParseException("Invalid length received for MultiProtocolExtnCapabilityTlv."); } if (length > cb.readableBytes()) { - throw new BGPParseException("BGP LS tlv length is more than readableBytes."); + throw new BgpParseException("BGP LS tlv length is more than readableBytes."); } short afi = cb.readShort(); byte res = cb.readByte(); @@ -281,10 +281,10 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { /** * Builder class for BGP open message. */ - static class Builder implements BGPOpenMsg.Builder { + static class Builder implements BgpOpenMsg.Builder { private boolean isHeaderSet = false; - private BGPHeader bgpMsgHeader; + private BgpHeader bgpMsgHeader; private boolean isHoldTimeSet = false; private short holdTime; private boolean isAsNumSet = false; @@ -294,40 +294,40 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { private boolean isLargeAsCapabilityTlvSet = false; private boolean isLsCapabilityTlvSet = false; - LinkedList capabilityTlv = new LinkedList<>(); + LinkedList capabilityTlv = new LinkedList<>(); @Override - public BGPOpenMsg build() throws BGPParseException { - BGPHeader bgpMsgHeader = this.isHeaderSet ? this.bgpMsgHeader : DEFAULT_OPEN_HEADER; + public BgpOpenMsg build() throws BgpParseException { + BgpHeader bgpMsgHeader = this.isHeaderSet ? this.bgpMsgHeader : DEFAULT_OPEN_HEADER; short holdTime = this.isHoldTimeSet ? this.holdTime : DEFAULT_HOLD_TIME; if (!this.isAsNumSet) { - throw new BGPParseException("BGP AS number is not set (mandatory)"); + throw new BgpParseException("BGP AS number is not set (mandatory)"); } if (!this.isBgpIdSet) { - throw new BGPParseException("BGPID is not set (mandatory)"); + throw new BgpParseException("BGPID is not set (mandatory)"); } if (this.isLargeAsCapabilityTlvSet) { - BGPValueType tlv; + BgpValueType tlv; int value = this.asNumber; tlv = new FourOctetAsNumCapabilityTlv(value); this.capabilityTlv.add(tlv); } if (this.isLsCapabilityTlvSet) { - BGPValueType tlv; + BgpValueType tlv; tlv = new MultiProtocolExtnCapabilityTlv(AFI, RES, SAFI); this.capabilityTlv.add(tlv); } - return new BGPOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId, + return new BgpOpenMsgVer4(bgpMsgHeader, PACKET_VERSION, this.asNumber, holdTime, this.bgpId, this.capabilityTlv); } @Override - public Builder setHeader(BGPHeader bgpMsgHeader) { + public Builder setHeader(BgpHeader bgpMsgHeader) { this.bgpMsgHeader = bgpMsgHeader; return this; } @@ -354,7 +354,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { } @Override - public Builder setCapabilityTlv(LinkedList capabilityTlv) { + public Builder setCapabilityTlv(LinkedList capabilityTlv) { this.capabilityTlv = capabilityTlv; return this; } @@ -376,7 +376,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { public void writeTo(ChannelBuffer cb) { try { WRITER.write(cb, this); - } catch (BGPParseException e) { + } catch (BgpParseException e) { log.debug("[writeTo] Error: " + e.toString()); } } @@ -386,10 +386,10 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { /** * Writer class for writing BGP open message to channel buffer. */ - public static class Writer implements BGPMessageWriter { + public static class Writer implements BgpMessageWriter { @Override - public void write(ChannelBuffer cb, BGPOpenMsgVer4 message) throws BGPParseException { + public void write(ChannelBuffer cb, BgpOpenMsgVer4 message) throws BgpParseException { int optParaLen = 0; int as4num = 0; @@ -400,7 +400,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { int msgLenIndex = message.bgpMsgHeader.write(cb); if (msgLenIndex <= 0) { - throw new BGPParseException("Unable to write message header."); + throw new BgpParseException("Unable to write message header."); } // write version in 1-octet @@ -408,13 +408,13 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { // get as4num if LS Capability is set if (message.isLargeAsCapabilitySet) { - LinkedList capabilityTlv = message + LinkedList capabilityTlv = message .getCapabilityTlv(); - ListIterator listIterator = capabilityTlv + ListIterator listIterator = capabilityTlv .listIterator(); while (listIterator.hasNext()) { - BGPValueType tlv = listIterator.next(); + BgpValueType tlv = listIterator.next(); if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) { as4num = ((FourOctetAsNumCapabilityTlv) tlv).getInt(); break; @@ -464,13 +464,13 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { * @param message of type BGPOpenMsgVer4 * @return capParaLen of open message */ - protected int packCapabilityTlv(ChannelBuffer cb, BGPOpenMsgVer4 message) { + protected int packCapabilityTlv(ChannelBuffer cb, BgpOpenMsgVer4 message) { int startIndex = cb.writerIndex(); int capParaLen = 0; int capParaLenIndex = 0; - LinkedList capabilityTlv = message.capabilityTlv; - ListIterator listIterator = capabilityTlv.listIterator(); + LinkedList capabilityTlv = message.capabilityTlv; + ListIterator listIterator = capabilityTlv.listIterator(); if (listIterator.hasNext()) { // Set optional parameter type as 2 @@ -487,7 +487,7 @@ public class BGPOpenMsgVer4 implements BGPOpenMsg { } while (listIterator.hasNext()) { - BGPValueType tlv = listIterator.next(); + BgpValueType tlv = listIterator.next(); if (tlv == null) { log.debug("Warning: tlv is null from CapabilityTlv list"); continue; diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpPathAttributes.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpPathAttributes.java index 20a7ba03..9ffddf68 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpPathAttributes.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpPathAttributes.java @@ -19,11 +19,11 @@ import java.util.LinkedList; import java.util.List; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; import org.onosproject.bgpio.types.As4Path; import org.onosproject.bgpio.types.AsPath; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.types.LocalPref; import org.onosproject.bgpio.types.Med; import org.onosproject.bgpio.types.NextHop; @@ -58,7 +58,7 @@ public class BgpPathAttributes { public static final int MPREACHNLRI_TYPE = 14; public static final int MPUNREACHNLRI_TYPE = 15; - private final List pathAttribute; + private final List pathAttribute; /** * Initialize parameter. @@ -72,7 +72,7 @@ public class BgpPathAttributes { * * @param pathAttribute list of path attributes */ - public BgpPathAttributes(List pathAttribute) { + public BgpPathAttributes(List pathAttribute) { this.pathAttribute = pathAttribute; } @@ -81,7 +81,7 @@ public class BgpPathAttributes { * * @return list of path attributes */ - public List pathAttributes() { + public List pathAttributes() { return this.pathAttribute; } @@ -90,13 +90,13 @@ public class BgpPathAttributes { * * @param cb channelBuffer * @return object of BgpPathAttributes - * @throws BGPParseException while parsing BGP path attributes + * @throws BgpParseException while parsing BGP path attributes */ public static BgpPathAttributes read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { - BGPValueType pathAttribute = null; - List pathAttributeList = new LinkedList<>(); + BgpValueType pathAttribute = null; + List pathAttributeList = new LinkedList<>(); boolean isOrigin = false; boolean isAsPath = false; boolean isNextHop = false; @@ -161,27 +161,27 @@ public class BgpPathAttributes { * @param isNextHop say whether nexthop attribute is present * @param isMpReach say whether mpreach attribute is present * @param isMpUnReach say whether mpunreach attribute is present - * @throws BGPParseException if mandatory path attribute is not present + * @throws BgpParseException if mandatory path attribute is not present */ public static void checkMandatoryAttr(boolean isOrigin, boolean isAsPath, boolean isNextHop, boolean isMpReach, boolean isMpUnReach) - throws BGPParseException { + throws BgpParseException { if (!isOrigin) { log.debug("Mandatory Attributes not Present"); - Validation.validateType(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.MISSING_WELLKNOWN_ATTRIBUTE, + Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE, Origin.ORIGIN_TYPE); } if (!isAsPath) { log.debug("Mandatory Attributes not Present"); - Validation.validateType(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.MISSING_WELLKNOWN_ATTRIBUTE, + Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE, AsPath.ASPATH_TYPE); } if (!isMpUnReach && !isMpReach && !isNextHop) { log.debug("Mandatory Attributes not Present"); - Validation.validateType(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.MISSING_WELLKNOWN_ATTRIBUTE, + Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE, NextHop.NEXTHOP_TYPE); } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java index 9f4cf9b9..4d6af594 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java @@ -20,14 +20,14 @@ import java.util.List; import org.jboss.netty.buffer.ChannelBuffer; import org.onlab.packet.IpPrefix; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPMessageReader; -import org.onosproject.bgpio.protocol.BGPType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpMessageReader; +import org.onosproject.bgpio.protocol.BgpType; import org.onosproject.bgpio.protocol.BgpUpdateMsg; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpHeader; import org.onosproject.bgpio.util.Validation; -import org.onosproject.bgpio.protocol.BGPVersion; +import org.onosproject.bgpio.protocol.BgpVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,12 +75,12 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { public static final int BYTE_IN_BITS = 8; public static final int MIN_LEN_AFTER_WITHDRW_ROUTES = 2; public static final int MINIMUM_COMMON_HEADER_LENGTH = 19; - public static final BGPType MSG_TYPE = BGPType.UPDATE; + public static final BgpType MSG_TYPE = BgpType.UPDATE; public static final BgpUpdateMsgVer4.Reader READER = new Reader(); private List withdrawnRoutes; private BgpPathAttributes bgpPathAttributes; - private BGPHeader bgpHeader; + private BgpHeader bgpHeader; private List nlri; /** @@ -91,7 +91,7 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { * @param bgpPathAttributes BGP Path attributes * @param nlri Network Layer Reachability Information */ - public BgpUpdateMsgVer4(BGPHeader bgpHeader, List withdrawnRoutes, + public BgpUpdateMsgVer4(BgpHeader bgpHeader, List withdrawnRoutes, BgpPathAttributes bgpPathAttributes, List nlri) { this.bgpHeader = bgpHeader; this.withdrawnRoutes = withdrawnRoutes; @@ -102,15 +102,15 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { /** * Reader reads BGP Update Message from the channel buffer. */ - static class Reader implements BGPMessageReader { + static class Reader implements BgpMessageReader { @Override - public BgpUpdateMsg readFrom(ChannelBuffer cb, BGPHeader bgpHeader) - throws BGPParseException { + public BgpUpdateMsg readFrom(ChannelBuffer cb, BgpHeader bgpHeader) + throws BgpParseException { if (cb.readableBytes() != (bgpHeader.getLength() - MINIMUM_COMMON_HEADER_LENGTH)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.BAD_MESSAGE_LENGTH, bgpHeader.getLength()); + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.BAD_MESSAGE_LENGTH, bgpHeader.getLength()); } LinkedList withDrwRoutes = new LinkedList<>(); @@ -120,8 +120,8 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { Short withDrwLen = cb.readShort(); if (cb.readableBytes() < withDrwLen) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.MALFORMED_ATTRIBUTE_LIST, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.MALFORMED_ATTRIBUTE_LIST, cb.readableBytes()); } ChannelBuffer tempCb = cb.readBytes(withDrwLen); @@ -131,23 +131,23 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { } if (cb.readableBytes() < MIN_LEN_AFTER_WITHDRW_ROUTES) { log.debug("Bgp Path Attribute len field not present"); - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.MALFORMED_ATTRIBUTE_LIST, null); } // Reading Total Path Attribute Length short totPathAttrLen = cb.readShort(); int len = withDrwLen + totPathAttrLen + PACKET_MINIMUM_LENGTH; if (len > bgpHeader.getLength()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.MALFORMED_ATTRIBUTE_LIST, null); } if (totPathAttrLen != 0) { // Parsing BGPPathAttributes if (cb.readableBytes() < totPathAttrLen) { Validation - .validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.MALFORMED_ATTRIBUTE_LIST, + .validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.MALFORMED_ATTRIBUTE_LIST, cb.readableBytes()); } tempCb = cb.readBytes(totPathAttrLen); @@ -167,10 +167,10 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { * * @param cb channelBuffer * @return list of IP Prefix - * @throws BGPParseException while parsing NLRI + * @throws BgpParseException while parsing NLRI */ public static LinkedList parseNlri(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { LinkedList nlri = new LinkedList<>(); while (cb.readableBytes() > 0) { int length = cb.readByte(); @@ -186,8 +186,8 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { len = len + 1; } if (cb.readableBytes() < len) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.MALFORMED_ATTRIBUTE_LIST, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.MALFORMED_ATTRIBUTE_LIST, cb.readableBytes()); } byte[] prefix = new byte[len]; @@ -204,10 +204,10 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { * * @param cb channelBuffer * @return list of IP prefix - * @throws BGPParseException while parsing withdrawn routes + * @throws BgpParseException while parsing withdrawn routes */ public static LinkedList parseWithdrawnRoutes(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { LinkedList withDrwRoutes = new LinkedList<>(); while (cb.readableBytes() > 0) { int length = cb.readByte(); @@ -224,8 +224,8 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { } if (cb.readableBytes() < len) { Validation - .validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.MALFORMED_ATTRIBUTE_LIST, + .validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.MALFORMED_ATTRIBUTE_LIST, cb.readableBytes()); } byte[] prefix = new byte[len]; @@ -238,17 +238,17 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { } @Override - public BGPVersion getVersion() { - return BGPVersion.BGP_4; + public BgpVersion getVersion() { + return BgpVersion.BGP_4; } @Override - public BGPType getType() { - return BGPType.UPDATE; + public BgpType getType() { + return BgpType.UPDATE; } @Override - public void writeTo(ChannelBuffer channelBuffer) throws BGPParseException { + public void writeTo(ChannelBuffer channelBuffer) throws BgpParseException { //Not to be implemented as of now } @@ -268,7 +268,7 @@ public class BgpUpdateMsgVer4 implements BgpUpdateMsg { } @Override - public BGPHeader getHeader() { + public BgpHeader getHeader() { return this.bgpHeader; } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AreaIDTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AreaIDTlv.java index 52bae466..842c6f02 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AreaIDTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AreaIDTlv.java @@ -18,15 +18,13 @@ package org.onosproject.bgpio.types; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.base.MoreObjects; /** * Provides AreaID Tlv which contains opaque value (32 Bit Area-ID). */ -public class AreaIDTlv implements BGPValueType { +public class AreaIDTlv implements BgpValueType { /* Reference :draft-ietf-idr-ls-distribution-11 * 0 1 2 3 @@ -38,8 +36,6 @@ public class AreaIDTlv implements BGPValueType { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - protected static final Logger log = LoggerFactory.getLogger(AreaIDTlv.class); - public static final short TYPE = 514; public static final short LENGTH = 4; @@ -115,6 +111,14 @@ public class AreaIDTlv implements BGPValueType { return TYPE; } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + return ((Integer) (this.areaID)).compareTo((Integer) (((AreaIDTlv) o).areaID)); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java index e9df3999..3ceca2ce 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java @@ -20,7 +20,7 @@ import java.util.List; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; import org.onosproject.bgpio.util.Constants; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; @@ -31,7 +31,7 @@ import com.google.common.base.MoreObjects; /** * Provides Implementation of As4Path BGP Path Attribute. */ -public class As4Path implements BGPValueType { +public class As4Path implements BgpValueType { private static final Logger log = LoggerFactory.getLogger(AsPath.class); public static final byte AS4PATH_TYPE = 17; public static final byte ASNUM_SIZE = 4; @@ -63,16 +63,16 @@ public class As4Path implements BGPValueType { * * @param cb ChannelBuffer * @return object of As4Path - * @throws BGPParseException while parsing As4Path + * @throws BgpParseException while parsing As4Path */ - public static As4Path read(ChannelBuffer cb) throws BGPParseException { + public static As4Path read(ChannelBuffer cb) throws BgpParseException { List as4pathSet = new ArrayList<>(); List as4pathSeq = new ArrayList<>(); ChannelBuffer tempCb = cb.copy(); Validation validation = Validation.parseAttributeHeader(cb); if (cb.readableBytes() < validation.getLength()) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR, validation.getLength()); } //if fourth bit is set length is read as short otherwise as byte , len includes type, length and value @@ -80,7 +80,7 @@ public class As4Path implements BGPValueType { .getLength() + Constants.TYPE_AND_LEN_AS_BYTE; ChannelBuffer data = tempCb.readBytes(len); if (validation.getFirstBit() && !validation.getSecondBit() && validation.getThirdBit()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data); } ChannelBuffer tempBuf = cb.readBytes(validation.getLength()); @@ -91,8 +91,8 @@ public class As4Path implements BGPValueType { //length = no of Ases * ASnum size (4 bytes) int length = pathSegLen * ASNUM_SIZE; if (tempBuf.readableBytes() < length) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, length); + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, length); } ChannelBuffer aspathBuf = tempBuf.readBytes(length); while (aspathBuf.readableBytes() > 0) { @@ -166,4 +166,10 @@ public class As4Path implements BGPValueType { //Not required to Implement as of now return 0; } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java index e3eb2c51..2a050c44 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; import org.onosproject.bgpio.util.Constants; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; @@ -32,7 +32,7 @@ import com.google.common.base.MoreObjects; /** * Provides Implementation of AsPath mandatory BGP Path Attribute. */ -public class AsPath implements BGPValueType { +public class AsPath implements BgpValueType { /** * Enum to provide AS types. */ @@ -94,16 +94,16 @@ public class AsPath implements BGPValueType { * * @param cb ChannelBuffer * @return object of AsPath - * @throws BGPParseException while parsing AsPath + * @throws BgpParseException while parsing AsPath */ - public static AsPath read(ChannelBuffer cb) throws BGPParseException { + public static AsPath read(ChannelBuffer cb) throws BgpParseException { List aspathSet = new ArrayList<>(); List aspathSeq = new ArrayList<>(); ChannelBuffer tempCb = cb.copy(); Validation validation = Validation.parseAttributeHeader(cb); if (cb.readableBytes() < validation.getLength()) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR, validation.getLength()); } //if fourth bit is set, length is read as short otherwise as byte , len includes type, length and value @@ -111,7 +111,7 @@ public class AsPath implements BGPValueType { .getLength() + Constants.TYPE_AND_LEN_AS_BYTE; ChannelBuffer data = tempCb.readBytes(len); if (validation.getFirstBit() && !validation.getSecondBit() && validation.getThirdBit()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data); } ChannelBuffer tempBuf = cb.readBytes(validation.getLength()); @@ -121,8 +121,8 @@ public class AsPath implements BGPValueType { byte pathSegLen = tempBuf.readByte(); int length = pathSegLen * ASNUM_SIZE; if (tempBuf.readableBytes() < length) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, length); + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, length); } ChannelBuffer aspathBuf = tempBuf.readBytes(length); while (aspathBuf.readableBytes() > 0) { @@ -205,4 +205,10 @@ public class AsPath implements BGPValueType { //Not required to Implement as of now return 0; } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AutonomousSystemTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AutonomousSystemTlv.java index 5d8a9193..119926c8 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AutonomousSystemTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AutonomousSystemTlv.java @@ -18,15 +18,13 @@ package org.onosproject.bgpio.types; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.base.MoreObjects; /** * Provides Autonomous System Tlv which contains opaque value (32 Bit AS Number). */ -public class AutonomousSystemTlv implements BGPValueType { +public class AutonomousSystemTlv implements BgpValueType { /* Reference :draft-ietf-idr-ls-distribution-11 * 0 1 2 3 @@ -38,8 +36,6 @@ public class AutonomousSystemTlv implements BGPValueType { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - protected static final Logger log = LoggerFactory.getLogger(AutonomousSystemTlv.class); - public static final short TYPE = 512; public static final short LENGTH = 4; @@ -115,6 +111,14 @@ public class AutonomousSystemTlv implements BGPValueType { return TYPE; } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + return ((Integer) (this.asNum)).compareTo((Integer) (((AutonomousSystemTlv) o).asNum)); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPErrorType.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpErrorType.java similarity index 97% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPErrorType.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpErrorType.java index dfcfc9dc..c0932ebe 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPErrorType.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpErrorType.java @@ -19,8 +19,8 @@ package org.onosproject.bgpio.types; /** * BgpErrorType class defines all errorCodes and error Subcodes required for Notification message. */ -public final class BGPErrorType { - private BGPErrorType() { +public final class BgpErrorType { + private BgpErrorType() { } //Error Codes diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPHeader.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpHeader.java similarity index 94% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPHeader.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpHeader.java index 6acda0d6..ad637753 100755 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPHeader.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpHeader.java @@ -23,7 +23,7 @@ import org.slf4j.LoggerFactory; * Provides BGP Message Header which is common for all the Messages. */ -public class BGPHeader { +public class BgpHeader { /* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 @@ -40,7 +40,7 @@ public class BGPHeader { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - protected static final Logger log = LoggerFactory.getLogger(BGPHeader.class); + protected static final Logger log = LoggerFactory.getLogger(BgpHeader.class); public static final int MARKER_LENGTH = 16; public static final short DEFAULT_HEADER_LENGTH = 19; @@ -52,7 +52,7 @@ public class BGPHeader { /** * Reset fields. */ - public BGPHeader() { + public BgpHeader() { this.marker = null; this.length = 0; this.type = 0; @@ -65,7 +65,7 @@ public class BGPHeader { * @param length message length * @param type message type */ - public BGPHeader(byte[] marker, short length, byte type) { + public BgpHeader(byte[] marker, short length, byte type) { this.marker = marker; this.length = length; this.type = type; @@ -148,7 +148,7 @@ public class BGPHeader { * @param cb ChannelBuffer * @return object of BGPHeader */ - public static BGPHeader read(ChannelBuffer cb) { + public static BgpHeader read(ChannelBuffer cb) { byte[] marker = new byte[MARKER_LENGTH]; byte type; @@ -156,6 +156,6 @@ public class BGPHeader { cb.readBytes(marker, 0, MARKER_LENGTH); length = cb.readShort(); type = cb.readByte(); - return new BGPHeader(marker, length, type); + return new BgpHeader(marker, length, type); } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPLSIdentifierTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpLSIdentifierTlv.java similarity index 64% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPLSIdentifierTlv.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpLSIdentifierTlv.java index f723d2ca..58645d4f 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPLSIdentifierTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpLSIdentifierTlv.java @@ -19,15 +19,13 @@ package org.onosproject.bgpio.types; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.base.MoreObjects; /** * Provides BGPLSIdentifier Tlv which contains opaque value (32 Bit BGPLS-Identifier). */ -public class BGPLSIdentifierTlv implements BGPValueType { +public class BgpLSIdentifierTlv implements BgpValueType { /* Reference :draft-ietf-idr-ls-distribution-11 * 0 1 2 3 @@ -39,44 +37,42 @@ public class BGPLSIdentifierTlv implements BGPValueType { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - protected static final Logger log = LoggerFactory.getLogger(BGPLSIdentifierTlv.class); - public static final short TYPE = 513; public static final short LENGTH = 4; - private final int bgpLSIdentifier; + private final int bgpLsIdentifier; /** - * Constructor to initialize bgpLSIdentifier. + * Constructor to initialize bgpLsIdentifier. * - * @param bgpLSIdentifier BgpLS-Identifier + * @param bgpLsIdentifier BGPLS-Identifier */ - public BGPLSIdentifierTlv(int bgpLSIdentifier) { - this.bgpLSIdentifier = bgpLSIdentifier; + public BgpLSIdentifierTlv(int bgpLsIdentifier) { + this.bgpLsIdentifier = bgpLsIdentifier; } /** - * Returns object of this class with specified rbgpLSIdentifier. + * Returns object of this class with specified bgpLsIdentifier. * - * @param bgpLSIdentifier BgpLS-Identifier - * @return BgpLS-Identifier + * @param bgpLsIdentifier BGPLS-Identifier + * @return BGPLS-Identifier */ - public static BGPLSIdentifierTlv of(final int bgpLSIdentifier) { - return new BGPLSIdentifierTlv(bgpLSIdentifier); + public static BgpLSIdentifierTlv of(final int bgpLsIdentifier) { + return new BgpLSIdentifierTlv(bgpLsIdentifier); } /** - * Returns opaque value of BgpLS-Identifier. + * Returns opaque value of BGPLS-Identifier. * - * @return opaque value of BgpLS-Identifier + * @return opaque value of BGPLS-Identifier */ - public int getBgpLSIdentifier() { - return bgpLSIdentifier; + public int getBgpLsIdentifier() { + return bgpLsIdentifier; } @Override public int hashCode() { - return Objects.hash(bgpLSIdentifier); + return Objects.hash(bgpLsIdentifier); } @Override @@ -85,9 +81,9 @@ public class BGPLSIdentifierTlv implements BGPValueType { return true; } - if (obj instanceof BGPLSIdentifierTlv) { - BGPLSIdentifierTlv other = (BGPLSIdentifierTlv) obj; - return Objects.equals(bgpLSIdentifier, other.bgpLSIdentifier); + if (obj instanceof BgpLSIdentifierTlv) { + BgpLSIdentifierTlv other = (BgpLSIdentifierTlv) obj; + return Objects.equals(bgpLsIdentifier, other.bgpLsIdentifier); } return false; } @@ -97,7 +93,7 @@ public class BGPLSIdentifierTlv implements BGPValueType { int iLenStartIndex = c.writerIndex(); c.writeShort(TYPE); c.writeShort(LENGTH); - c.writeInt(bgpLSIdentifier); + c.writeInt(bgpLsIdentifier); return c.writerIndex() - iLenStartIndex; } @@ -107,8 +103,8 @@ public class BGPLSIdentifierTlv implements BGPValueType { * @param cb ChannelBuffer * @return object of BGPLSIdentifierTlv */ - public static BGPLSIdentifierTlv read(ChannelBuffer cb) { - return BGPLSIdentifierTlv.of(cb.readInt()); + public static BgpLSIdentifierTlv read(ChannelBuffer cb) { + return BgpLSIdentifierTlv.of(cb.readInt()); } @Override @@ -116,12 +112,20 @@ public class BGPLSIdentifierTlv implements BGPValueType { return TYPE; } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + return ((Integer) (this.bgpLsIdentifier)).compareTo((Integer) (((BgpLSIdentifierTlv) o).bgpLsIdentifier)); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) .add("Type", TYPE) .add("Length", LENGTH) - .add("Value", bgpLSIdentifier) + .add("Value", bgpLsIdentifier) .toString(); } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPValueType.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpValueType.java old mode 100755 new mode 100644 similarity index 85% rename from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPValueType.java rename to framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpValueType.java index 54a8b43c..af7f4b75 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BGPValueType.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/BgpValueType.java @@ -21,7 +21,7 @@ import org.jboss.netty.buffer.ChannelBuffer; /** * Abstraction which Provides the BGP of TLV format. */ -public interface BGPValueType { +public interface BgpValueType { /** * Returns the Type of BGP Message. * @@ -36,4 +36,12 @@ public interface BGPValueType { * @return length written to channel buffer */ int write(ChannelBuffer cb); + + /** + * Compares two objects. + * + * @param o object + * @return result after comparing two objects + */ + int compareTo(Object o); } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/FourOctetAsNumCapabilityTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/FourOctetAsNumCapabilityTlv.java old mode 100755 new mode 100644 index 61570285..59db3318 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/FourOctetAsNumCapabilityTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/FourOctetAsNumCapabilityTlv.java @@ -26,7 +26,7 @@ import com.google.common.base.MoreObjects; /** * Provides FourOctetAsNumCapabilityTlv Capability Tlv. */ -public class FourOctetAsNumCapabilityTlv implements BGPValueType { +public class FourOctetAsNumCapabilityTlv implements BgpValueType { /** * support to indicate its support for four-octet AS numbers -CAPABILITY TLV format. @@ -111,4 +111,10 @@ public class FourOctetAsNumCapabilityTlv implements BGPValueType { .add("Length", LENGTH) .add("Value", rawValue).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPReachabilityInformationTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPReachabilityInformationTlv.java index 59afbed6..d97537e8 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPReachabilityInformationTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPReachabilityInformationTlv.java @@ -15,21 +15,20 @@ */ package org.onosproject.bgpio.types; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; import org.onlab.packet.IpPrefix; import org.onosproject.bgpio.util.Validation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.base.MoreObjects; /** * Provides IP Reachability InformationTlv Tlv which contains IP Prefix. */ -public class IPReachabilityInformationTlv implements BGPValueType { +public class IPReachabilityInformationTlv implements BgpValueType { /* * Reference :draft-ietf-idr-ls-distribution-11 @@ -45,10 +44,9 @@ public class IPReachabilityInformationTlv implements BGPValueType { Figure 14: IP Reachability Information TLV Format */ - protected static final Logger log = LoggerFactory.getLogger(IPReachabilityInformationTlv.class); - public static final short TYPE = 265; public static final int ONE_BYTE_LEN = 8; + private byte prefixLen; private byte[] ipPrefix; public short length; @@ -145,6 +143,16 @@ public class IPReachabilityInformationTlv implements BGPValueType { return TYPE; } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + ByteBuffer value1 = ByteBuffer.wrap(this.ipPrefix); + ByteBuffer value2 = ByteBuffer.wrap(((IPReachabilityInformationTlv) o).ipPrefix); + return value1.compareTo(value2); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPv4AddressTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPv4AddressTlv.java index d5f03268..4efde70e 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPv4AddressTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPv4AddressTlv.java @@ -20,9 +20,8 @@ import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; import org.onlab.packet.Ip4Address; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.util.Validation; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; @@ -30,8 +29,7 @@ import com.google.common.base.Preconditions; /** * Provides Implementation of IPv4AddressTlv. */ -public class IPv4AddressTlv implements BGPValueType { - private static final Logger log = LoggerFactory.getLogger(IPv4AddressTlv.class); +public class IPv4AddressTlv implements BgpValueType { private static final int LENGTH = 4; private Ip4Address address; @@ -53,7 +51,7 @@ public class IPv4AddressTlv implements BGPValueType { * * @return Ipv4 address of interface/neighbor */ - public Ip4Address getValue() { + public Ip4Address address() { return address; } @@ -94,13 +92,12 @@ public class IPv4AddressTlv implements BGPValueType { * @param cb channelBuffer * @param type address type * @return object of IPv4AddressTlv - * @throws BGPParseException while parsing IPv4AddressTlv + * @throws BgpParseException while parsing IPv4AddressTlv */ - public static IPv4AddressTlv read(ChannelBuffer cb, short type) throws BGPParseException { - //TODO: use Validation.toInetAddress once Validation is merged - InetAddress ipAddress = (InetAddress) cb.readBytes(LENGTH); + public static IPv4AddressTlv read(ChannelBuffer cb, short type) throws BgpParseException { + InetAddress ipAddress = Validation.toInetAddress(LENGTH, cb); if (ipAddress.isMulticastAddress()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); } Ip4Address address = Ip4Address.valueOf(ipAddress); return IPv4AddressTlv.of(address, type); @@ -117,6 +114,14 @@ public class IPv4AddressTlv implements BGPValueType { return new IPv4AddressTlv(address, type); } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + return ((Ip4Address) (this.address)).compareTo((Ip4Address) (((IPv4AddressTlv) o).address)); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPv6AddressTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPv6AddressTlv.java index 65b7c16d..087cd5c6 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPv6AddressTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IPv6AddressTlv.java @@ -20,9 +20,8 @@ import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; import org.onlab.packet.Ip6Address; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.util.Validation; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; @@ -30,8 +29,7 @@ import com.google.common.base.Preconditions; /** * Provides Implementation of IPv6AddressTlv. */ -public class IPv6AddressTlv implements BGPValueType { - private static final Logger log = LoggerFactory.getLogger(IPv6AddressTlv.class); +public class IPv6AddressTlv implements BgpValueType { private static final int LENGTH = 16; private final Ip6Address address; @@ -53,7 +51,7 @@ public class IPv6AddressTlv implements BGPValueType { * * @return Ipv6 address of interface/neighbor */ - public Ip6Address getValue() { + public Ip6Address address() { return address; } @@ -94,13 +92,12 @@ public class IPv6AddressTlv implements BGPValueType { * @param cb channelBuffer * @param type address type * @return object of IPv6AddressTlv - * @throws BGPParseException while parsing IPv6AddressTlv + * @throws BgpParseException while parsing IPv6AddressTlv */ - public static IPv6AddressTlv read(ChannelBuffer cb, short type) throws BGPParseException { - //TODO: use Validation.toInetAddress once Validation is merged - InetAddress ipAddress = (InetAddress) cb.readBytes(LENGTH); + public static IPv6AddressTlv read(ChannelBuffer cb, short type) throws BgpParseException { + InetAddress ipAddress = Validation.toInetAddress(LENGTH, cb); if (ipAddress.isMulticastAddress()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); } Ip6Address address = Ip6Address.valueOf(ipAddress); return IPv6AddressTlv.of(address, type); @@ -117,6 +114,14 @@ public class IPv6AddressTlv implements BGPValueType { return new IPv6AddressTlv(address, type); } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + return ((Ip6Address) (this.address)).compareTo((Ip6Address) (((IPv6AddressTlv) o).address)); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IsIsNonPseudonode.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IsIsNonPseudonode.java index d5f3e7f3..427aa929 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IsIsNonPseudonode.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IsIsNonPseudonode.java @@ -15,21 +15,18 @@ */ package org.onosproject.bgpio.types; -import java.util.Objects; +import java.nio.ByteBuffer; +import java.util.Arrays; import org.jboss.netty.buffer.ChannelBuffer; import org.onosproject.bgpio.protocol.IGPRouterID; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.base.MoreObjects; /** * Provides Implementation of IsIsNonPseudonode Tlv. */ -public class IsIsNonPseudonode implements IGPRouterID, BGPValueType { - protected static final Logger log = LoggerFactory.getLogger(IsIsNonPseudonode.class); - +public class IsIsNonPseudonode implements IGPRouterID, BgpValueType { public static final short TYPE = 515; public static final short LENGTH = 6; @@ -41,7 +38,7 @@ public class IsIsNonPseudonode implements IGPRouterID, BGPValueType { * @param isoNodeID ISO system-ID */ public IsIsNonPseudonode(byte[] isoNodeID) { - this.isoNodeID = isoNodeID; + this.isoNodeID = Arrays.copyOf(isoNodeID, isoNodeID.length); } /** @@ -65,7 +62,7 @@ public class IsIsNonPseudonode implements IGPRouterID, BGPValueType { @Override public int hashCode() { - return Objects.hash(isoNodeID); + return Arrays.hashCode(isoNodeID); } @Override @@ -75,7 +72,7 @@ public class IsIsNonPseudonode implements IGPRouterID, BGPValueType { } if (obj instanceof IsIsNonPseudonode) { IsIsNonPseudonode other = (IsIsNonPseudonode) obj; - return Objects.equals(isoNodeID, other.isoNodeID); + return Arrays.equals(isoNodeID, other.isoNodeID); } return false; } @@ -97,7 +94,7 @@ public class IsIsNonPseudonode implements IGPRouterID, BGPValueType { */ public static IsIsNonPseudonode read(ChannelBuffer cb) { byte[] isoNodeID = new byte[LENGTH]; - cb.readBytes(isoNodeID, 0, LENGTH); + cb.readBytes(isoNodeID); return IsIsNonPseudonode.of(isoNodeID); } @@ -106,6 +103,16 @@ public class IsIsNonPseudonode implements IGPRouterID, BGPValueType { return TYPE; } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + ByteBuffer value1 = ByteBuffer.wrap(this.isoNodeID); + ByteBuffer value2 = ByteBuffer.wrap(((IsIsNonPseudonode) o).isoNodeID); + return value1.compareTo(value2); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IsIsPseudonode.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IsIsPseudonode.java index 35fd2493..094c4382 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IsIsPseudonode.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/IsIsPseudonode.java @@ -15,28 +15,23 @@ */ package org.onosproject.bgpio.types; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.nio.ByteBuffer; +import java.util.Arrays; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; import org.onosproject.bgpio.protocol.IGPRouterID; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.base.MoreObjects; /** * Provides implementation of IsIsPseudonode Tlv. */ -public class IsIsPseudonode implements IGPRouterID, BGPValueType { - private static final Logger log = LoggerFactory.getLogger(IsIsPseudonode.class); - +public class IsIsPseudonode implements IGPRouterID, BgpValueType { public static final short TYPE = 515; public static final short LENGTH = 7; - private final List isoNodeID; + private final byte[] isoNodeID; private byte psnIdentifier; /** @@ -45,8 +40,8 @@ public class IsIsPseudonode implements IGPRouterID, BGPValueType { * @param isoNodeID ISO system-ID * @param psnIdentifier PSN identifier */ - public IsIsPseudonode(List isoNodeID, byte psnIdentifier) { - this.isoNodeID = isoNodeID; + public IsIsPseudonode(byte[] isoNodeID, byte psnIdentifier) { + this.isoNodeID = Arrays.copyOf(isoNodeID, isoNodeID.length); this.psnIdentifier = psnIdentifier; } @@ -57,7 +52,7 @@ public class IsIsPseudonode implements IGPRouterID, BGPValueType { * @param psnIdentifier PSN identifier * @return object of IsIsPseudonode */ - public static IsIsPseudonode of(final List isoNodeID, + public static IsIsPseudonode of(final byte[] isoNodeID, final byte psnIdentifier) { return new IsIsPseudonode(isoNodeID, psnIdentifier); } @@ -67,7 +62,7 @@ public class IsIsPseudonode implements IGPRouterID, BGPValueType { * * @return ISO NodeID */ - public List getISONodeID() { + public byte[] getISONodeID() { return isoNodeID; } @@ -82,7 +77,7 @@ public class IsIsPseudonode implements IGPRouterID, BGPValueType { @Override public int hashCode() { - return Objects.hash(isoNodeID) & Objects.hash(psnIdentifier); + return Arrays.hashCode(isoNodeID) & Objects.hash(psnIdentifier); } @Override @@ -91,27 +86,9 @@ public class IsIsPseudonode implements IGPRouterID, BGPValueType { return true; } if (obj instanceof IsIsPseudonode) { - int countObjSubTlv = 0; - int countOtherSubTlv = 0; - boolean isCommonSubTlv = true; IsIsPseudonode other = (IsIsPseudonode) obj; - Iterator objListIterator = other.isoNodeID.iterator(); - countOtherSubTlv = other.isoNodeID.size(); - countObjSubTlv = isoNodeID.size(); - if (countObjSubTlv != countOtherSubTlv) { - return false; - } else { - while (objListIterator.hasNext() && isCommonSubTlv) { - Byte subTlv = objListIterator.next(); - if (isoNodeID.contains(subTlv) && other.isoNodeID.contains(subTlv)) { - isCommonSubTlv = Objects.equals(isoNodeID.get(isoNodeID.indexOf(subTlv)), - other.isoNodeID.get(other.isoNodeID.indexOf(subTlv))); - } else { - isCommonSubTlv = false; - } - } - return isCommonSubTlv && Objects.equals(psnIdentifier, other.psnIdentifier); - } + return Arrays.equals(isoNodeID, other.isoNodeID) + && Objects.equals(psnIdentifier, other.psnIdentifier); } return false; } @@ -121,11 +98,7 @@ public class IsIsPseudonode implements IGPRouterID, BGPValueType { int iLenStartIndex = c.writerIndex(); c.writeShort(TYPE); c.writeShort(LENGTH); - Iterator objListIterator = isoNodeID.iterator(); - while (objListIterator.hasNext()) { - byte value = objListIterator.next(); - c.writeByte(value); - } + c.writeBytes(isoNodeID, 0, LENGTH - 1); c.writeByte(psnIdentifier); return c.writerIndex() - iLenStartIndex; } @@ -137,12 +110,8 @@ public class IsIsPseudonode implements IGPRouterID, BGPValueType { * @return object of IsIsPseudonode */ public static IsIsPseudonode read(ChannelBuffer cb) { - List isoNodeID = new ArrayList(); - byte value; - for (int i = 0; i < LENGTH; i++) { - value = cb.readByte(); - isoNodeID.add(value); - } + byte[] isoNodeID = new byte[LENGTH - 1]; + cb.readBytes(isoNodeID); byte psnIdentifier = cb.readByte(); return IsIsPseudonode.of(isoNodeID, psnIdentifier); } @@ -152,6 +121,19 @@ public class IsIsPseudonode implements IGPRouterID, BGPValueType { return TYPE; } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + ByteBuffer value1 = ByteBuffer.wrap(this.isoNodeID); + ByteBuffer value2 = ByteBuffer.wrap(((IsIsPseudonode) o).isoNodeID); + if (value1.compareTo(value2) != 0) { + return value1.compareTo(value2); + } + return ((Byte) (this.psnIdentifier)).compareTo((Byte) (((IsIsPseudonode) o).psnIdentifier)); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkLocalRemoteIdentifiersTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkLocalRemoteIdentifiersTlv.java index 988925f5..0c412432 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkLocalRemoteIdentifiersTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkLocalRemoteIdentifiersTlv.java @@ -18,16 +18,13 @@ package org.onosproject.bgpio.types; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.base.MoreObjects; /** * Provides Implementation of Link Local/Remote IdentifiersTlv. */ -public class LinkLocalRemoteIdentifiersTlv implements BGPValueType { - private static final Logger log = LoggerFactory.getLogger(LinkLocalRemoteIdentifiersTlv.class); +public class LinkLocalRemoteIdentifiersTlv implements BgpValueType { public static final short TYPE = 258; private static final int LENGTH = 8; @@ -119,6 +116,20 @@ public class LinkLocalRemoteIdentifiersTlv implements BGPValueType { return new LinkLocalRemoteIdentifiersTlv(linkLocalIdentifer, linkRemoteIdentifer); } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + int result = ((Integer) (this.linkLocalIdentifer)) + .compareTo((Integer) (((LinkLocalRemoteIdentifiersTlv) o).linkLocalIdentifer)); + if (result != 0) { + return result; + } + return ((Integer) (this.linkRemoteIdentifer)) + .compareTo((Integer) (((LinkLocalRemoteIdentifiersTlv) o).linkRemoteIdentifer)); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java new file mode 100644 index 00000000..cdf6ebeb --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java @@ -0,0 +1,314 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types; + +import java.util.LinkedList; +import java.util.List; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv; +import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId; +import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId; +import org.onosproject.bgpio.types.attr.BgpAttrNodeName; +import org.onosproject.bgpio.types.attr.BgpAttrOpaqueNode; +import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4; +import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV6; +import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric; +import org.onosproject.bgpio.types.attr.BgpLinkAttrIsIsAdminstGrp; +import org.onosproject.bgpio.types.attr.BgpLinkAttrMplsProtocolMask; +import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth; +import org.onosproject.bgpio.types.attr.BgpLinkAttrName; +import org.onosproject.bgpio.types.attr.BgpLinkAttrOpaqLnkAttrib; +import org.onosproject.bgpio.types.attr.BgpLinkAttrProtectionType; +import org.onosproject.bgpio.types.attr.BgpLinkAttrSrlg; +import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric; +import org.onosproject.bgpio.types.attr.BgpLinkAttrUnRsrvdLinkBandwidth; +import org.onosproject.bgpio.types.attr.BgpPrefixAttrExtRouteTag; +import org.onosproject.bgpio.types.attr.BgpPrefixAttrIgpFlags; +import org.onosproject.bgpio.types.attr.BgpPrefixAttrMetric; +import org.onosproject.bgpio.types.attr.BgpPrefixAttrOspfFwdAddr; +import org.onosproject.bgpio.types.attr.BgpPrefixAttrOpaqueData; +import org.onosproject.bgpio.types.attr.BgpPrefixAttrRouteTag; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP Link state attribute. + */ +public class LinkStateAttributes implements BgpValueType { + + protected static final Logger log = LoggerFactory + .getLogger(LinkStateAttributes.class); + + /* Node Attributes */ + public static final short ATTR_NODE_MT_TOPOLOGY_ID = 263; + public static final short ATTR_NODE_FLAG_BITS = 1024; + public static final short ATTR_NODE_OPAQUE_NODE = 1025; + public static final short ATTR_NODE_NAME = 1026; + public static final short ATTR_NODE_ISIS_AREA_ID = 1027; + public static final short ATTR_NODE_IPV4_LOCAL_ROUTER_ID = 1028; + public static final short ATTR_NODE_IPV6_LOCAL_ROUTER_ID = 1029; + + /* Link Attributes */ + public static final short ATTR_LINK_IPV4_REMOTE_ROUTER_ID = 1030; + public static final short ATTR_LINK_IPV6_REMOTE_ROUTER_ID = 1031; + public static final short ATTR_LINK_ADMINISTRATIVE_GRPS = 1088; + public static final short ATTR_LINK_MAX_BANDWIDTH = 1089; + public static final short ATTR_LINK_MAX_RES_BANDWIDTH = 1090; + public static final short ATTR_LINK_UNRES_BANDWIDTH = 1091; + public static final short ATTR_LINK_TE_DEFAULT_METRIC = 1092; + public static final short ATTR_LINK_PROTECTION_TYPE = 1093; + public static final short ATTR_LINK_MPLS_PROTOCOL_MASK = 1094; + public static final short ATTR_LINK_IGP_METRIC = 1095; + public static final short ATTR_LINK_SHR_RISK_GRP = 1096; + public static final short ATTR_LINK_OPAQUE_ATTR = 1097; + public static final short ATTR_LINK_NAME_ATTR = 1098; + + /* Prefix Attributes */ + public static final short ATTR_PREFIX_IGP_FLAG = 1152; + public static final short ATTR_PREFIX_ROUTE_TAG = 1153; + public static final short ATTR_PREFIX_EXTENDED_TAG = 1154; + public static final short ATTR_PREFIX_METRIC = 1155; + public static final short ATTR_PREFIX_OSPF_FWD_ADDR = 1156; + public static final short ATTR_PREFIX_OPAQUE_ATTR = 1157; + + public static final byte LINKSTATE_ATTRIB_TYPE = 50; + public static final byte TYPE_AND_LEN = 4; + private boolean isLinkStateAttribute = false; + private List linkStateAttribList; + + /** + * Constructor to reset parameters. + */ + LinkStateAttributes() { + this.linkStateAttribList = null; + } + + /** + * Constructor to initialize parameters. + * + * @param linkStateAttribList Linked list of Link, Node and Prefix TLVs + */ + LinkStateAttributes(List linkStateAttribList) { + this.linkStateAttribList = linkStateAttribList; + this.isLinkStateAttribute = true; + } + + /** + * Returns linked list of Link, Node and Prefix TLVs. + * + * @return linked list of Link, Node and Prefix TLVs + */ + public List linkStateAttributes() { + return this.linkStateAttribList; + } + + /** + * Returns if the Link state attributes are set or not. + * + * @return a boolean value to to check if the LS attributes are set or not + */ + public boolean isLinkStateAttributeSet() { + return this.isLinkStateAttribute; + } + + /** + * Reads the Link state attribute TLVs. + * + * @param cb ChannelBuffer + * @return constructor of LinkStateAttributes + * @throws BgpParseException while parsing link state attributes + */ + public static LinkStateAttributes read(ChannelBuffer cb) + throws BgpParseException { + + ChannelBuffer tempBuf = cb; + Validation parseFlags = Validation.parseAttributeHeader(cb); + int len = parseFlags.isShort() ? parseFlags.getLength() + TYPE_AND_LEN + : parseFlags.getLength() + 3; + + ChannelBuffer data = tempBuf.readBytes(len); + if (!parseFlags.getFirstBit() || parseFlags.getSecondBit() + || parseFlags.getThirdBit()) { + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_FLAGS_ERROR, + data); + } + + if (cb.readableBytes() < parseFlags.getLength()) { + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.BAD_MESSAGE_LENGTH, + parseFlags.getLength()); + } + + BgpValueType bgpLSAttrib = null; + LinkedList linkStateAttribList; + linkStateAttribList = new LinkedList(); + ChannelBuffer tempCb = cb.readBytes(parseFlags.getLength()); + while (tempCb.readableBytes() > 0) { + short tlvCodePoint = tempCb.readShort(); + switch (tlvCodePoint) { + + /********* 7 NODE ATTRIBUTES ********/ + case ATTR_NODE_MT_TOPOLOGY_ID: /* 263 Multi-Topology Identifier*/ + bgpLSAttrib = BgpAttrNodeMultiTopologyId.read(tempCb); + break; + + case ATTR_NODE_FLAG_BITS: /*Node flag bit TLV*/ + bgpLSAttrib = BgpAttrNodeFlagBitTlv.read(tempCb); + break; + + case ATTR_NODE_OPAQUE_NODE: /*Opaque Node Attribute*/ + bgpLSAttrib = BgpAttrOpaqueNode.read(tempCb); + break; + + case ATTR_NODE_NAME: /*Node Name*/ + bgpLSAttrib = BgpAttrNodeName.read(tempCb); + break; + + case ATTR_NODE_ISIS_AREA_ID: /*IS-IS Area Identifier TLV*/ + bgpLSAttrib = BgpAttrNodeIsIsAreaId.read(tempCb); + break; + + case ATTR_NODE_IPV4_LOCAL_ROUTER_ID: /*IPv4 Router-ID of Local Node*/ + bgpLSAttrib = BgpAttrRouterIdV4.read(tempCb, (short) ATTR_NODE_IPV4_LOCAL_ROUTER_ID); + break; + + case ATTR_NODE_IPV6_LOCAL_ROUTER_ID: /*IPv6 Router-ID of Local Node*/ + bgpLSAttrib = BgpAttrRouterIdV6.read(tempCb, (short) ATTR_NODE_IPV6_LOCAL_ROUTER_ID); + break; + + /********* 15 LINK ATTRIBUTES ********/ + + case ATTR_LINK_IPV4_REMOTE_ROUTER_ID: /*IPv4 Router-ID of Remote Node*/ + bgpLSAttrib = BgpAttrRouterIdV4.read(tempCb, (short) 1030); + break; + + case ATTR_LINK_IPV6_REMOTE_ROUTER_ID: /*IPv6 Router-ID of Remote Node*/ + bgpLSAttrib = BgpAttrRouterIdV6.read(tempCb, (short) 1031); + break; + + case ATTR_LINK_ADMINISTRATIVE_GRPS: /*ISIS Administrative group STLV 3*/ + bgpLSAttrib = BgpLinkAttrIsIsAdminstGrp.read(tempCb); + break; + + case ATTR_LINK_MAX_BANDWIDTH: /*Maximum link bandwidth*/ + bgpLSAttrib = BgpLinkAttrMaxLinkBandwidth.read(tempCb, + (short) 1089); + break; + + case ATTR_LINK_MAX_RES_BANDWIDTH: /* Maximum Reservable link bandwidth */ + bgpLSAttrib = BgpLinkAttrMaxLinkBandwidth.read(tempCb, + (short) 1090); + break; + + case ATTR_LINK_UNRES_BANDWIDTH: /* UnReserved link bandwidth */ + bgpLSAttrib = BgpLinkAttrUnRsrvdLinkBandwidth + .read(tempCb, (short) 1091); + break; + + case ATTR_LINK_TE_DEFAULT_METRIC: /* TE Default Metric */ + bgpLSAttrib = BgpLinkAttrTeDefaultMetric.read(tempCb); + break; + + case ATTR_LINK_PROTECTION_TYPE:/* Link Protection type */ + bgpLSAttrib = BgpLinkAttrProtectionType.read(tempCb); + break; + + case ATTR_LINK_MPLS_PROTOCOL_MASK: /* MPLS Protocol Mask */ + bgpLSAttrib = BgpLinkAttrMplsProtocolMask.read(tempCb); // 2 + break; + + case ATTR_LINK_IGP_METRIC: /* IGP Metric */ + bgpLSAttrib = BgpLinkAttrIgpMetric.read(tempCb); // 2 + break; + + case ATTR_LINK_SHR_RISK_GRP: /* Shared Risk Link Group */ + bgpLSAttrib = BgpLinkAttrSrlg.read(tempCb); // 3 + break; + + case ATTR_LINK_OPAQUE_ATTR: /* Opaque link attribute */ + bgpLSAttrib = BgpLinkAttrOpaqLnkAttrib.read(tempCb); + break; + + case ATTR_LINK_NAME_ATTR: /* Link Name attribute */ + bgpLSAttrib = BgpLinkAttrName.read(tempCb); + break; + + /********* 6 PREFIX ATTRIBUTES ********/ + + case ATTR_PREFIX_IGP_FLAG: /* IGP Flags */ + bgpLSAttrib = BgpPrefixAttrIgpFlags.read(tempCb); + break; + + case ATTR_PREFIX_ROUTE_TAG: /* Route Tag */ + bgpLSAttrib = BgpPrefixAttrRouteTag.read(tempCb); + break; + + case ATTR_PREFIX_EXTENDED_TAG: /* Extended Tag */ + bgpLSAttrib = BgpPrefixAttrExtRouteTag.read(tempCb); + break; + + case ATTR_PREFIX_METRIC: /* Prefix Metric */ + bgpLSAttrib = BgpPrefixAttrMetric.read(tempCb); + break; + + case ATTR_PREFIX_OSPF_FWD_ADDR: /* OSPF Forwarding Address */ + bgpLSAttrib = BgpPrefixAttrOspfFwdAddr.read(tempCb); + break; + + case ATTR_PREFIX_OPAQUE_ATTR: /* Opaque Prefix Attribute */ + bgpLSAttrib = BgpPrefixAttrOpaqueData.read(tempCb); + break; + + default: + throw new BgpParseException( + "The Bgp-LS Attribute is not supported : " + + tlvCodePoint); + } + + linkStateAttribList.add(bgpLSAttrib); + } + return new LinkStateAttributes(linkStateAttribList); + } + + @Override + public short getType() { + return LINKSTATE_ATTRIB_TYPE; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO This will be implemented in the next version + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("linkStateAttribList", linkStateAttribList).toString(); + } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LocalPref.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LocalPref.java index 0f78ab77..36793c18 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LocalPref.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LocalPref.java @@ -18,7 +18,7 @@ package org.onosproject.bgpio.types; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; import org.onosproject.bgpio.util.Constants; import org.onosproject.bgpio.util.Validation; @@ -27,7 +27,7 @@ import com.google.common.base.MoreObjects; /** * Provides implementation of LocalPref BGP Path Attribute. */ -public class LocalPref implements BGPValueType { +public class LocalPref implements BgpValueType { public static final byte LOCAL_PREF_TYPE = 5; public static final byte LOCAL_PREF_MAX_LEN = 4; @@ -56,14 +56,14 @@ public class LocalPref implements BGPValueType { * * @param cb channelBuffer * @return object of LocalPref - * @throws BGPParseException while parsing localPref attribute + * @throws BgpParseException while parsing localPref attribute */ - public static LocalPref read(ChannelBuffer cb) throws BGPParseException { + public static LocalPref read(ChannelBuffer cb) throws BgpParseException { int localPref; ChannelBuffer tempCb = cb.copy(); Validation parseFlags = Validation.parseAttributeHeader(cb); if ((parseFlags.getLength() > LOCAL_PREF_MAX_LEN) || cb.readableBytes() < parseFlags.getLength()) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR, parseFlags.getLength()); } @@ -71,7 +71,7 @@ public class LocalPref implements BGPValueType { Constants.TYPE_AND_LEN_AS_SHORT : parseFlags.getLength() + Constants.TYPE_AND_LEN_AS_BYTE; ChannelBuffer data = tempCb.readBytes(len); if (parseFlags.getFirstBit()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data); } localPref = cb.readInt(); @@ -112,4 +112,10 @@ public class LocalPref implements BGPValueType { //Not to implement as of now return 0; } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Med.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Med.java index 23402c26..7f1ab53f 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Med.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Med.java @@ -18,7 +18,7 @@ package org.onosproject.bgpio.types; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; import org.onosproject.bgpio.util.Constants; import org.onosproject.bgpio.util.Validation; @@ -27,7 +27,7 @@ import com.google.common.base.MoreObjects; /** * Provides Implementation of Med BGP Path Attribute. */ -public class Med implements BGPValueType { +public class Med implements BgpValueType { public static final byte MED_TYPE = 4; public static final byte MED_MAX_LEN = 4; @@ -56,22 +56,22 @@ public class Med implements BGPValueType { * * @param cb ChannelBuffer * @return object of Med - * @throws BGPParseException while parsing Med path attribute + * @throws BgpParseException while parsing Med path attribute */ - public static Med read(ChannelBuffer cb) throws BGPParseException { + public static Med read(ChannelBuffer cb) throws BgpParseException { int med; ChannelBuffer tempCb = cb.copy(); Validation parseFlags = Validation.parseAttributeHeader(cb); if ((parseFlags.getLength() > MED_MAX_LEN) || cb.readableBytes() < parseFlags.getLength()) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR, parseFlags.getLength()); } int len = parseFlags.isShort() ? parseFlags.getLength() + Constants.TYPE_AND_LEN_AS_SHORT : parseFlags .getLength() + Constants.TYPE_AND_LEN_AS_BYTE; ChannelBuffer data = tempCb.readBytes(len); if (!parseFlags.getFirstBit() && parseFlags.getSecondBit() && parseFlags.getThirdBit()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data); } med = cb.readInt(); @@ -112,4 +112,10 @@ public class Med implements BGPValueType { //Not to implement as of now return 0; } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java index fe99d28d..689f30ea 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpReachNlri.java @@ -22,10 +22,10 @@ import java.util.List; import org.jboss.netty.buffer.ChannelBuffer; import org.onlab.packet.Ip4Address; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPLSNlri; -import org.onosproject.bgpio.protocol.linkstate.BGPPrefixIPv4LSNlriVer4; -import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSNlriVer4; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpLSNlri; +import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4; import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4; import org.onosproject.bgpio.util.Constants; import org.onosproject.bgpio.util.Validation; @@ -37,14 +37,14 @@ import com.google.common.base.MoreObjects; /* * Provides Implementation of MpReach Nlri BGP Path Attribute. */ -public class MpReachNlri implements BGPValueType { +public class MpReachNlri implements BgpValueType { private static final Logger log = LoggerFactory.getLogger(MpReachNlri.class); public static final byte MPREACHNLRI_TYPE = 14; public static final byte LINK_NLRITYPE = 2; private boolean isMpReachNlri = false; - private final List mpReachNlri; + private final List mpReachNlri; private final int length; private final short afi; private final byte safi; @@ -59,7 +59,7 @@ public class MpReachNlri implements BGPValueType { * @param ipNextHop nexthop IpAddress * @param length of MpReachNlri */ - public MpReachNlri(List mpReachNlri, short afi, byte safi, Ip4Address ipNextHop, int length) { + public MpReachNlri(List mpReachNlri, short afi, byte safi, Ip4Address ipNextHop, int length) { this.mpReachNlri = mpReachNlri; this.isMpReachNlri = true; this.ipNextHop = ipNextHop; @@ -82,7 +82,7 @@ public class MpReachNlri implements BGPValueType { * * @return list of MpReach Nlri */ - public List mpReachNlri() { + public List mpReachNlri() { return this.mpReachNlri; } @@ -100,9 +100,9 @@ public class MpReachNlri implements BGPValueType { * * @param cb channelBuffer * @return object of MpReachNlri - * @throws BGPParseException while parsing MpReachNlri + * @throws BgpParseException while parsing MpReachNlri */ - public static MpReachNlri read(ChannelBuffer cb) throws BGPParseException { + public static MpReachNlri read(ChannelBuffer cb) throws BgpParseException { ChannelBuffer tempBuf = cb.copy(); Validation parseFlags = Validation.parseAttributeHeader(cb); int len = parseFlags.isShort() ? parseFlags.getLength() + Constants.TYPE_AND_LEN_AS_SHORT : @@ -110,15 +110,15 @@ public class MpReachNlri implements BGPValueType { ChannelBuffer data = tempBuf.readBytes(len); if (cb.readableBytes() < parseFlags.getLength()) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR, parseFlags.getLength()); } if (!parseFlags.getFirstBit() && parseFlags.getSecondBit() && parseFlags.getThirdBit()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data); } - BGPLSNlri bgpLSNlri = null; - List mpReachNlri = new LinkedList<>(); + BgpLSNlri bgpLSNlri = null; + List mpReachNlri = new LinkedList<>(); ChannelBuffer tempCb = cb.readBytes(parseFlags.getLength()); short afi = 0; byte safi = 0; @@ -133,7 +133,7 @@ public class MpReachNlri implements BGPValueType { byte nextHopLen = tempCb.readByte(); InetAddress ipAddress = Validation.toInetAddress(nextHopLen, cb); if (ipAddress.isMulticastAddress()) { - throw new BGPParseException("Multicast not supported"); + throw new BgpParseException("Multicast not supported"); } ipNextHop = Ip4Address.valueOf(ipAddress); byte reserved = tempCb.readByte(); @@ -142,19 +142,19 @@ public class MpReachNlri implements BGPValueType { short nlriType = tempCb.readShort(); short totNlriLen = tempCb.readShort(); if (tempCb.readableBytes() < totNlriLen) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen); + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen); } tempBuf = tempCb.readBytes(totNlriLen); switch (nlriType) { - case BGPNodeLSNlriVer4.NODE_NLRITYPE: - bgpLSNlri = BGPNodeLSNlriVer4.read(tempBuf, afi, safi); + case BgpNodeLSNlriVer4.NODE_NLRITYPE: + bgpLSNlri = BgpNodeLSNlriVer4.read(tempBuf, afi, safi); break; case BgpLinkLsNlriVer4.LINK_NLRITYPE: bgpLSNlri = BgpLinkLsNlriVer4.read(tempBuf, afi, safi); break; - case BGPPrefixIPv4LSNlriVer4.PREFIX_IPV4_NLRITYPE: - bgpLSNlri = BGPPrefixIPv4LSNlriVer4.read(tempBuf, afi, safi); + case BgpPrefixIPv4LSNlriVer4.PREFIX_IPV4_NLRITYPE: + bgpLSNlri = BgpPrefixIPv4LSNlriVer4.read(tempBuf, afi, safi); break; default: log.debug("nlriType not supported" + nlriType); @@ -162,7 +162,7 @@ public class MpReachNlri implements BGPValueType { mpReachNlri.add(bgpLSNlri); } } else { - throw new BGPParseException("Not Supporting afi " + afi + "safi " + safi); + throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi); } } return new MpReachNlri(mpReachNlri, afi, safi, ipNextHop, parseFlags.getLength()); @@ -216,4 +216,10 @@ public class MpReachNlri implements BGPValueType { .add("length", length) .toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java index 8763ec59..f354b3ea 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MpUnReachNlri.java @@ -20,10 +20,10 @@ import java.util.LinkedList; import java.util.List; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPLSNlri; -import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSNlriVer4; -import org.onosproject.bgpio.protocol.linkstate.BGPPrefixIPv4LSNlriVer4; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpLSNlri; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4; import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4; import org.onosproject.bgpio.util.Constants; import org.onosproject.bgpio.util.Validation; @@ -35,7 +35,7 @@ import com.google.common.base.MoreObjects; /** * Provides Implementation of MpUnReach Nlri BGP Path Attribute. */ -public class MpUnReachNlri implements BGPValueType { +public class MpUnReachNlri implements BgpValueType { private static final Logger log = LoggerFactory.getLogger(MpUnReachNlri.class); public static final byte MPUNREACHNLRI_TYPE = 15; @@ -44,7 +44,7 @@ public class MpUnReachNlri implements BGPValueType { private boolean isMpUnReachNlri = false; private final short afi; private final byte safi; - private final List mpUnReachNlri; + private final List mpUnReachNlri; private final int length; /** @@ -55,7 +55,7 @@ public class MpUnReachNlri implements BGPValueType { * @param safi subsequent address family identifier * @param length of MpUnReachNlri */ - public MpUnReachNlri(List mpUnReachNlri, short afi, byte safi, + public MpUnReachNlri(List mpUnReachNlri, short afi, byte safi, int length) { this.mpUnReachNlri = mpUnReachNlri; this.isMpUnReachNlri = true; @@ -69,9 +69,9 @@ public class MpUnReachNlri implements BGPValueType { * * @param cb ChannelBuffer * @return object of MpUnReachNlri - * @throws BGPParseException while parsing MpUnReachNlri + * @throws BgpParseException while parsing MpUnReachNlri */ - public static MpUnReachNlri read(ChannelBuffer cb) throws BGPParseException { + public static MpUnReachNlri read(ChannelBuffer cb) throws BgpParseException { ChannelBuffer tempBuf = cb.copy(); Validation parseFlags = Validation.parseAttributeHeader(cb); int len = parseFlags.isShort() ? parseFlags.getLength() + Constants.TYPE_AND_LEN_AS_SHORT @@ -80,17 +80,17 @@ public class MpUnReachNlri implements BGPValueType { if (!parseFlags.getFirstBit() && parseFlags.getSecondBit() && parseFlags.getThirdBit()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data); } if (cb.readableBytes() < parseFlags.getLength()) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, parseFlags.getLength()); + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, parseFlags.getLength()); } - LinkedList mpUnReachNlri = new LinkedList<>(); - BGPLSNlri bgpLSNlri = null; + LinkedList mpUnReachNlri = new LinkedList<>(); + BgpLSNlri bgpLSNlri = null; short afi = 0; byte safi = 0; ChannelBuffer tempCb = cb.readBytes(parseFlags.getLength()); @@ -106,19 +106,19 @@ public class MpUnReachNlri implements BGPValueType { short totNlriLen = tempCb.readShort(); if (tempCb.readableBytes() < totNlriLen) { Validation.validateLen( - BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen); + BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen); } tempBuf = tempCb.readBytes(totNlriLen); switch (nlriType) { - case BGPNodeLSNlriVer4.NODE_NLRITYPE: - bgpLSNlri = BGPNodeLSNlriVer4.read(tempBuf, afi, safi); + case BgpNodeLSNlriVer4.NODE_NLRITYPE: + bgpLSNlri = BgpNodeLSNlriVer4.read(tempBuf, afi, safi); break; case BgpLinkLsNlriVer4.LINK_NLRITYPE: bgpLSNlri = BgpLinkLsNlriVer4.read(tempBuf, afi, safi); break; - case BGPPrefixIPv4LSNlriVer4.PREFIX_IPV4_NLRITYPE: - bgpLSNlri = BGPPrefixIPv4LSNlriVer4.read(tempBuf, afi, + case BgpPrefixIPv4LSNlriVer4.PREFIX_IPV4_NLRITYPE: + bgpLSNlri = BgpPrefixIPv4LSNlriVer4.read(tempBuf, afi, safi); break; default: @@ -128,7 +128,7 @@ public class MpUnReachNlri implements BGPValueType { } } else { //TODO: check with the values got from capability - throw new BGPParseException("Not Supporting afi " + afi + throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi); } } @@ -164,7 +164,7 @@ public class MpUnReachNlri implements BGPValueType { * * @return list of MpUnReach Nlri */ - public List mpUnReachNlri() { + public List mpUnReachNlri() { return this.mpUnReachNlri; } @@ -192,6 +192,12 @@ public class MpUnReachNlri implements BGPValueType { return 0; } + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java old mode 100755 new mode 100644 index 9beff68c..7082483e --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/MultiProtocolExtnCapabilityTlv.java @@ -25,7 +25,7 @@ import com.google.common.base.MoreObjects; /** * Provides MultiProtocolExtnCapabilityTlv. */ -public class MultiProtocolExtnCapabilityTlv implements BGPValueType { +public class MultiProtocolExtnCapabilityTlv implements BgpValueType { /* 0 7 15 23 31 @@ -141,7 +141,7 @@ public class MultiProtocolExtnCapabilityTlv implements BGPValueType { * @param cb of type channel buffer * @return object of MultiProtocolExtnCapabilityTlv */ - public static BGPValueType read(ChannelBuffer cb) { + public static BgpValueType read(ChannelBuffer cb) { short afi = cb.readShort(); byte res = cb.readByte(); byte safi = cb.readByte(); @@ -157,4 +157,10 @@ public class MultiProtocolExtnCapabilityTlv implements BGPValueType { .add("Reserved", res) .add("SAFI", safi).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/NextHop.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/NextHop.java index 1d083b72..806efe52 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/NextHop.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/NextHop.java @@ -20,7 +20,7 @@ import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; import org.onlab.packet.Ip4Address; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; import org.onosproject.bgpio.util.Constants; import org.onosproject.bgpio.util.Validation; @@ -30,7 +30,7 @@ import com.google.common.base.Preconditions; /** * Implementation of NextHop BGP Path Attribute. */ -public class NextHop implements BGPValueType { +public class NextHop implements BgpValueType { public static final byte NEXTHOP_TYPE = 3; private boolean isNextHop = false; @@ -60,27 +60,27 @@ public class NextHop implements BGPValueType { * * @param cb ChannelBuffer * @return object of NextHop - * @throws BGPParseException while parsing nexthop attribute + * @throws BgpParseException while parsing nexthop attribute */ - public static NextHop read(ChannelBuffer cb) throws BGPParseException { + public static NextHop read(ChannelBuffer cb) throws BgpParseException { Ip4Address nextHop; ChannelBuffer tempCb = cb.copy(); Validation parseFlags = Validation.parseAttributeHeader(cb); if (cb.readableBytes() < parseFlags.getLength()) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR, parseFlags.getLength()); } int len = parseFlags.isShort() ? parseFlags.getLength() + Constants.TYPE_AND_LEN_AS_SHORT : parseFlags .getLength() + Constants.TYPE_AND_LEN_AS_BYTE; ChannelBuffer data = tempCb.readBytes(len); if (parseFlags.getFirstBit() && !parseFlags.getSecondBit() && parseFlags.getThirdBit()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data); } InetAddress ipAddress = Validation.toInetAddress(parseFlags.getLength(), cb); if (ipAddress.isMulticastAddress()) { - throw new BGPParseException("Multicast address is not supported"); + throw new BgpParseException("Multicast address is not supported"); } nextHop = Ip4Address.valueOf(ipAddress); @@ -130,4 +130,10 @@ public class NextHop implements BGPValueType { .add("nextHop", nextHop) .toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFNonPseudonode.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFNonPseudonode.java index 6d8282b7..d281a4ef 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFNonPseudonode.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFNonPseudonode.java @@ -20,18 +20,13 @@ import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; import org.onosproject.bgpio.protocol.IGPRouterID; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.base.MoreObjects; /** * Provides implementation of OSPFNonPseudonode Tlv. */ -public class OSPFNonPseudonode implements IGPRouterID, BGPValueType { - - protected static final Logger log = LoggerFactory.getLogger(OSPFNonPseudonode.class); - +public class OSPFNonPseudonode implements IGPRouterID, BgpValueType { public static final short TYPE = 515; public static final short LENGTH = 4; @@ -107,6 +102,14 @@ public class OSPFNonPseudonode implements IGPRouterID, BGPValueType { return TYPE; } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + return ((Integer) (this.routerID)).compareTo((Integer) (((OSPFNonPseudonode) o).routerID)); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFPseudonode.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFPseudonode.java index 82a39bd1..0d17651a 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFPseudonode.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFPseudonode.java @@ -20,18 +20,13 @@ import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; import org.onlab.packet.Ip4Address; import org.onosproject.bgpio.protocol.IGPRouterID; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.base.MoreObjects; /** * Provides implementation of OSPFPseudonode Tlv. */ -public class OSPFPseudonode implements IGPRouterID, BGPValueType { - - protected static final Logger log = LoggerFactory.getLogger(OSPFPseudonode.class); - +public class OSPFPseudonode implements IGPRouterID, BgpValueType { public static final short TYPE = 515; public static final short LENGTH = 8; @@ -113,6 +108,18 @@ public class OSPFPseudonode implements IGPRouterID, BGPValueType { return TYPE; } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + int result = ((Integer) (this.routerID)).compareTo((Integer) (((OSPFPseudonode) o).routerID)); + if (result != 0) { + return this.drInterface.compareTo(((OSPFPseudonode) o).drInterface); + } + return result; + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFRouteTypeTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFRouteTypeTlv.java index 20fffbfa..be321c95 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFRouteTypeTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/OSPFRouteTypeTlv.java @@ -18,16 +18,14 @@ package org.onosproject.bgpio.types; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.onosproject.bgpio.exceptions.BgpParseException; import com.google.common.base.MoreObjects; /** * Provides OSPF Route Type Tlv which contains route type. */ -public class OSPFRouteTypeTlv implements BGPValueType { +public class OSPFRouteTypeTlv implements BgpValueType { /* Reference :draft-ietf-idr-ls-distribution-11 0 1 2 3 @@ -41,8 +39,6 @@ public class OSPFRouteTypeTlv implements BGPValueType { Figure : OSPF Route Type TLV Format */ - protected static final Logger log = LoggerFactory.getLogger(OSPFRouteTypeTlv.class); - public static final short TYPE = 264; public static final short LENGTH = 1; public static final int INTRA_AREA_TYPE = 1; @@ -51,15 +47,16 @@ public class OSPFRouteTypeTlv implements BGPValueType { public static final short EXTERNAL_TYPE_2 = 4; public static final short NSSA_TYPE_1 = 5; public static final short NSSA_TYPE_2 = 6; + private final byte routeType; /** * Enum for Route Type. */ - public enum ROUTETYPE { + public enum RouteType { Intra_Area(1), Inter_Area(2), External_1(3), External_2(4), NSSA_1(5), NSSA_2(6); int value; - ROUTETYPE(int val) { + RouteType(int val) { value = val; } public byte getType() { @@ -90,24 +87,24 @@ public class OSPFRouteTypeTlv implements BGPValueType { * Returns RouteType. * * @return RouteType - * @throws BGPParseException if routeType is not matched + * @throws BgpParseException if routeType is not matched */ - public ROUTETYPE getValue() throws BGPParseException { + public RouteType getValue() throws BgpParseException { switch (routeType) { case INTRA_AREA_TYPE: - return ROUTETYPE.Intra_Area; + return RouteType.Intra_Area; case INTER_AREA_TYPE: - return ROUTETYPE.Inter_Area; + return RouteType.Inter_Area; case EXTERNAL_TYPE_1: - return ROUTETYPE.External_1; + return RouteType.External_1; case EXTERNAL_TYPE_2: - return ROUTETYPE.External_2; + return RouteType.External_2; case NSSA_TYPE_1: - return ROUTETYPE.NSSA_1; + return RouteType.NSSA_1; case NSSA_TYPE_2: - return ROUTETYPE.NSSA_2; + return RouteType.NSSA_2; default: - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); } } @@ -152,6 +149,14 @@ public class OSPFRouteTypeTlv implements BGPValueType { return TYPE; } + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + return ((Byte) (this.routeType)).compareTo((Byte) (((OSPFRouteTypeTlv) o).routeType)); + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Origin.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Origin.java index 2052e965..d642d83c 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Origin.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/Origin.java @@ -18,7 +18,7 @@ package org.onosproject.bgpio.types; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; import org.onosproject.bgpio.util.Constants; import org.onosproject.bgpio.util.Validation; @@ -27,7 +27,7 @@ import com.google.common.base.MoreObjects; /** * Provides Implementation of mandatory BGP Origin path attribute. */ -public class Origin implements BGPValueType { +public class Origin implements BgpValueType { /** * Enum to provide ORIGIN types. @@ -99,9 +99,9 @@ public class Origin implements BGPValueType { * * @param cb ChannelBuffer * @return object of Origin - * @throws BGPParseException while parsing Origin path attribute + * @throws BgpParseException while parsing Origin path attribute */ - public static Origin read(ChannelBuffer cb) throws BGPParseException { + public static Origin read(ChannelBuffer cb) throws BgpParseException { ChannelBuffer tempCb = cb.copy(); Validation parseFlags = Validation.parseAttributeHeader(cb); @@ -109,18 +109,18 @@ public class Origin implements BGPValueType { .getLength() + Constants.TYPE_AND_LEN_AS_BYTE; ChannelBuffer data = tempCb.readBytes(len); if ((parseFlags.getLength() > ORIGIN_VALUE_LEN) || (cb.readableBytes() < parseFlags.getLength())) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR, parseFlags.getLength()); } if (parseFlags.getFirstBit() && !parseFlags.getSecondBit() && parseFlags.getThirdBit()) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data); } byte originValue; originValue = cb.readByte(); if ((originValue != ORIGINTYPE.INCOMPLETE.value) && (originValue != ORIGINTYPE.IGP.value) && (originValue != ORIGINTYPE.EGP.value)) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.INVALID_ORIGIN_ATTRIBUTE, data); + throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.INVALID_ORIGIN_ATTRIBUTE, data); } return new Origin(originValue); } @@ -159,4 +159,10 @@ public class Origin implements BGPValueType { .add("origin", origin) .toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteDistinguisher.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteDistinguisher.java index d0267092..37632ad8 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteDistinguisher.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/RouteDistinguisher.java @@ -18,10 +18,12 @@ package org.onosproject.bgpio.types; import org.jboss.netty.buffer.ChannelBuffer; +import com.google.common.base.MoreObjects; + /** * Implementation of RouteDistinguisher. */ -public class RouteDistinguisher { +public class RouteDistinguisher implements Comparable { private long routeDistinguisher; @@ -59,4 +61,19 @@ public class RouteDistinguisher { public long getRouteDistinguisher() { return this.routeDistinguisher; } + + @Override + public int compareTo(RouteDistinguisher rd) { + if (this.equals(rd)) { + return 0; + } + return ((Long) (this.getRouteDistinguisher())).compareTo((Long) (rd.getRouteDistinguisher())); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("routeDistinguisher", routeDistinguisher) + .toString(); + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeFlagBitTlv.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeFlagBitTlv.java index e7f4a4c0..e0fef7c8 100755 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeFlagBitTlv.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeFlagBitTlv.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP attribute node flag. */ -public final class BgpAttrNodeFlagBitTlv implements BGPValueType { +public final class BgpAttrNodeFlagBitTlv implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpAttrNodeFlagBitTlv.class); @@ -86,10 +86,10 @@ public final class BgpAttrNodeFlagBitTlv implements BGPValueType { * * @param cb ChannelBuffer * @return attribute node flag bit tlv - * @throws BGPParseException while parsing BgpAttrNodeFlagBitTlv + * @throws BgpParseException while parsing BgpAttrNodeFlagBitTlv */ public static BgpAttrNodeFlagBitTlv read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { boolean bOverloadBit = false; boolean bAttachedBit = false; boolean bExternalBit = false; @@ -98,8 +98,8 @@ public final class BgpAttrNodeFlagBitTlv implements BGPValueType { short lsAttrLength = cb.readShort(); if ((lsAttrLength != 1) || (cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -190,4 +190,10 @@ public final class BgpAttrNodeFlagBitTlv implements BGPValueType { .add("bExternalBit", bExternalBit).add("bAbrBit", bAbrBit) .toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeIsIsAreaId.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeIsIsAreaId.java new file mode 100644 index 00000000..0435a65f --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeIsIsAreaId.java @@ -0,0 +1,136 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import java.util.Arrays; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP attribute ISIS Area Identifier. + */ +public class BgpAttrNodeIsIsAreaId implements BgpValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpAttrNodeIsIsAreaId.class); + + public static final int ATTRNODE_ISISAREAID = 1027; + + /* IS-IS Area Identifier TLV */ + private byte[] isisAreaId; + + /** + * Constructor to initialize value. + * + * @param isisAreaId ISIS area Identifier + */ + public BgpAttrNodeIsIsAreaId(byte[] isisAreaId) { + this.isisAreaId = Arrays.copyOf(isisAreaId, isisAreaId.length); + } + + /** + * Returns object of this class with specified values. + * + * @param isisAreaId ISIS area Identifier + * @return object of BgpAttrNodeIsIsAreaId + */ + public static BgpAttrNodeIsIsAreaId of(final byte[] isisAreaId) { + return new BgpAttrNodeIsIsAreaId(isisAreaId); + } + + /** + * Reads the IS-IS Area Identifier. + * + * @param cb ChannelBuffer + * @return object of BgpAttrNodeIsIsAreaId + * @throws BgpParseException while parsing BgpAttrNodeIsIsAreaId + */ + public static BgpAttrNodeIsIsAreaId read(ChannelBuffer cb) + throws BgpParseException { + byte[] isisAreaId; + + short lsAttrLength = cb.readShort(); + + if (cb.readableBytes() < lsAttrLength) { + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + isisAreaId = new byte[lsAttrLength]; + cb.readBytes(isisAreaId); + + return BgpAttrNodeIsIsAreaId.of(isisAreaId); + } + + /** + * Returns ISIS area Identifier. + * + * @return Area ID + */ + public byte[] attrNodeIsIsAreaId() { + return isisAreaId; + } + + @Override + public short getType() { + return ATTRNODE_ISISAREAID; + } + + @Override + public int hashCode() { + return Arrays.hashCode(isisAreaId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpAttrNodeIsIsAreaId) { + BgpAttrNodeIsIsAreaId other = (BgpAttrNodeIsIsAreaId) obj; + return Arrays.equals(isisAreaId, other.isisAreaId); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO This will be implemented in the next version + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("isisAreaId", isisAreaId).toString(); + } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeMultiTopologyId.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeMultiTopologyId.java index 4b704fb0..31d855db 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeMultiTopologyId.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeMultiTopologyId.java @@ -17,12 +17,13 @@ package org.onosproject.bgpio.types.attr; import java.util.ArrayList; import java.util.List; +import java.util.ListIterator; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +33,7 @@ import com.google.common.base.MoreObjects; /** * BGP Multi-Topology ID of the LS attribute. */ -public class BgpAttrNodeMultiTopologyId implements BGPValueType { +public class BgpAttrNodeMultiTopologyId implements BgpValueType { private static final Logger log = LoggerFactory .getLogger(BgpAttrNodeMultiTopologyId.class); @@ -66,18 +67,18 @@ public class BgpAttrNodeMultiTopologyId implements BGPValueType { * * @param cb ChannelBuffer * @return Constructor of BgpAttrNodeMultiTopologyId - * @throws BGPParseException while parsing BgpAttrNodeMultiTopologyId + * @throws BgpParseException while parsing BgpAttrNodeMultiTopologyId */ public static BgpAttrNodeMultiTopologyId read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { ArrayList multiTopologyId = new ArrayList(); short tempMultiTopologyId; short lsAttrLength = cb.readShort(); int len = lsAttrLength / 2; // Length is 2*n and n is the number of MT-IDs if (cb.readableBytes() < lsAttrLength) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -134,4 +135,30 @@ public class BgpAttrNodeMultiTopologyId implements BGPValueType { .add("multiTopologyId", multiTopologyId) .toString(); } + + @Override + public int compareTo(Object o) { + if (this.equals(o)) { + return 0; + } + int countOtherSubTlv = ((BgpAttrNodeMultiTopologyId) o).multiTopologyId.size(); + int countObjSubTlv = multiTopologyId.size(); + if (countOtherSubTlv != countObjSubTlv) { + if (countOtherSubTlv > countObjSubTlv) { + return 1; + } else { + return -1; + } + } + ListIterator listIterator = multiTopologyId.listIterator(); + ListIterator listIteratorOther = ((BgpAttrNodeMultiTopologyId) o).multiTopologyId.listIterator(); + while (listIterator.hasNext()) { + short id = listIterator.next(); + short id1 = listIteratorOther.next(); + if (((Short) id).compareTo((Short) id1) != 0) { + return ((Short) id).compareTo((Short) id1); + } + } + return 0; + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeName.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeName.java new file mode 100644 index 00000000..2e1c7a05 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrNodeName.java @@ -0,0 +1,135 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import java.util.Arrays; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP attribute node name. + */ +public class BgpAttrNodeName implements BgpValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpAttrNodeName.class); + + public static final int ATTRNODE_NAME = 1026; + + /* Node Name */ + private byte[] nodeName; + + /** + * Constructor to initialize value. + * + * @param nodeName node name + */ + public BgpAttrNodeName(byte[] nodeName) { + this.nodeName = Arrays.copyOf(nodeName, nodeName.length); + } + + /** + * Returns object of this class with specified values. + * + * @param nodeName node name + * @return object of BgpAttrNodeName + */ + public static BgpAttrNodeName of(final byte[] nodeName) { + return new BgpAttrNodeName(nodeName); + } + + /** + * Reads the LS attribute node name. + * + * @param cb ChannelBuffer + * @return object of BgpAttrNodeName + * @throws BgpParseException while parsing BgpAttrNodeName + */ + public static BgpAttrNodeName read(ChannelBuffer cb) + throws BgpParseException { + byte[] nodeName; + + short lsAttrLength = cb.readShort(); + + if (cb.readableBytes() < lsAttrLength) { + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + nodeName = new byte[lsAttrLength]; + cb.readBytes(nodeName); + return BgpAttrNodeName.of(nodeName); + } + + /** + * Returns LS attribute node name. + * + * @return node name + */ + public byte[] attrNodeName() { + return nodeName; + } + + @Override + public short getType() { + return ATTRNODE_NAME; + } + + @Override + public int hashCode() { + return Arrays.hashCode(nodeName); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpAttrNodeName) { + BgpAttrNodeName other = (BgpAttrNodeName) obj; + return Arrays.equals(nodeName, other.nodeName); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO This will be implemented in the next version + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("nodeName", nodeName).toString(); + } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrOpaqueNode.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrOpaqueNode.java new file mode 100644 index 00000000..545755a7 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrOpaqueNode.java @@ -0,0 +1,138 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import java.util.Arrays; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP attribute opaque node. + */ +public class BgpAttrOpaqueNode implements BgpValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpAttrOpaqueNode.class); + + public static final int ATTRNODE_OPAQUEDATA = 1025; + + /* Opaque Node Attribute */ + private byte[] opaqueNodeAttribute; + + /** + * Constructor to initialize parameter. + * + * @param opaqueNodeAttribute opaque node attribute + */ + public BgpAttrOpaqueNode(byte[] opaqueNodeAttribute) { + this.opaqueNodeAttribute = Arrays.copyOf(opaqueNodeAttribute, opaqueNodeAttribute.length); + } + + /** + * Returns object of this class with specified values. + * + * @param opaqueNodeAttribute Prefix Metric + * @return object of BgpAttrOpaqueNode + */ + public static BgpAttrOpaqueNode of(byte[] opaqueNodeAttribute) { + return new BgpAttrOpaqueNode(opaqueNodeAttribute); + } + + /** + * Reads the Opaque Node Properties. + * + * @param cb ChannelBuffer + * @return object of BgpAttrOpaqueNode + * @throws BgpParseException while parsing BgpAttrOpaqueNode + */ + public static BgpAttrOpaqueNode read(ChannelBuffer cb) + throws BgpParseException { + + byte[] opaqueNodeAttribute; + + short lsAttrLength = cb.readShort(); + + if (cb.readableBytes() < lsAttrLength) { + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + opaqueNodeAttribute = new byte[lsAttrLength]; + cb.readBytes(opaqueNodeAttribute); + + return BgpAttrOpaqueNode.of(opaqueNodeAttribute); + } + + /** + * Returns opaque node attribute. + * + * @return LS node attribute value + */ + public byte[] attrOpaqueNode() { + return opaqueNodeAttribute; + } + + @Override + public short getType() { + return ATTRNODE_OPAQUEDATA; + } + + @Override + public int hashCode() { + return Arrays.hashCode(opaqueNodeAttribute); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpAttrOpaqueNode) { + BgpAttrOpaqueNode other = (BgpAttrOpaqueNode) obj; + return Arrays + .equals(opaqueNodeAttribute, other.opaqueNodeAttribute); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO This will be implemented in the next version + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("opaqueNodeAttribute", opaqueNodeAttribute).toString(); + } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV4.java old mode 100755 new mode 100644 index a10d167a..f3c0d17b --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV4.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV4.java @@ -19,9 +19,9 @@ import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; import org.onlab.packet.Ip4Address; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,7 +31,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP attribute node router ID. */ -public final class BgpAttrRouterIdV4 implements BGPValueType { +public final class BgpAttrRouterIdV4 implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpAttrRouterIdV4.class); @@ -70,15 +70,15 @@ public final class BgpAttrRouterIdV4 implements BGPValueType { * @param cb ChannelBuffer * @param sType tag type * @return object of BgpAttrRouterIdV4 - * @throws BGPParseException while parsing BgpAttrRouterIdV4 + * @throws BgpParseException while parsing BgpAttrRouterIdV4 */ public static BgpAttrRouterIdV4 read(ChannelBuffer cb, short sType) - throws BGPParseException { + throws BgpParseException { short lsAttrLength = cb.readShort(); if ((lsAttrLength != 4) || (cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -131,4 +131,10 @@ public final class BgpAttrRouterIdV4 implements BGPValueType { return MoreObjects.toStringHelper(getClass()).omitNullValues() .add("ip4RouterId", ip4RouterId).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV6.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV6.java old mode 100755 new mode 100644 index ea63c379..648fd56e --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV6.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV6.java @@ -19,9 +19,9 @@ import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; import org.onlab.packet.Ip6Address; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,7 +31,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP attribute IPv6 router ID. */ -public final class BgpAttrRouterIdV6 implements BGPValueType { +public final class BgpAttrRouterIdV6 implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpAttrRouterIdV6.class); @@ -70,18 +70,18 @@ public final class BgpAttrRouterIdV6 implements BGPValueType { * @param cb ChannelBuffer * @param sType TLV type * @return object of BgpAttrRouterIdV6 - * @throws BGPParseException while parsing BgpAttrRouterIdV6 + * @throws BgpParseException while parsing BgpAttrRouterIdV6 */ public static BgpAttrRouterIdV6 read(ChannelBuffer cb, short sType) - throws BGPParseException { + throws BgpParseException { byte[] ipBytes; Ip6Address ip6RouterId; short lsAttrLength = cb.readShort(); if ((lsAttrLength != 16) || (cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -134,4 +134,10 @@ public final class BgpAttrRouterIdV6 implements BGPValueType { return MoreObjects.toStringHelper(getClass()).omitNullValues() .add("ip6RouterId", ip6RouterId).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIgpMetric.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIgpMetric.java old mode 100755 new mode 100644 index c1cb299c..5721cf6c --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIgpMetric.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIgpMetric.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP link IGP metric attribute. */ -public class BgpLinkAttrIgpMetric implements BGPValueType { +public class BgpLinkAttrIgpMetric implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpLinkAttrIgpMetric.class); @@ -75,10 +75,10 @@ public class BgpLinkAttrIgpMetric implements BGPValueType { * * @param cb Channel buffer * @return object of type BgpLinkAttrIgpMetric - * @throws BGPParseException while parsing BgpLinkAttrIgpMetric + * @throws BgpParseException while parsing BgpLinkAttrIgpMetric */ public static BgpLinkAttrIgpMetric read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { short linkigp; int igpMetric = 0; @@ -88,8 +88,8 @@ public class BgpLinkAttrIgpMetric implements BGPValueType { if (cb.readableBytes() < lsAttrLength || lsAttrLength > ATTRLINK_MAX_LEN) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -169,4 +169,10 @@ public class BgpLinkAttrIgpMetric implements BGPValueType { .add("igpMetric", igpMetric).add("igpMetricLen", igpMetricLen) .toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIsIsAdminstGrp.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIsIsAdminstGrp.java index 086e8b06..448f1e58 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIsIsAdminstGrp.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIsIsAdminstGrp.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP attribute Is Is Administrative area. */ -public final class BgpLinkAttrIsIsAdminstGrp implements BGPValueType { +public final class BgpLinkAttrIsIsAdminstGrp implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpLinkAttrIsIsAdminstGrp.class); @@ -65,17 +65,17 @@ public final class BgpLinkAttrIsIsAdminstGrp implements BGPValueType { * * @param cb Channel buffer * @return object of type BgpLinkAttrIsIsAdminstGrp - * @throws BGPParseException while parsing BgpLinkAttrIsIsAdminstGrp + * @throws BgpParseException while parsing BgpLinkAttrIsIsAdminstGrp */ public static BgpLinkAttrIsIsAdminstGrp read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { long isisAdminGrp; short lsAttrLength = cb.readShort(); if ((lsAttrLength != ISIS_ADMIN_DATA_LEN) || (cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -127,4 +127,10 @@ public final class BgpLinkAttrIsIsAdminstGrp implements BGPValueType { return MoreObjects.toStringHelper(getClass()) .add("isisAdminGrp", isisAdminGrp).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidth.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidth.java index a1f0198b..2711ca94 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidth.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidth.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP attribute Max Link bandwidth. */ -public final class BgpLinkAttrMaxLinkBandwidth implements BGPValueType { +public final class BgpLinkAttrMaxLinkBandwidth implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpLinkAttrMaxLinkBandwidth.class); @@ -72,17 +72,17 @@ public final class BgpLinkAttrMaxLinkBandwidth implements BGPValueType { * @param cb Channel buffer * @param type type of this tlv * @return object of type BgpLinkAttrMaxLinkBandwidth - * @throws BGPParseException while parsing BgpLinkAttrMaxLinkBandwidth + * @throws BgpParseException while parsing BgpLinkAttrMaxLinkBandwidth */ public static BgpLinkAttrMaxLinkBandwidth read(ChannelBuffer cb, short type) - throws BGPParseException { + throws BgpParseException { float maxBandwidth; short lsAttrLength = cb.readShort(); if ((lsAttrLength != MAX_BANDWIDTH_LEN) || (cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -147,4 +147,10 @@ public final class BgpLinkAttrMaxLinkBandwidth implements BGPValueType { return MoreObjects.toStringHelper(getClass()) .add("maxBandwidth", maxBandwidth).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMplsProtocolMask.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMplsProtocolMask.java old mode 100755 new mode 100644 index 61143fae..2bf1a59d --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMplsProtocolMask.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMplsProtocolMask.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP MPLS protocol mask attribute. */ -public class BgpLinkAttrMplsProtocolMask implements BGPValueType { +public class BgpLinkAttrMplsProtocolMask implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpLinkAttrMplsProtocolMask.class); @@ -72,10 +72,10 @@ public class BgpLinkAttrMplsProtocolMask implements BGPValueType { * * @param cb Channel buffer * @return object of type BgpLinkAttrMPLSProtocolMask - * @throws BGPParseException while parsing BgpLinkAttrMplsProtocolMask + * @throws BgpParseException while parsing BgpLinkAttrMplsProtocolMask */ public static BgpLinkAttrMplsProtocolMask read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { boolean bLdp = false; boolean bRsvpTe = false; @@ -83,8 +83,8 @@ public class BgpLinkAttrMplsProtocolMask implements BGPValueType { if ((lsAttrLength != MASK_BYTE_LEN) || (cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -149,4 +149,10 @@ public class BgpLinkAttrMplsProtocolMask implements BGPValueType { return MoreObjects.toStringHelper(getClass()) .add("bLdp", bLdp).add("bRsvpTe", bRsvpTe).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrName.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrName.java old mode 100755 new mode 100644 index e44ba7e1..856ffc36 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrName.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrName.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Arrays; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP link name attribute. */ -public class BgpLinkAttrName implements BGPValueType { +public class BgpLinkAttrName implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpLinkAttrName.class); @@ -64,16 +64,16 @@ public class BgpLinkAttrName implements BGPValueType { * * @param cb Channel buffer * @return object of type BgpLinkAttrName - * @throws BGPParseException while parsing BgpLinkAttrName + * @throws BgpParseException while parsing BgpLinkAttrName */ public static BgpLinkAttrName read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { byte[] linkName; short lsAttrLength = cb.readShort(); if (cb.readableBytes() < lsAttrLength) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -125,4 +125,10 @@ public class BgpLinkAttrName implements BGPValueType { return MoreObjects.toStringHelper(getClass()).omitNullValues() .add("linkName", linkName).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrOpaqLnkAttrib.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrOpaqLnkAttrib.java old mode 100755 new mode 100644 index 258598be..275b85be --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrOpaqLnkAttrib.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrOpaqLnkAttrib.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Arrays; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP link opaque attribute. */ -public final class BgpLinkAttrOpaqLnkAttrib implements BGPValueType { +public final class BgpLinkAttrOpaqLnkAttrib implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpLinkAttrOpaqLnkAttrib.class); @@ -65,18 +65,18 @@ public final class BgpLinkAttrOpaqLnkAttrib implements BGPValueType { * * @param cb Channel buffer * @return object of type BgpLinkAttrOpaqLnkAttrib - * @throws BGPParseException while parsing BgpLinkAttrOpaqLnkAttrib + * @throws BgpParseException while parsing BgpLinkAttrOpaqLnkAttrib */ public static BgpLinkAttrOpaqLnkAttrib read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { byte[] opaqueLinkAttribute; short lsAttrLength = cb.readShort(); if (cb.readableBytes() < lsAttrLength) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -130,4 +130,10 @@ public final class BgpLinkAttrOpaqLnkAttrib implements BGPValueType { return MoreObjects.toStringHelper(getClass()).omitNullValues() .add("opaqueLinkAttribute", opaqueLinkAttribute).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrProtectionType.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrProtectionType.java old mode 100755 new mode 100644 index b45d95b8..59011d97 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrProtectionType.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrProtectionType.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP link protection type attribute. */ -public final class BgpLinkAttrProtectionType implements BGPValueType { +public final class BgpLinkAttrProtectionType implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpLinkAttrProtectionType.class); @@ -102,10 +102,10 @@ public final class BgpLinkAttrProtectionType implements BGPValueType { * * @param cb Channel buffer * @return object of type BgpLinkAttrProtectionType - * @throws BGPParseException while parsing BgpLinkAttrProtectionType + * @throws BgpParseException while parsing BgpLinkAttrProtectionType */ public static BgpLinkAttrProtectionType read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { short linkProtectionType; byte higherByte; short lsAttrLength = cb.readShort(); @@ -119,8 +119,8 @@ public final class BgpLinkAttrProtectionType implements BGPValueType { if ((lsAttrLength != LINK_PROTECTION_LEN) || (cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -237,4 +237,10 @@ public final class BgpLinkAttrProtectionType implements BGPValueType { .add("bDedOnePlusOne", bDedOnePlusOne) .add("bEnhanced", bEnhanced).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrSrlg.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrSrlg.java new file mode 100644 index 00000000..4a6f23f9 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrSrlg.java @@ -0,0 +1,136 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.util.Validation; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP link Shared Risk Link Group attribute. + */ +public class BgpLinkAttrSrlg implements BgpValueType { + + public static final short ATTRNODE_SRLG = 1097; + + /* Shared Risk Link Group */ + private List sRlg = new ArrayList(); + + /** + * Constructor to initialize the date. + * + * @param sRlg Shared Risk link group data + */ + public BgpLinkAttrSrlg(List sRlg) { + this.sRlg = sRlg; + } + + /** + * Returns object of this class with specified values. + * + * @param sRlg Shared Risk link group data + * @return object of BgpLinkAttrSrlg + */ + public static BgpLinkAttrSrlg of(ArrayList sRlg) { + return new BgpLinkAttrSrlg(sRlg); + } + + /** + * Reads the BGP link attributes Shared Risk link group data. + * + * @param cb Channel buffer + * @return object of type BgpLinkAttrSrlg + * @throws BgpParseException while parsing BgpLinkAttrSrlg + */ + public static BgpLinkAttrSrlg read(ChannelBuffer cb) + throws BgpParseException { + int tempSrlg; + ArrayList sRlg = new ArrayList(); + + short lsAttrLength = cb.readShort(); + int len = lsAttrLength / Integer.SIZE; // each element is of 4 octets + + if (cb.readableBytes() < lsAttrLength) { + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + for (int i = 0; i < len; i++) { + tempSrlg = cb.readInt(); + sRlg.add(new Integer(tempSrlg)); + } + + return BgpLinkAttrSrlg.of(sRlg); + } + + /** + * Returns the Shared Risk link group data. + * + * @return array of Shared Risk link group data + */ + public List attrSrlg() { + return sRlg; + } + + @Override + public short getType() { + return ATTRNODE_SRLG; + } + + @Override + public int hashCode() { + return Objects.hash(sRlg); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpLinkAttrSrlg) { + BgpLinkAttrSrlg other = (BgpLinkAttrSrlg) obj; + return Objects.equals(sRlg, other.sRlg); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO This will be implemented in the next version + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues().add("sRlg", sRlg).toString(); + } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetric.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetric.java old mode 100755 new mode 100644 index 7febe3c3..1ae7ecc5 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetric.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetric.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP link state Default TE metric link attribute. */ -public class BgpLinkAttrTeDefaultMetric implements BGPValueType { +public class BgpLinkAttrTeDefaultMetric implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpLinkAttrTeDefaultMetric.class); @@ -66,18 +66,18 @@ public class BgpLinkAttrTeDefaultMetric implements BGPValueType { * * @param cb Channel buffer * @return object of type BgpLinkAttrTeDefaultMetric - * @throws BGPParseException while parsing BgpLinkAttrTeDefaultMetric + * @throws BgpParseException while parsing BgpLinkAttrTeDefaultMetric */ public static BgpLinkAttrTeDefaultMetric read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { int linkTeMetric; short lsAttrLength = cb.readShort(); if ((lsAttrLength != TE_DATA_LEN) || (cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -129,4 +129,10 @@ public class BgpLinkAttrTeDefaultMetric implements BGPValueType { return MoreObjects.toStringHelper(getClass()) .add("linkTEMetric", linkTeMetric).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrUnRsrvdLinkBandwidth.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrUnRsrvdLinkBandwidth.java new file mode 100644 index 00000000..c927eea5 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrUnRsrvdLinkBandwidth.java @@ -0,0 +1,163 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP unreserved bandwidth attribute. + */ +public class BgpLinkAttrUnRsrvdLinkBandwidth implements BgpValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpLinkAttrUnRsrvdLinkBandwidth.class); + + public static final int MAX_BANDWIDTH_LEN = 4; + public static final int NO_OF_BITS = 8; + public static final int NO_OF_PRIORITY = 8; + + public short sType; + + /* ISIS administrative group */ + private List maxUnResBandwidth = new ArrayList(); + + /** + * Constructor to initialize the values. + * + * @param maxUnResBandwidth Maximum Unreserved bandwidth + * @param sType returns the tag value + */ + public BgpLinkAttrUnRsrvdLinkBandwidth(List maxUnResBandwidth, + short sType) { + this.maxUnResBandwidth = maxUnResBandwidth; + this.sType = sType; + } + + /** + * Returns object of this class with specified values. + * + * @param linkPfxMetric Prefix Metric + * @param sType returns the tag value + * @return object of BgpLinkAttrUnRsrvdLinkBandwidth + */ + public static BgpLinkAttrUnRsrvdLinkBandwidth of(List linkPfxMetric, short sType) { + return new BgpLinkAttrUnRsrvdLinkBandwidth(linkPfxMetric, sType); + } + + /** + * Reads the BGP link attributes of Maximum link bandwidth. + * + * @param cb Channel buffer + * @return object of type BgpLinkAttrMaxLinkBandwidth + * @throws BgpParseException while parsing BgpLinkAttrMaxLinkBandwidth + */ + public static BgpLinkAttrUnRsrvdLinkBandwidth read(ChannelBuffer cb, + short sType) + throws BgpParseException { + ArrayList maxUnResBandwidth = new ArrayList(); + float tmp; + short lsAttrLength = cb.readShort(); + + if ((lsAttrLength != MAX_BANDWIDTH_LEN * NO_OF_PRIORITY) + || (cb.readableBytes() < lsAttrLength)) { + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + for (int i = 0; i < NO_OF_PRIORITY; i++) { + tmp = ieeeToFloatRead(cb.readInt()) * NO_OF_BITS; + maxUnResBandwidth.add(new Float(tmp)); + } + + return BgpLinkAttrUnRsrvdLinkBandwidth.of(maxUnResBandwidth, sType); + } + + /** + * Returns maximum unreserved bandwidth. + * + * @return unreserved bandwidth. + */ + public List getLinkAttrUnRsrvdLinkBandwidth() { + return maxUnResBandwidth; + } + + /** + * Parse the IEEE floating point notation and returns it in normal float. + * + * @param iVal IEEE floating point number + * @return normal float + */ + static float ieeeToFloatRead(int iVal) { + iVal = (((iVal & 0xFF) << 24) | ((iVal & 0xFF00) << 8) + | ((iVal & 0xFF0000) >> 8) | ((iVal >> 24) & 0xFF)); + + return Float.intBitsToFloat(iVal); + } + + @Override + public short getType() { + return this.sType; + } + + @Override + public int hashCode() { + return Objects.hash(maxUnResBandwidth); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpLinkAttrUnRsrvdLinkBandwidth) { + BgpLinkAttrUnRsrvdLinkBandwidth other = (BgpLinkAttrUnRsrvdLinkBandwidth) obj; + return Objects.equals(maxUnResBandwidth, other.maxUnResBandwidth); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO This will be implemented in the next version + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("maxUnResBandwidth", maxUnResBandwidth).toString(); + } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrExtRouteTag.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrExtRouteTag.java new file mode 100644 index 00000000..a2d7c57e --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrExtRouteTag.java @@ -0,0 +1,145 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP prefix route Extended tag attribute. + */ +public class BgpPrefixAttrExtRouteTag implements BgpValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpPrefixAttrExtRouteTag.class); + + public static final int ATTR_PREFIX_EXTROUTETAG = 1154; + public static final int ATTR_PREFIX_EXT_LEN = 8; + + /* Prefix Route Tag */ + private List pfxExtRouteTag = new ArrayList(); + + /** + * Constructor to initialize the values. + * + * @param pfxExtRouteTag Extended route tag + */ + public BgpPrefixAttrExtRouteTag(List pfxExtRouteTag) { + this.pfxExtRouteTag = checkNotNull(pfxExtRouteTag); + } + + /** + * Returns object of this class with specified values. + * + * @param pfxExtRouteTag Prefix Metric + * @return object of BgpPrefixAttrMetric + */ + public static BgpPrefixAttrExtRouteTag of(ArrayList pfxExtRouteTag) { + return new BgpPrefixAttrExtRouteTag(pfxExtRouteTag); + } + + /** + * Reads the Extended Tag. + * + * @param cb ChannelBuffer + * @return object of BgpPrefixAttrExtRouteTag + * @throws BgpParseException while parsing BgpPrefixAttrExtRouteTag + */ + public static BgpPrefixAttrExtRouteTag read(ChannelBuffer cb) + throws BgpParseException { + ArrayList pfxExtRouteTag = new ArrayList(); + long temp; + + short lsAttrLength = cb.readShort(); + int len = lsAttrLength / ATTR_PREFIX_EXT_LEN; + + if (cb.readableBytes() < lsAttrLength) { + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, + lsAttrLength); + } + + for (int i = 0; i < len; i++) { + temp = cb.readLong(); + pfxExtRouteTag.add(new Long(temp)); + } + + return new BgpPrefixAttrExtRouteTag(pfxExtRouteTag); + } + + /** + * Returns Extended route tag. + * + * @return route tag + */ + public List pfxExtRouteTag() { + return pfxExtRouteTag; + } + + @Override + public short getType() { + return ATTR_PREFIX_EXTROUTETAG; + } + + @Override + public int hashCode() { + return Objects.hash(pfxExtRouteTag); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpPrefixAttrExtRouteTag) { + BgpPrefixAttrExtRouteTag other = (BgpPrefixAttrExtRouteTag) obj; + return Objects.equals(pfxExtRouteTag, other.pfxExtRouteTag); + } + return false; + } + + @Override + public int write(ChannelBuffer cb) { + // TODO This will be implemented in the next version + return 0; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("pfxExtRouteTag", pfxExtRouteTag).toString(); + } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIgpFlags.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIgpFlags.java old mode 100755 new mode 100644 index a215e6f1..4e84191a --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIgpFlags.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIgpFlags.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP prefix IGP Flag attribute. */ -public final class BgpPrefixAttrIgpFlags implements BGPValueType { +public final class BgpPrefixAttrIgpFlags implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpPrefixAttrIgpFlags.class); @@ -88,10 +88,10 @@ public final class BgpPrefixAttrIgpFlags implements BGPValueType { * * @param cb ChannelBuffer * @return object of BgpPrefixAttrIGPFlags - * @throws BGPParseException while parsing BgpPrefixAttrIGPFlags + * @throws BgpParseException while parsing BgpPrefixAttrIGPFlags */ public static BgpPrefixAttrIgpFlags read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { boolean bisisUpDownBit = false; boolean bOspfNoUnicastBit = false; boolean bOspfLclAddrBit = false; @@ -101,8 +101,8 @@ public final class BgpPrefixAttrIgpFlags implements BGPValueType { if ((lsAttrLength != ATTR_PREFIX_FLAG_LEN) || (cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -195,4 +195,10 @@ public final class BgpPrefixAttrIgpFlags implements BGPValueType { .add("bOspfLclAddrBit", bOspfLclAddrBit) .add("bOspfNSSABit", bOspfNSSABit).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrMetric.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrMetric.java old mode 100755 new mode 100644 index 0678b81f..1886102c --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrMetric.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrMetric.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP prefix metric attribute. */ -public class BgpPrefixAttrMetric implements BGPValueType { +public class BgpPrefixAttrMetric implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpPrefixAttrMetric.class); @@ -65,18 +65,18 @@ public class BgpPrefixAttrMetric implements BGPValueType { * * @param cb ChannelBuffer * @return object of BgpPrefixAttrMetric - * @throws BGPParseException while parsing BgpPrefixAttrMetric + * @throws BgpParseException while parsing BgpPrefixAttrMetric */ public static BgpPrefixAttrMetric read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { int linkPfxMetric; short lsAttrLength = cb.readShort(); // 4 Bytes if ((lsAttrLength != ATTR_PREFIX_LEN) || (cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -128,4 +128,10 @@ public class BgpPrefixAttrMetric implements BGPValueType { return MoreObjects.toStringHelper(getClass()) .add("linkPfxMetric", linkPfxMetric).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueData.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueData.java old mode 100755 new mode 100644 index c7008ca1..6f7a74bb --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueData.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueData.java @@ -18,9 +18,9 @@ package org.onosproject.bgpio.types.attr; import java.util.Arrays; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP prefix opaque data attribute. */ -public final class BgpPrefixAttrOpaqueData implements BGPValueType { +public final class BgpPrefixAttrOpaqueData implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpPrefixAttrOpaqueData.class); @@ -65,18 +65,18 @@ public final class BgpPrefixAttrOpaqueData implements BGPValueType { * * @param cb ChannelBuffer * @return object of BgpPrefixAttrOpaqueData - * @throws BGPParseException while parsing BgpPrefixAttrOpaqueData + * @throws BgpParseException while parsing BgpPrefixAttrOpaqueData */ public static BgpPrefixAttrOpaqueData read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { byte[] opaquePrefixAttribute; short lsAttrLength = cb.readShort(); opaquePrefixAttribute = new byte[lsAttrLength]; if (cb.readableBytes() < lsAttrLength) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -131,4 +131,9 @@ public final class BgpPrefixAttrOpaqueData implements BGPValueType { .toString(); } + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOspfFwdAddr.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOspfFwdAddr.java old mode 100755 new mode 100644 index cf043046..4e9db1ee --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOspfFwdAddr.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOspfFwdAddr.java @@ -20,9 +20,9 @@ import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; import org.onlab.packet.Ip4Address; import org.onlab.packet.Ip6Address; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +32,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP prefix OSPF Forwarding address attribute. */ -public class BgpPrefixAttrOspfFwdAddr implements BGPValueType { +public class BgpPrefixAttrOspfFwdAddr implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpPrefixAttrOspfFwdAddr.class); @@ -80,10 +80,10 @@ public class BgpPrefixAttrOspfFwdAddr implements BGPValueType { * * @param cb ChannelBuffer * @return object of BgpPrefixAttrOSPFFwdAddr - * @throws BGPParseException while parsing BgpPrefixAttrOspfFwdAddr + * @throws BgpParseException while parsing BgpPrefixAttrOspfFwdAddr */ public static BgpPrefixAttrOspfFwdAddr read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { short lsAttrLength; byte[] ipBytes; Ip4Address ip4RouterId = null; @@ -93,8 +93,8 @@ public class BgpPrefixAttrOspfFwdAddr implements BGPValueType { ipBytes = new byte[lsAttrLength]; if ((cb.readableBytes() < lsAttrLength)) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -184,4 +184,10 @@ public class BgpPrefixAttrOspfFwdAddr implements BGPValueType { .add("ip6RouterId", ip6RouterId).toString(); } } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTag.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTag.java old mode 100755 new mode 100644 index 426eb274..3894c003 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTag.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTag.java @@ -20,9 +20,9 @@ import java.util.List; import java.util.Objects; import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.util.Validation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +32,7 @@ import com.google.common.base.MoreObjects; /** * Implements BGP prefix route tag attribute. */ -public class BgpPrefixAttrRouteTag implements BGPValueType { +public class BgpPrefixAttrRouteTag implements BgpValueType { protected static final Logger log = LoggerFactory .getLogger(BgpPrefixAttrRouteTag.class); @@ -66,10 +66,10 @@ public class BgpPrefixAttrRouteTag implements BGPValueType { * * @param cb ChannelBuffer * @return object of BgpPrefixAttrRouteTag - * @throws BGPParseException while parsing BgpPrefixAttrRouteTag + * @throws BgpParseException while parsing BgpPrefixAttrRouteTag */ public static BgpPrefixAttrRouteTag read(ChannelBuffer cb) - throws BGPParseException { + throws BgpParseException { int tmp; ArrayList pfxRouteTag = new ArrayList(); @@ -77,8 +77,8 @@ public class BgpPrefixAttrRouteTag implements BGPValueType { int len = lsAttrLength / Integer.SIZE; if (cb.readableBytes() < lsAttrLength) { - Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR, - BGPErrorType.ATTRIBUTE_LENGTH_ERROR, + Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, + BgpErrorType.ATTRIBUTE_LENGTH_ERROR, lsAttrLength); } @@ -133,4 +133,10 @@ public class BgpPrefixAttrRouteTag implements BGPValueType { return MoreObjects.toStringHelper(getClass()).omitNullValues() .add("pfxRouteTag", pfxRouteTag).toString(); } + + @Override + public int compareTo(Object o) { + // TODO Auto-generated method stub + return 0; + } } diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java index bc131893..23dd1a75 100644 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java @@ -24,7 +24,7 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.onlab.packet.IpAddress; import org.onlab.packet.IpPrefix; -import org.onosproject.bgpio.exceptions.BGPParseException; +import org.onosproject.bgpio.exceptions.BgpParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -109,13 +109,13 @@ public class Validation { * @param errorCode Error code * @param subErrCode Sub Error Code * @param length erroneous length - * @throws BGPParseException for erroneous length + * @throws BgpParseException for erroneous length */ - public static void validateLen(byte errorCode, byte subErrCode, int length) throws BGPParseException { + public static void validateLen(byte errorCode, byte subErrCode, int length) throws BgpParseException { byte[] errLen = Ints.toByteArray(length); ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(errLen); - throw new BGPParseException(errorCode, subErrCode, buffer); + throw new BgpParseException(errorCode, subErrCode, buffer); } /** @@ -124,13 +124,13 @@ public class Validation { * @param errorCode Error code * @param subErrCode Sub Error Code * @param type erroneous type - * @throws BGPParseException for erroneous type + * @throws BgpParseException for erroneous type */ - public static void validateType(byte errorCode, byte subErrCode, int type) throws BGPParseException { + public static void validateType(byte errorCode, byte subErrCode, int type) throws BgpParseException { byte[] errType = Ints.toByteArray(type); ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(errType); - throw new BGPParseException(errorCode, subErrCode, buffer); + throw new BgpParseException(errorCode, subErrCode, buffer); } /** diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsgTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpKeepaliveMsgTest.java similarity index 83% rename from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsgTest.java rename to framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpKeepaliveMsgTest.java index 68ce3070..682c1bc0 100755 --- a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsgTest.java +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpKeepaliveMsgTest.java @@ -18,8 +18,8 @@ package org.onosproject.bgpio.protocol; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.junit.Test; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpHeader; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; @@ -28,13 +28,13 @@ import static org.hamcrest.core.Is.is; /** * Test case for BGP KEEPALIVE Message. */ -public class BGPKeepaliveMsgTest { +public class BgpKeepaliveMsgTest { /** * This test case checks BGP Keepalive message. */ @Test - public void keepaliveMessageTest1() throws BGPParseException { + public void keepaliveMessageTest1() throws BgpParseException { // BGP KEEPALIVE Message byte[] keepaliveMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -47,13 +47,13 @@ public class BGPKeepaliveMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(keepaliveMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPKeepaliveMsg.class)); + assertThat(message, instanceOf(BgpKeepaliveMsg.class)); ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); message.writeTo(buf); diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpNotificationMsgTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpNotificationMsgTest.java index 78edf133..6dfa57ee 100644 --- a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpNotificationMsgTest.java +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpNotificationMsgTest.java @@ -18,8 +18,8 @@ package org.onosproject.bgpio.protocol; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.junit.Test; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpHeader; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; @@ -33,10 +33,10 @@ public class BgpNotificationMsgTest { /** * Notification message with error code, error subcode and data. * - * @throws BGPParseException while decoding and encoding notification message + * @throws BgpParseException while decoding and encoding notification message */ @Test - public void bgpNotificationMessageTest1() throws BGPParseException { + public void bgpNotificationMessageTest1() throws BgpParseException { byte[] notificationMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -52,12 +52,12 @@ public class BgpNotificationMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(notificationMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message = null; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message = null; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPNotificationMsg.class)); + assertThat(message, instanceOf(BgpNotificationMsg.class)); ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); message.writeTo(buf); @@ -72,10 +72,10 @@ public class BgpNotificationMsgTest { /** * Notification message without data. * - * @throws BGPParseException while decoding and encoding notification message + * @throws BgpParseException while decoding and encoding notification message */ @Test - public void bgpNotificationMessageTest2() throws BGPParseException { + public void bgpNotificationMessageTest2() throws BgpParseException { byte[] notificationMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -90,12 +90,12 @@ public class BgpNotificationMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(notificationMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message = null; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message = null; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPNotificationMsg.class)); + assertThat(message, instanceOf(BgpNotificationMsg.class)); ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); message.writeTo(buf); @@ -111,10 +111,10 @@ public class BgpNotificationMsgTest { /** * Notification message with wrong maker value. * - * @throws BGPParseException while decoding and encoding notification message + * @throws BgpParseException while decoding and encoding notification message */ - @Test(expected = BGPParseException.class) - public void bgpNotificationMessageTest3() throws BGPParseException { + @Test(expected = BgpParseException.class) + public void bgpNotificationMessageTest3() throws BgpParseException { byte[] notificationMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -129,12 +129,12 @@ public class BgpNotificationMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(notificationMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message = null; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message = null; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPNotificationMsg.class)); + assertThat(message, instanceOf(BgpNotificationMsg.class)); ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); message.writeTo(buf); @@ -149,10 +149,10 @@ public class BgpNotificationMsgTest { /** * Notification message without error subcode. * - * @throws BGPParseException while decoding and encoding notification message + * @throws BgpParseException while decoding and encoding notification message */ - @Test(expected = BGPParseException.class) - public void bgpNotificationMessageTest4() throws BGPParseException { + @Test(expected = BgpParseException.class) + public void bgpNotificationMessageTest4() throws BgpParseException { byte[] notificationMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -167,12 +167,12 @@ public class BgpNotificationMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(notificationMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message = null; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message = null; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPNotificationMsg.class)); + assertThat(message, instanceOf(BgpNotificationMsg.class)); ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); message.writeTo(buf); @@ -187,10 +187,10 @@ public class BgpNotificationMsgTest { /** * Notification message with wrong message length. * - * @throws BGPParseException while decoding and encoding notification message + * @throws BgpParseException while decoding and encoding notification message */ - @Test(expected = BGPParseException.class) - public void bgpNotificationMessageTest5() throws BGPParseException { + @Test(expected = BgpParseException.class) + public void bgpNotificationMessageTest5() throws BgpParseException { byte[] notificationMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -205,12 +205,12 @@ public class BgpNotificationMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(notificationMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message = null; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message = null; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPNotificationMsg.class)); + assertThat(message, instanceOf(BgpNotificationMsg.class)); ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); message.writeTo(buf); diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BGPOpenMsgTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpOpenMsgTest.java similarity index 81% rename from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BGPOpenMsgTest.java rename to framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpOpenMsgTest.java index d5210177..1fe4036f 100755 --- a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BGPOpenMsgTest.java +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpOpenMsgTest.java @@ -18,8 +18,8 @@ package org.onosproject.bgpio.protocol; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.junit.Test; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.types.BgpHeader; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; @@ -28,13 +28,13 @@ import static org.hamcrest.core.Is.is; /** * Test cases for BGP Open Message. */ -public class BGPOpenMsgTest { +public class BgpOpenMsgTest { /** * This test case checks open message without optional parameter. */ @Test - public void openMessageTest1() throws BGPParseException { + public void openMessageTest1() throws BgpParseException { //Open message without optional parameter byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -48,12 +48,12 @@ public class BGPOpenMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(openMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPOpenMsg.class)); + assertThat(message, instanceOf(BgpOpenMsg.class)); ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); message.writeTo(buf); @@ -69,7 +69,7 @@ public class BGPOpenMsgTest { * capability. */ @Test - public void openMessageTest2() throws BGPParseException { + public void openMessageTest2() throws BgpParseException { // OPEN Message (MultiProtocolExtension-CAPABILITY). byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -91,13 +91,13 @@ public class BGPOpenMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(openMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPOpenMsg.class)); + assertThat(message, instanceOf(BgpOpenMsg.class)); ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); message.writeTo(buf); @@ -113,7 +113,7 @@ public class BGPOpenMsgTest { * capability. */ @Test - public void openMessageTest3() throws BGPParseException { + public void openMessageTest3() throws BgpParseException { // OPEN Message (Four-Octet AS number capability). byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -135,13 +135,13 @@ public class BGPOpenMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(openMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPOpenMsg.class)); + assertThat(message, instanceOf(BgpOpenMsg.class)); ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); message.writeTo(buf); @@ -156,7 +156,7 @@ public class BGPOpenMsgTest { * This test case checks open message with capabilities. */ @Test - public void openMessageTest4() throws BGPParseException { + public void openMessageTest4() throws BgpParseException { // OPEN Message with capabilities. byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -178,13 +178,13 @@ public class BGPOpenMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(openMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPOpenMsg.class)); + assertThat(message, instanceOf(BgpOpenMsg.class)); ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); message.writeTo(buf); @@ -200,8 +200,8 @@ public class BGPOpenMsgTest { * In this test case, Invalid version is given as input and expecting * an exception. */ - @Test(expected = BGPParseException.class) - public void openMessageTest5() throws BGPParseException { + @Test(expected = BgpParseException.class) + public void openMessageTest5() throws BgpParseException { // OPEN Message with invalid version number. byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -217,20 +217,20 @@ public class BGPOpenMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(openMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPOpenMsg.class)); + assertThat(message, instanceOf(BgpOpenMsg.class)); } /** * In this test case, Marker is set as 0 in input and expecting * an exception. */ - @Test(expected = BGPParseException.class) - public void openMessageTest6() throws BGPParseException { + @Test(expected = BgpParseException.class) + public void openMessageTest6() throws BgpParseException { // OPEN Message with marker set to 0. byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -246,20 +246,20 @@ public class BGPOpenMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(openMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPOpenMsg.class)); + assertThat(message, instanceOf(BgpOpenMsg.class)); } /** * In this test case, Invalid message length is given as input and expecting * an exception. */ - @Test(expected = BGPParseException.class) - public void openMessageTest7() throws BGPParseException { + @Test(expected = BgpParseException.class) + public void openMessageTest7() throws BgpParseException { // OPEN Message with invalid header length. byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -275,20 +275,20 @@ public class BGPOpenMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(openMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPOpenMsg.class)); + assertThat(message, instanceOf(BgpOpenMsg.class)); } /** * In this test case, Invalid message type is given as input and expecting * an exception. */ - @Test(expected = BGPParseException.class) - public void openMessageTest8() throws BGPParseException { + @Test(expected = BgpParseException.class) + public void openMessageTest8() throws BgpParseException { // OPEN Message with invalid message type. byte[] openMsg = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, @@ -304,11 +304,11 @@ public class BGPOpenMsgTest { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); buffer.writeBytes(openMsg); - BGPMessageReader reader = BGPFactories.getGenericReader(); - BGPMessage message; - BGPHeader bgpHeader = new BGPHeader(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + BgpMessage message; + BgpHeader bgpHeader = new BgpHeader(); message = reader.readFrom(buffer, bgpHeader); - assertThat(message, instanceOf(BGPOpenMsg.class)); + assertThat(message, instanceOf(BgpOpenMsg.class)); } } diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/AreaIdTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/AreaIdTest.java index 6a9e2ec5..e11564ab 100644 --- a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/AreaIdTest.java +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/AreaIdTest.java @@ -36,42 +36,4 @@ public class AreaIdTest { .addEqualityGroup(tlv2) .testEquals(); } - - /** - * Test for OSPFNonPseudonode Tlv. - */ - public static class OspfNonPseudonodeTest { - private final int value1 = 0x12121212; - private final int value2 = 0x12121211; - private final OSPFNonPseudonode tlv1 = OSPFNonPseudonode.of(value1); - private final OSPFNonPseudonode sameAsTlv1 = OSPFNonPseudonode.of(value1); - private final OSPFNonPseudonode tlv2 = OSPFNonPseudonode.of(value2); - - @Test - public void basics() { - new EqualsTester() - .addEqualityGroup(tlv1, sameAsTlv1) - .addEqualityGroup(tlv2) - .testEquals(); - } - } - - /** - * Test for IsIsNonPseudonode Tlv. - */ - public static class IsIsNonPseudonodeTest { - private final byte[] value1 = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; - private final byte[] value2 = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x59}; - private final IsIsNonPseudonode tlv1 = IsIsNonPseudonode.of(value1); - private final IsIsNonPseudonode sameAsTlv1 = IsIsNonPseudonode.of(value1); - private final IsIsNonPseudonode tlv2 = IsIsNonPseudonode.of(value2); - - @Test - public void basics() { - new EqualsTester() - .addEqualityGroup(tlv1, sameAsTlv1) - .addEqualityGroup(tlv2) - .testEquals(); - } - } } diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/BGPLSIdentifierTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/BgpLSIdentifierTest.java similarity index 82% rename from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/BGPLSIdentifierTest.java rename to framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/BgpLSIdentifierTest.java index f3355d35..59cf96fa 100644 --- a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/BGPLSIdentifierTest.java +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/BgpLSIdentifierTest.java @@ -22,12 +22,12 @@ import com.google.common.testing.EqualsTester; /** * Test for BGPLSIdentifier Tlv. */ -public class BGPLSIdentifierTest { +public class BgpLSIdentifierTest { private final int value1 = 8738; private final int value2 = 13107; - private final BGPLSIdentifierTlv tlv1 = BGPLSIdentifierTlv.of(value1); - private final BGPLSIdentifierTlv sameAsTlv1 = new BGPLSIdentifierTlv(value1); - private final BGPLSIdentifierTlv tlv2 = new BGPLSIdentifierTlv(value2); + private final BgpLSIdentifierTlv tlv1 = BgpLSIdentifierTlv.of(value1); + private final BgpLSIdentifierTlv sameAsTlv1 = new BgpLSIdentifierTlv(value1); + private final BgpLSIdentifierTlv tlv2 = new BgpLSIdentifierTlv(value2); @Test public void basics() { diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IsIsNonPseudonodeTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IsIsNonPseudonodeTest.java new file mode 100644 index 00000000..7ce4d5d3 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IsIsNonPseudonodeTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +/** + * Test for IsIsNonPseudonode Tlv. + */ +public class IsIsNonPseudonodeTest { + private final byte[] value1 = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58}; + private final byte[] value2 = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x59}; + private final IsIsNonPseudonode tlv1 = IsIsNonPseudonode.of(value1); + private final IsIsNonPseudonode sameAsTlv1 = IsIsNonPseudonode.of(value1); + private final IsIsNonPseudonode tlv2 = IsIsNonPseudonode.of(value2); + + @Test + public void testEquality() { + new EqualsTester() + .addEqualityGroup(tlv1, sameAsTlv1) + .addEqualityGroup(tlv2) + .testEquals(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IsIsPseudonodeTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IsIsPseudonodeTest.java index 00e85dcf..a2a7c2b5 100644 --- a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IsIsPseudonodeTest.java +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IsIsPseudonodeTest.java @@ -15,11 +15,6 @@ */ package org.onosproject.bgpio.types; -import java.util.ArrayList; -import java.util.List; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; import org.junit.Test; import com.google.common.testing.EqualsTester; @@ -29,28 +24,13 @@ import com.google.common.testing.EqualsTester; */ public class IsIsPseudonodeTest { private final byte[] value1 = new byte[] {0x01, 0x02, 0x01, 0x02, 0x01, 0x02}; - byte value; - List isoNodeID1 = new ArrayList(); - ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); private final byte[] value2 = new byte[] {0x01, 0x02, 0x01, 0x02, 0x01, 0x03}; - List isoNodeID2 = new ArrayList(); - ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer(); - private final IsIsPseudonode tlv1 = IsIsPseudonode.of(isoNodeID1, (byte) 1); - private final IsIsPseudonode sameAsTlv1 = IsIsPseudonode.of(isoNodeID1, (byte) 1); - private final IsIsPseudonode tlv2 = IsIsPseudonode.of(isoNodeID2, (byte) 1); + private final IsIsPseudonode tlv1 = IsIsPseudonode.of(value1, (byte) 1); + private final IsIsPseudonode sameAsTlv1 = IsIsPseudonode.of(value1, (byte) 1); + private final IsIsPseudonode tlv2 = IsIsPseudonode.of(value2, (byte) 1); @Test public void testEquality() { - buffer.writeBytes(value1); - for (int i = 0; i < 6; i++) { - value = buffer.readByte(); - isoNodeID1.add(value); - } - buffer1.writeBytes(value2); - for (int i = 0; i < 6; i++) { - value = buffer1.readByte(); - isoNodeID1.add(value); - } new EqualsTester() .addEqualityGroup(tlv1, sameAsTlv1) .addEqualityGroup(tlv2) diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/LocalPrefTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/LocalPrefTest.java index 02a06e05..1bd34385 100644 --- a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/LocalPrefTest.java +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/LocalPrefTest.java @@ -13,10 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.bgpio; +package org.onosproject.bgpio.types; import org.junit.Test; -import org.onosproject.bgpio.types.LocalPref; import com.google.common.testing.EqualsTester; @@ -32,9 +31,6 @@ public class LocalPrefTest { @Test public void testEquality() { - new EqualsTester() - .addEqualityGroup(attr1, sameAsAttr1) - .addEqualityGroup(attr2) - .testEquals(); + new EqualsTester().addEqualityGroup(attr1, sameAsAttr1).addEqualityGroup(attr2).testEquals(); } } diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/MedTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/MedTest.java index eafcec74..2ee5b33f 100644 --- a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/MedTest.java +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/MedTest.java @@ -13,10 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.bgpio; +package org.onosproject.bgpio.types; import org.junit.Test; -import org.onosproject.bgpio.types.Med; import com.google.common.testing.EqualsTester; @@ -32,9 +31,6 @@ public class MedTest { @Test public void testEquality() { - new EqualsTester() - .addEqualityGroup(attr1, sameAsAttr1) - .addEqualityGroup(attr2) - .testEquals(); + new EqualsTester().addEqualityGroup(attr1, sameAsAttr1).addEqualityGroup(attr2).testEquals(); } } diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidthTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidthTest.java new file mode 100644 index 00000000..06fecc92 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidthTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +/** + * Test for BGP link max bandwidth attribute. + */ +public class BgpLinkAttrMaxLinkBandwidthTest { + private final float val = 0x010203; + private final short valLen = 3; + private final float val1 = 0x01020304; + private final short val1Len = 4; + + private final BgpLinkAttrMaxLinkBandwidth data = BgpLinkAttrMaxLinkBandwidth + .of(val, valLen); + private final BgpLinkAttrMaxLinkBandwidth sameAsData = BgpLinkAttrMaxLinkBandwidth + .of(val, valLen); + private final BgpLinkAttrMaxLinkBandwidth diffData = BgpLinkAttrMaxLinkBandwidth + .of(val1, val1Len); + + @Test + public void basics() { + new EqualsTester().addEqualityGroup(data, sameAsData) + .addEqualityGroup(diffData).testEquals(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrNameTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrNameTest.java new file mode 100644 index 00000000..45048527 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrNameTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +/** + * Test for Link attribute name Tlv. + */ +public class BgpLinkAttrNameTest { + private final byte[] array = new byte[] {0x01, 0x02, 0x03, 0x04}; + private final byte[] array1 = new byte[] {0x01, 0x02, 0x03, 0x01}; + + private final BgpLinkAttrName isisData = BgpLinkAttrName.of(array); + private final BgpLinkAttrName sameAsIsisData = BgpLinkAttrName.of(array); + private final BgpLinkAttrName isisDiff = BgpLinkAttrName.of(array1); + + @Test + public void basics() { + new EqualsTester().addEqualityGroup(isisData, sameAsIsisData) + .addEqualityGroup(isisDiff).testEquals(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrOpaqLnkAttribTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrOpaqLnkAttribTest.java new file mode 100644 index 00000000..71d05f85 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrOpaqLnkAttribTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +/** + * Test for Opaque Link attribute Tlv. + */ +public class BgpLinkAttrOpaqLnkAttribTest { + private final byte[] array = new byte[] {0x01, 0x02, 0x03, 0x04}; + private final byte[] array1 = new byte[] {0x01, 0x02, 0x03, 0x01}; + + private final BgpLinkAttrOpaqLnkAttrib isisData = BgpLinkAttrOpaqLnkAttrib + .of(array); + private final BgpLinkAttrOpaqLnkAttrib sameAsIsisData = BgpLinkAttrOpaqLnkAttrib + .of(array); + private final BgpLinkAttrOpaqLnkAttrib isisDiff = BgpLinkAttrOpaqLnkAttrib + .of(array1); + + @Test + public void basics() { + new EqualsTester().addEqualityGroup(isisData, sameAsIsisData) + .addEqualityGroup(isisDiff).testEquals(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetricTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetricTest.java new file mode 100644 index 00000000..9f3a7fad --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetricTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import org.junit.Test; +import com.google.common.testing.EqualsTester; + +/** + * Test for BGP link TE default metric attribute. + */ +public class BgpLinkAttrTeDefaultMetricTest { + private final int val = 0x010203; + private final int val1 = 0x01020304; + + private final BgpLinkAttrTeDefaultMetric data = BgpLinkAttrTeDefaultMetric + .of(val); + private final BgpLinkAttrTeDefaultMetric sameAsData = BgpLinkAttrTeDefaultMetric + .of(val); + private final BgpLinkAttrTeDefaultMetric diffData = BgpLinkAttrTeDefaultMetric + .of(val1); + + @Test + public void basics() { + new EqualsTester().addEqualityGroup(data, sameAsData) + .addEqualityGroup(diffData).testEquals(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrUnRsrvdLinkBandwidthTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrUnRsrvdLinkBandwidthTest.java new file mode 100644 index 00000000..f1d2a1fa --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrUnRsrvdLinkBandwidthTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import java.util.ArrayList; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +/** + * Test for BGP unreserved bandwidth attribute. + */ +public class BgpLinkAttrUnRsrvdLinkBandwidthTest { + ArrayList maxUnResBandwidth = new ArrayList(); + ArrayList maxUnResBandwidth1 = new ArrayList(); + short sType = 10; + + private final BgpLinkAttrUnRsrvdLinkBandwidth isisData = BgpLinkAttrUnRsrvdLinkBandwidth + .of(maxUnResBandwidth, sType); + private final BgpLinkAttrUnRsrvdLinkBandwidth sameAsIsisData = BgpLinkAttrUnRsrvdLinkBandwidth + .of(maxUnResBandwidth, sType); + private final BgpLinkAttrUnRsrvdLinkBandwidth isisDiff = BgpLinkAttrUnRsrvdLinkBandwidth + .of(maxUnResBandwidth1, sType); + + @Test + public void basics() { + + maxUnResBandwidth.add(new Float(1)); + maxUnResBandwidth.add(new Float(2)); + maxUnResBandwidth.add(new Float(3)); + maxUnResBandwidth.add(new Float(4)); + + maxUnResBandwidth1.add(new Float(1)); + maxUnResBandwidth1.add(new Float(2)); + maxUnResBandwidth1.add(new Float(3)); + maxUnResBandwidth1.add(new Float(1)); + + new EqualsTester().addEqualityGroup(isisData, sameAsIsisData) + .addEqualityGroup(isisDiff).testEquals(); + + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueDataTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueDataTest.java new file mode 100644 index 00000000..17dafbb7 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueDataTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +/** + * Test for prefix attribute opaque data Tlv. + */ +public class BgpPrefixAttrOpaqueDataTest { + private final byte[] array = new byte[] {0x01, 0x02, 0x03, 0x04}; + private final byte[] array1 = new byte[] {0x01, 0x02, 0x03, 0x01}; + + private final BgpPrefixAttrOpaqueData isisData = BgpPrefixAttrOpaqueData + .of(array); + private final BgpPrefixAttrOpaqueData sameAsIsisData = BgpPrefixAttrOpaqueData + .of(array); + private final BgpPrefixAttrOpaqueData isisDiff = BgpPrefixAttrOpaqueData + .of(array1); + + @Test + public void basics() { + new EqualsTester().addEqualityGroup(isisData, sameAsIsisData) + .addEqualityGroup(isisDiff).testEquals(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTagTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTagTest.java new file mode 100644 index 00000000..25ced61f --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrRouteTagTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgpio.types.attr; + +import java.util.ArrayList; + +import org.junit.Test; + +import com.google.common.testing.EqualsTester; + +/** + * Test for BGP prefix route tag attribute. + */ +public class BgpPrefixAttrRouteTagTest { + ArrayList maxUnResBandwidth = new ArrayList(); + ArrayList maxUnResBandwidth1 = new ArrayList(); + + private final BgpPrefixAttrRouteTag isisData = BgpPrefixAttrRouteTag + .of(maxUnResBandwidth); + private final BgpPrefixAttrRouteTag sameAsIsisData = BgpPrefixAttrRouteTag + .of(maxUnResBandwidth); + private final BgpPrefixAttrRouteTag isisDiff = BgpPrefixAttrRouteTag + .of(maxUnResBandwidth1); + + @Test + public void basics() { + + maxUnResBandwidth.add(new Integer(1)); + maxUnResBandwidth.add(new Integer(2)); + maxUnResBandwidth.add(new Integer(3)); + maxUnResBandwidth.add(new Integer(4)); + + maxUnResBandwidth1.add(new Integer(1)); + maxUnResBandwidth1.add(new Integer(2)); + maxUnResBandwidth1.add(new Integer(3)); + maxUnResBandwidth1.add(new Integer(1)); + + new EqualsTester().addEqualityGroup(isisData, sameAsIsisData) + .addEqualityGroup(isisDiff).testEquals(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/AdjRibIn.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/AdjRibIn.java new file mode 100644 index 00000000..9cbfbf65 --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/AdjRibIn.java @@ -0,0 +1,132 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.bgp.controller.impl; + +import java.util.Map; +import java.util.TreeMap; + +import org.onosproject.bgpio.protocol.BgpLSNlri; +import org.onosproject.bgpio.protocol.linkstate.BgpLinkLSIdentifier; +import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSIdentifier; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpPrefixLSIdentifier; +import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of Adj-RIB-In for each peer. + */ +public class AdjRibIn { + private Map nodeTree = new TreeMap<>(); + private Map linkTree = new TreeMap<>(); + private Map prefixTree = new TreeMap<>(); + + /** + * Returns the adjacency node. + * + * @return node adjacency RIB node + */ + public Map nodeTree() { + return nodeTree; + } + + /** + * Returns the adjacency link. + * + * @return link adjacency RIB node + */ + public Map linkTree() { + return linkTree; + } + + /** + * Returns the adjacency prefix. + * + * @return prefix adjacency RIB node + */ + public Map prefixTree() { + return prefixTree; + } + + /** + * Update nlri identifier into the tree if nlri identifier exists in tree otherwise add this to the tree. + * + * @param nlri NLRI Info + * @param details has pathattribute , protocolID and identifier + */ + public void add(BgpLSNlri nlri, PathAttrNlriDetails details) { + if (nlri instanceof BgpNodeLSNlriVer4) { + BgpNodeLSIdentifier nodeLSIdentifier = ((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors(); + if (nodeTree.containsKey(nodeLSIdentifier)) { + nodeTree.replace(nodeLSIdentifier, details); + } else { + nodeTree.put(nodeLSIdentifier, details); + } + } else if (nlri instanceof BgpLinkLsNlriVer4) { + BgpLinkLSIdentifier linkLSIdentifier = ((BgpLinkLsNlriVer4) nlri).getLinkIdentifier(); + if (linkTree.containsKey(linkLSIdentifier)) { + linkTree.replace(linkLSIdentifier, details); + } else { + linkTree.put(linkLSIdentifier, details); + } + } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) { + BgpPrefixLSIdentifier prefixIdentifier = ((BgpPrefixIPv4LSNlriVer4) nlri).getPrefixIdentifier(); + if (prefixTree.containsKey(prefixIdentifier)) { + prefixTree.replace(prefixIdentifier, details); + } else { + prefixTree.put(prefixIdentifier, details); + } + } + } + + /** + * Removes nlri identifier if it exists in the adjacency tree. + * + * @param nlri NLRI Info + */ + public void remove(BgpLSNlri nlri) { + if (nlri instanceof BgpNodeLSNlriVer4) { + BgpNodeLSIdentifier nodeLSIdentifier = ((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors(); + if (nodeTree.containsKey(nodeLSIdentifier)) { + nodeTree.remove(nodeLSIdentifier); + } + } else if (nlri instanceof BgpLinkLsNlriVer4) { + BgpLinkLSIdentifier linkLSIdentifier = ((BgpLinkLsNlriVer4) nlri).getLinkIdentifier(); + if (linkTree.containsKey(linkLSIdentifier)) { + linkTree.remove(linkLSIdentifier); + } + } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) { + BgpPrefixLSIdentifier prefixIdentifier = ((BgpPrefixIPv4LSNlriVer4) nlri).getPrefixIdentifier(); + if (prefixTree.containsKey(prefixIdentifier)) { + prefixTree.remove(prefixIdentifier); + } + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues() + .add("nodeTree", nodeTree) + .add("linkTree", linkTree) + .add("prefixTree", prefixTree) + .toString(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java deleted file mode 100755 index 45f74634..00000000 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bgp.controller.impl; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.RejectedExecutionException; - -import org.jboss.netty.channel.Channel; -import org.onlab.packet.IpAddress; -import org.onosproject.bgp.controller.BGPController; -import org.onosproject.bgp.controller.BGPPeer; -import org.onosproject.bgp.controller.BgpSessionInfo; -import org.onosproject.bgpio.protocol.BGPFactories; -import org.onosproject.bgpio.protocol.BGPFactory; -import org.onosproject.bgpio.protocol.BGPMessage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.MoreObjects; - -/** - * BGPPeerImpl implements BGPPeer, maintains peer information and store updates in RIB . - */ -public class BGPPeerImpl implements BGPPeer { - - protected final Logger log = LoggerFactory.getLogger(BGPPeerImpl.class); - - private static final String SHUTDOWN_MSG = "Worker has already been shutdown"; - - private BGPController bgpController; - private Channel channel; - protected String channelId; - private boolean connected; - protected boolean isHandShakeComplete = false; - private BgpSessionInfo sessionInfo; - private BGPPacketStatsImpl pktStats; - - - @Override - public BgpSessionInfo sessionInfo() { - return sessionInfo; - } - - /** - * Initialize peer. - * - *@param bgpController controller instance - *@param sessionInfo bgp session info - *@param pktStats packet statistics - */ - public BGPPeerImpl(BGPController bgpController, BgpSessionInfo sessionInfo, BGPPacketStatsImpl pktStats) { - this.bgpController = bgpController; - this.sessionInfo = sessionInfo; - this.pktStats = pktStats; - } - - // ************************ - // Channel related - // ************************ - - @Override - public final void disconnectPeer() { - this.channel.close(); - } - - @Override - public final void sendMessage(BGPMessage m) { - log.debug("Sending message to {}", channel.getRemoteAddress()); - try { - channel.write(Collections.singletonList(m)); - this.pktStats.addOutPacket(); - } catch (RejectedExecutionException e) { - log.warn(e.getMessage()); - if (!e.getMessage().contains(SHUTDOWN_MSG)) { - throw e; - } - } - } - - @Override - public final void sendMessage(List msgs) { - try { - channel.write(msgs); - this.pktStats.addOutPacket(msgs.size()); - } catch (RejectedExecutionException e) { - log.warn(e.getMessage()); - if (!e.getMessage().contains(SHUTDOWN_MSG)) { - throw e; - } - } - } - - @Override - public final boolean isConnected() { - return this.connected; - } - - @Override - public final void setConnected(boolean connected) { - this.connected = connected; - }; - - @Override - public final void setChannel(Channel channel) { - this.channel = channel; - final SocketAddress address = channel.getRemoteAddress(); - if (address instanceof InetSocketAddress) { - final InetSocketAddress inetAddress = (InetSocketAddress) address; - final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress()); - if (ipAddress.isIp4()) { - channelId = ipAddress.toString() + ':' + inetAddress.getPort(); - } else { - channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort(); - } - } - }; - - @Override - public final Channel getChannel() { - return this.channel; - }; - - @Override - public String channelId() { - return channelId; - } - - @Override - public BGPFactory factory() { - return BGPFactories.getFactory(sessionInfo.remoteBgpVersion()); - } - - @Override - public boolean isHandshakeComplete() { - return isHandShakeComplete; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()).omitNullValues() - .add("channel", channelId()) - .add("bgpId", sessionInfo().remoteBgpId()).toString(); - } -} diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java similarity index 71% rename from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java rename to framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java index f21c311c..8754563d 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java @@ -23,8 +23,8 @@ import java.net.SocketAddress; import java.net.UnknownHostException; import java.nio.channels.ClosedChannelException; import java.util.Collections; -import java.util.List; import java.util.LinkedList; +import java.util.List; import java.util.ListIterator; import java.util.concurrent.RejectedExecutionException; @@ -40,20 +40,20 @@ import org.jboss.netty.handler.timeout.ReadTimeoutException; import org.jboss.netty.handler.timeout.ReadTimeoutHandler; import org.onlab.packet.Ip4Address; import org.onlab.packet.IpAddress; -import org.onosproject.bgp.controller.BGPCfg; -import org.onosproject.bgp.controller.BGPController; -import org.onosproject.bgp.controller.BGPId; -import org.onosproject.bgp.controller.BGPPeer; -import org.onosproject.bgp.controller.BGPPeerCfg; -import org.onosproject.bgp.controller.impl.BGPControllerImpl.BGPPeerManagerImpl; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPFactory; -import org.onosproject.bgpio.protocol.BGPMessage; -import org.onosproject.bgpio.protocol.BGPOpenMsg; -import org.onosproject.bgpio.protocol.BGPType; -import org.onosproject.bgpio.protocol.BGPVersion; -import org.onosproject.bgpio.types.BGPErrorType; -import org.onosproject.bgpio.types.BGPValueType; +import org.onosproject.bgp.controller.BgpCfg; +import org.onosproject.bgp.controller.BgpController; +import org.onosproject.bgp.controller.BgpId; +import org.onosproject.bgp.controller.BgpPeer; +import org.onosproject.bgp.controller.BgpPeerCfg; +import org.onosproject.bgp.controller.impl.BgpControllerImpl.BgpPeerManagerImpl; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpFactory; +import org.onosproject.bgpio.protocol.BgpMessage; +import org.onosproject.bgpio.protocol.BgpOpenMsg; +import org.onosproject.bgpio.protocol.BgpType; +import org.onosproject.bgpio.protocol.BgpVersion; +import org.onosproject.bgpio.types.BgpErrorType; +import org.onosproject.bgpio.types.BgpValueType; import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv; import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv; import org.slf4j.Logger; @@ -62,20 +62,20 @@ import org.slf4j.LoggerFactory; /** * Channel handler deals with the bgp peer connection and dispatches messages from peer to the appropriate locations. */ -class BGPChannelHandler extends IdleStateAwareChannelHandler { +class BgpChannelHandler extends IdleStateAwareChannelHandler { - private static final Logger log = LoggerFactory.getLogger(BGPChannelHandler.class); + private static final Logger log = LoggerFactory.getLogger(BgpChannelHandler.class); static final int BGP_MIN_HOLDTIME = 3; static final int BGP_MAX_KEEPALIVE_INTERVAL = 3; - private BGPPeer bgpPeer; - private BGPId thisbgpId; + private BgpPeer bgpPeer; + private BgpId thisbgpId; private Channel channel; - private BGPKeepAliveTimer keepAliveTimer = null; + private BgpKeepAliveTimer keepAliveTimer = null; private short peerHoldTime = 0; private short negotiatedHoldTime = 0; private long peerAsNum; private int peerIdentifier; - private BGPPacketStatsImpl bgpPacketStats; + private BgpPacketStatsImpl bgpPacketStats; static final int MAX_WRONG_COUNT_PACKET = 5; static final byte MULTI_PROTOCOL_EXTN_CAPA_TYPE = 1; static final byte FOUR_OCTET_AS_NUM_CAPA_TYPE = 65; @@ -97,30 +97,30 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { // peer state for the older (still connected) peer private volatile Boolean duplicateBGPIdFound; // Indicates the bgp version used by this bgp peer - protected BGPVersion bgpVersion; - private BGPController bgpController; - protected BGPFactory factory4; + protected BgpVersion bgpVersion; + private BgpController bgpController; + protected BgpFactory factory4; private boolean isIbgpSession; private BgpSessionInfoImpl sessionInfo; - private BGPPeerManagerImpl peerManager; + private BgpPeerManagerImpl peerManager; private InetSocketAddress inetAddress; private IpAddress ipAddress; private SocketAddress address; private String peerAddr; - private BGPCfg bgpconfig; + private BgpCfg bgpconfig; /** * Create a new unconnected BGPChannelHandler. * * @param bgpController bgp controller */ - BGPChannelHandler(BGPController bgpController) { + BgpChannelHandler(BgpController bgpController) { this.bgpController = bgpController; - this.peerManager = (BGPPeerManagerImpl) bgpController.peerManager(); + this.peerManager = (BgpPeerManagerImpl) bgpController.peerManager(); this.state = ChannelState.IDLE; - this.factory4 = Controller.getBGPMessageFactory4(); + this.factory4 = Controller.getBgpMessageFactory4(); this.duplicateBGPIdFound = Boolean.FALSE; - this.bgpPacketStats = new BGPPacketStatsImpl(); + this.bgpPacketStats = new BgpPacketStatsImpl(); this.bgpconfig = bgpController.getConfig(); } @@ -147,24 +147,29 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { OPENSENT(false) { @Override - void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException { + void processBgpMessage(BgpChannelHandler h, BgpMessage m) throws IOException, BgpParseException { log.debug("message received in OPENSENT state"); // check for OPEN message - if (m.getType() != BGPType.OPEN) { + if (m.getType() != BgpType.OPEN) { // When the message type is not keep alive message increment the wrong packet statistics - h.processUnknownMsg(BGPErrorType.FINITE_STATE_MACHINE_ERROR, - BGPErrorType.RECEIVE_UNEXPECTED_MESSAGE_IN_OPENSENT_STATE, m.getType() - .getType()); + h.processUnknownMsg(BgpErrorType.FINITE_STATE_MACHINE_ERROR, + BgpErrorType.RECEIVE_UNEXPECTED_MESSAGE_IN_OPENSENT_STATE, + m.getType().getType()); log.debug("Message is not OPEN message"); } else { log.debug("Sending keep alive message in OPENSENT state"); h.bgpPacketStats.addInPacket(); - BGPOpenMsg pOpenmsg = (BGPOpenMsg) m; + BgpOpenMsg pOpenmsg = (BgpOpenMsg) m; h.peerIdentifier = pOpenmsg.getBgpId(); // validate capabilities and open msg if (h.openMsgValidation(h, pOpenmsg)) { + if (h.connectionCollisionDetection(BgpPeerCfg.State.OPENCONFIRM, + h.peerIdentifier, h.peerAddr)) { + h.channel.close(); + return; + } log.debug("Sending handshake OPEN message"); /* @@ -176,7 +181,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { if (h.peerHoldTime < h.bgpconfig.getHoldTime()) { h.channel.getPipeline().replace("holdTime", "holdTime", - new ReadTimeoutHandler(BGPPipelineFactory.TIMER, + new ReadTimeoutHandler(BgpPipelineFactory.TIMER, h.peerHoldTime)); } @@ -190,30 +195,35 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { h.sendKeepAliveMessage(); h.bgpPacketStats.addOutPacket(); h.setState(OPENCONFIRM); - h.bgpconfig.setPeerConnState(h.peerAddr, BGPPeerCfg.State.OPENCONFIRM); + h.bgpconfig.setPeerConnState(h.peerAddr, BgpPeerCfg.State.OPENCONFIRM); } } }, OPENWAIT(false) { @Override - void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException { + void processBgpMessage(BgpChannelHandler h, BgpMessage m) throws IOException, BgpParseException { log.debug("Message received in OPEN WAIT State"); // check for open message - if (m.getType() != BGPType.OPEN) { + if (m.getType() != BgpType.OPEN) { // When the message type is not open message increment the wrong packet statistics - h.processUnknownMsg(BGPErrorType.FINITE_STATE_MACHINE_ERROR, BGPErrorType.UNSPECIFIED_ERROR, m - .getType().getType()); + h.processUnknownMsg(BgpErrorType.FINITE_STATE_MACHINE_ERROR, BgpErrorType.UNSPECIFIED_ERROR, + m.getType().getType()); log.debug("Message is not OPEN message"); } else { h.bgpPacketStats.addInPacket(); - BGPOpenMsg pOpenmsg = (BGPOpenMsg) m; + BgpOpenMsg pOpenmsg = (BgpOpenMsg) m; h.peerIdentifier = pOpenmsg.getBgpId(); // Validate open message if (h.openMsgValidation(h, pOpenmsg)) { + if (h.connectionCollisionDetection(BgpPeerCfg.State.OPENSENT, + h.peerIdentifier, h.peerAddr)) { + h.channel.close(); + return; + } log.debug("Sending handshake OPEN message"); /* @@ -225,7 +235,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { if (h.peerHoldTime < h.bgpconfig.getHoldTime()) { h.channel.getPipeline().replace("holdTime", "holdTime", - new ReadTimeoutHandler(BGPPipelineFactory.TIMER, + new ReadTimeoutHandler(BgpPipelineFactory.TIMER, h.peerHoldTime)); } @@ -237,6 +247,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { h.sendHandshakeOpenMessage(); h.bgpPacketStats.addOutPacket(); h.setState(OPENCONFIRM); + h.bgpconfig.setPeerConnState(h.peerAddr, BgpPeerCfg.State.OPENCONFIRM); } } } @@ -244,14 +255,14 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { OPENCONFIRM(false) { @Override - void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException { + void processBgpMessage(BgpChannelHandler h, BgpMessage m) throws IOException, BgpParseException { log.debug("Message received in OPENCONFIRM state"); // check for keep alive message - if (m.getType() != BGPType.KEEP_ALIVE) { + if (m.getType() != BgpType.KEEP_ALIVE) { // When the message type is not keep alive message handle the wrong packet - h.processUnknownMsg(BGPErrorType.FINITE_STATE_MACHINE_ERROR, - BGPErrorType.RECEIVE_UNEXPECTED_MESSAGE_IN_OPENCONFIRM_STATE, m.getType() - .getType()); + h.processUnknownMsg(BgpErrorType.FINITE_STATE_MACHINE_ERROR, + BgpErrorType.RECEIVE_UNEXPECTED_MESSAGE_IN_OPENCONFIRM_STATE, + m.getType().getType()); log.debug("Message is not KEEPALIVE message"); } else { @@ -260,7 +271,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { log.debug("Sending keep alive message in OPENCONFIRM state"); final InetSocketAddress inetAddress = (InetSocketAddress) h.address; - h.thisbgpId = BGPId.bgpId(IpAddress.valueOf(inetAddress.getAddress())); + h.thisbgpId = BgpId.bgpId(IpAddress.valueOf(inetAddress.getAddress())); // set session parameters h.negotiatedHoldTime = (h.peerHoldTime < h.bgpconfig.getHoldTime()) ? h.peerHoldTime @@ -268,7 +279,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { h.sessionInfo = new BgpSessionInfoImpl(h.thisbgpId, h.bgpVersion, h.peerAsNum, h.peerHoldTime, h.peerIdentifier, h.negotiatedHoldTime, h.isIbgpSession); - h.bgpPeer = h.peerManager.getBGPPeerInstance(h.bgpController, h.sessionInfo, h.bgpPacketStats); + h.bgpPeer = h.peerManager.getBgpPeerInstance(h.bgpController, h.sessionInfo, h.bgpPacketStats); // set the status of bgp as connected h.bgpPeer.setConnected(true); h.bgpPeer.setChannel(h.channel); @@ -280,8 +291,8 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { */ if (h.negotiatedHoldTime != 0) { - h.keepAliveTimer = new BGPKeepAliveTimer(h, - (h.negotiatedHoldTime / BGP_MAX_KEEPALIVE_INTERVAL)); + h.keepAliveTimer = new BgpKeepAliveTimer(h, + (h.negotiatedHoldTime / BGP_MAX_KEEPALIVE_INTERVAL)); } else { h.sendKeepAliveMessage(); } @@ -292,17 +303,10 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { h.setHandshakeComplete(true); if (!h.peerManager.addConnectedPeer(h.thisbgpId, h.bgpPeer)) { - /* - * RFC 4271, Section 6.8, Based on the value of the BGP identifier, a convention is established - * for detecting which BGP connection is to be preserved when a collision occurs. The convention - * is to compare the BGP Identifiers of the peers involved in the collision and to retain only - * the connection initiated by the BGP speaker with the higher-valued BGP Identifier.. - */ - // TODO: Connection collision handling. disconnectDuplicate(h); } else { h.setState(ESTABLISHED); - h.bgpconfig.setPeerConnState(h.peerAddr, BGPPeerCfg.State.ESTABLISHED); + h.bgpconfig.setPeerConnState(h.peerAddr, BgpPeerCfg.State.ESTABLISHED); } } } @@ -310,7 +314,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { ESTABLISHED(true) { @Override - void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException { + void processBgpMessage(BgpChannelHandler h, BgpMessage m) throws IOException, BgpParseException { log.debug("Message received in established state " + m.getType()); // dispatch the message h.dispatchMessage(m); @@ -337,7 +341,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * * @param h channel handler */ - protected void disconnectDuplicate(BGPChannelHandler h) { + protected void disconnectDuplicate(BgpChannelHandler h) { log.error("Duplicated BGP IP or incompleted cleanup - " + "" + "disconnecting channel {}", h.getPeerInfoString()); h.duplicateBGPIdFound = Boolean.TRUE; @@ -349,8 +353,8 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { this.handshakeComplete = handshakeComplete; } - void processBGPMessage(BGPChannelHandler bgpChannelHandler, BGPMessage pm) - throws IOException, BGPParseException { + void processBgpMessage(BgpChannelHandler bgpChannelHandler, BgpMessage pm) + throws IOException, BgpParseException { // TODO Auto-generated method stub log.debug("BGP message stub"); } @@ -373,7 +377,8 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { } // Connection should establish only if local ip and Autonomous system number is configured. - if (bgpconfig.getState() != BGPCfg.State.IP_AS_CONFIGURED) { + if (bgpconfig.getState() != BgpCfg.State.IP_AS_CONFIGURED) { + sendNotification(BgpErrorType.CEASE, BgpErrorType.CONNECTION_REJECTED, null); channel.close(); log.info("BGP local AS and router ID not configured"); return; @@ -385,12 +390,13 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { // if peer is not configured disconnect session if (!bgpconfig.isPeerConfigured(peerAddr)) { log.debug("Peer is not configured {}", peerAddr); + sendNotification(BgpErrorType.CEASE, BgpErrorType.CONNECTION_REJECTED, null); channel.close(); return; } // if connection is already established close channel - if (peerManager.isPeerConnected(BGPId.bgpId(IpAddress.valueOf(peerAddr)))) { + if (peerManager.isPeerConnected(BgpId.bgpId(IpAddress.valueOf(peerAddr)))) { log.debug("Duplicate connection received, peer {}", peerAddr); channel.close(); return; @@ -406,7 +412,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { sendHandshakeOpenMessage(); bgpPacketStats.addOutPacket(); setState(ChannelState.OPENSENT); - bgpconfig.setPeerConnState(peerAddr, BGPPeerCfg.State.OPENSENT); + bgpconfig.setPeerConnState(peerAddr, BgpPeerCfg.State.OPENSENT); } } @@ -436,6 +442,25 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { if (bgpPeer != null) { peerManager.removeConnectedPeer(thisbgpId); } + + // Retry connection if connection is lost to bgp speaker/peer + if ((channel != null) && (null != channel.getPipeline().get("ActiveHandler"))) { + BgpConnectPeerImpl connectPeer; + BgpPeerCfg.State peerCfgState; + + peerCfgState = bgpconfig.getPeerConnState(peerAddr); + // on session disconnect using configuration, do not retry + if (!peerCfgState.equals(BgpPeerCfg.State.IDLE)) { + log.debug("Connection reset by peer, retry, STATE:{}", peerCfgState); + BgpPeerConfig peerConfig = (BgpPeerConfig) bgpconfig.displayPeers(peerAddr); + + bgpconfig.setPeerConnState(peerAddr, BgpPeerCfg.State.IDLE); + connectPeer = new BgpConnectPeerImpl(bgpController, peerAddr, Controller.getBgpPortNum()); + peerConfig.setConnectPeer(connectPeer); + } + } else { + bgpconfig.setPeerConnState(peerAddr, BgpPeerCfg.State.IDLE); + } } else { // A duplicate was disconnected on this ChannelHandler, // this is the same peer reconnecting, but the original state was @@ -448,6 +473,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { keepAliveTimer.getKeepAliveTimer().cancel(); } } else { + bgpconfig.setPeerConnState(peerAddr, BgpPeerCfg.State.IDLE); log.warn("No bgp ip in channelHandler registered for " + "disconnected peer {}", getPeerInfoString()); } } @@ -461,14 +487,14 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { if ((ChannelState.OPENWAIT == state) || (ChannelState.OPENSENT == state)) { // When ReadTimeout timer is expired in OPENWAIT/OPENSENT state, it is considered - sendNotification(BGPErrorType.HOLD_TIMER_EXPIRED, (byte) 0, null); + sendNotification(BgpErrorType.HOLD_TIMER_EXPIRED, (byte) 0, null); channel.close(); state = ChannelState.IDLE; return; } else if (ChannelState.OPENCONFIRM == state) { // When ReadTimeout timer is expired in OPENCONFIRM state. - sendNotification(BGPErrorType.HOLD_TIMER_EXPIRED, (byte) 0, null); + sendNotification(BgpErrorType.HOLD_TIMER_EXPIRED, (byte) 0, null); channel.close(); state = ChannelState.IDLE; return; @@ -482,9 +508,9 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { log.debug("StackTrace for previous Exception: ", e.getCause()); } channel.close(); - } else if (e.getCause() instanceof BGPParseException) { + } else if (e.getCause() instanceof BgpParseException) { byte[] data = new byte[] {}; - BGPParseException errMsg = (BGPParseException) e.getCause(); + BgpParseException errMsg = (BgpParseException) e.getCause(); byte errorCode = errMsg.getErrorCode(); byte errorSubCode = errMsg.getErrorSubCode(); ChannelBuffer tempCb = errMsg.getData(); @@ -511,14 +537,47 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { if (e.getMessage() instanceof List) { @SuppressWarnings("Unchecked") - List msglist = (List) e.getMessage(); - for (BGPMessage pm : msglist) { + List msglist = (List) e.getMessage(); + for (BgpMessage pm : msglist) { // Do the actual packet processing - state.processBGPMessage(this, pm); + state.processBgpMessage(this, pm); } } else { - state.processBGPMessage(this, (BGPMessage) e.getMessage()); + state.processBgpMessage(this, (BgpMessage) e.getMessage()); + } + } + + /** + * Check for connection collision. + * + * @param state connection state + * @param peerIdentifier BGP peer identifier + * @param peerAddr BGP peer address + * @return true if bgp spreakers initiated connection + * @throws BgpParseException on error while procession collision detection + * @throws IOException on error while procession collision detection + */ + public boolean connectionCollisionDetection(BgpPeerCfg.State state, int peerIdentifier, String peerAddr) + throws IOException, BgpParseException { + /* + * RFC 4271, Section 6.8, Based on the value of the BGP identifier, a convention is established for detecting + * which BGP connection is to be preserved when a collision occurs. The convention is to compare the BGP + * Identifiers of the peers involved in the collision and to retain only the connection initiated by the BGP + * speaker with the higher-valued BGP Identifier.. + */ + BgpPeerCfg.State currentState = bgpconfig.getPeerConnState(peerAddr); + if (currentState.equals(state)) { + if (((Ip4Address.valueOf(bgpconfig.getRouterId())).compareTo(Ip4Address.valueOf(peerIdentifier))) > 0) { + // send notification + sendNotification(BgpErrorType.CEASE, BgpErrorType.CONNECTION_COLLISION_RESOLUTION, null); + log.debug("Connection collision detected, local id: {}, peer id: {}, peer state:{}, in state:{}", + (Ip4Address.valueOf(bgpconfig.getRouterId())), (Ip4Address.valueOf(peerIdentifier)), + currentState, state); + return true; + } } + + return false; } // ************************* @@ -546,9 +605,9 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * To handle the BGP message. * * @param m bgp message - * @throws BGPParseException throw exception + * @throws BgpParseException throw exception */ - private void dispatchMessage(BGPMessage m) throws BGPParseException { + private void dispatchMessage(BgpMessage m) throws BgpParseException { bgpPacketStats.addInPacket(); bgpController.processBGPPacket(thisbgpId, m); } @@ -589,24 +648,22 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * * @return packet statistics */ - public BGPPacketStatsImpl getBgpPacketStats() { + public BgpPacketStatsImpl getBgpPacketStats() { return bgpPacketStats; } /** * Send handshake open message to the peer. * - * @throws IOException, BGPParseException + * @throws IOException, BgpParseException */ - private void sendHandshakeOpenMessage() throws IOException, BGPParseException { + private void sendHandshakeOpenMessage() throws IOException, BgpParseException { int bgpId; bgpId = Ip4Address.valueOf(bgpconfig.getRouterId()).toInt(); - BGPMessage msg = factory4.openMessageBuilder().setAsNumber((short) bgpconfig.getAsNumber()) - .setHoldTime(bgpconfig.getHoldTime()).setBgpId(bgpId) - .setLsCapabilityTlv(bgpconfig.getLsCapability()) - .setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability()) - .build(); + BgpMessage msg = factory4.openMessageBuilder().setAsNumber((short) bgpconfig.getAsNumber()) + .setHoldTime(bgpconfig.getHoldTime()).setBgpId(bgpId).setLsCapabilityTlv(bgpconfig.getLsCapability()) + .setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability()).build(); log.debug("Sending open message to {}", channel.getRemoteAddress()); channel.write(Collections.singletonList(msg)); @@ -618,12 +675,12 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * @param errorCode error code send in notification * @param errorSubCode sub error code send in notification * @param data data to send in notification - * @throws IOException, BGPParseException while building message + * @throws IOException, BgpParseException while building message */ private void sendNotification(byte errorCode, byte errorSubCode, byte[] data) - throws IOException, BGPParseException { - BGPMessage msg = factory4.notificationMessageBuilder().setErrorCode(errorCode).setErrorSubCode(errorSubCode) - .setData(data).build(); + throws IOException, BgpParseException { + BgpMessage msg = factory4.notificationMessageBuilder().setErrorCode(errorCode) + .setErrorSubCode(errorSubCode).setData(data).build(); log.debug("Sending notification message to {}", channel.getRemoteAddress()); channel.write(Collections.singletonList(msg)); } @@ -632,11 +689,11 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * Send keep alive message. * * @throws IOException when channel is disconnected - * @throws BGPParseException while building keep alive message + * @throws BgpParseException while building keep alive message */ - synchronized void sendKeepAliveMessage() throws IOException, BGPParseException { + synchronized void sendKeepAliveMessage() throws IOException, BgpParseException { - BGPMessage msg = factory4.keepaliveMessageBuilder().build(); + BgpMessage msg = factory4.keepaliveMessageBuilder().build(); log.debug("Sending keepalive message to {}", channel.getRemoteAddress()); channel.write(Collections.singletonList(msg)); } @@ -647,10 +704,10 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * @param errorCode error code * @param errorSubCode error sub code * @param data message type - * @throws BGPParseException while processing error messsage + * @throws BgpParseException while processing error messsage * @throws IOException while processing error message */ - public void processUnknownMsg(byte errorCode, byte errorSubCode, byte data) throws BGPParseException, IOException { + public void processUnknownMsg(byte errorCode, byte errorSubCode, byte data) throws BgpParseException, IOException { log.debug("UNKNOWN message received"); byte[] byteArray = new byte[1]; byteArray[0] = data; @@ -664,26 +721,26 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * @param h channel handler * @param openMsg open message * @return true if valid message, otherwise false - * @throws BGPParseException throw exception + * @throws BgpParseException throw exception */ - public boolean openMsgValidation(BGPChannelHandler h, BGPOpenMsg openMsg) throws BGPParseException { + public boolean openMsgValidation(BgpChannelHandler h, BgpOpenMsg openMsg) throws BgpParseException { boolean result; // Validate BGP ID result = bgpIdValidation(openMsg); if (!result) { - throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_BGP_IDENTIFIER, null); + throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.BAD_BGP_IDENTIFIER, null); } // Validate AS number result = asNumberValidation(h, openMsg); if (!result) { - throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null); + throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.BAD_PEER_AS, null); } // Validate hold timer if ((openMsg.getHoldTime() != 0) && (openMsg.getHoldTime() < BGP_MIN_HOLDTIME)) { - throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.UNACCEPTABLE_HOLD_TIME, null); + throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.UNACCEPTABLE_HOLD_TIME, null); } // Validate capabilities @@ -697,25 +754,25 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * @param h channel handler * @param openmsg open message * @return success or failure - * @throws BGPParseException + * @throws BgpParseException */ - private boolean capabilityValidation(BGPChannelHandler h, BGPOpenMsg openmsg) throws BGPParseException { + private boolean capabilityValidation(BgpChannelHandler h, BgpOpenMsg openmsg) throws BgpParseException { log.debug("capabilityValidation"); boolean isMultiProtocolcapabilityExists = false; boolean isFourOctetCapabilityExits = false; int capAsNum = 0; - List capabilityTlv = openmsg.getCapabilityTlv(); - ListIterator listIterator = capabilityTlv.listIterator(); - List unSupportedCapabilityTlv = new LinkedList<>(); - ListIterator unSupportedCaplistIterator = unSupportedCapabilityTlv.listIterator(); - BGPValueType tempTlv; + List capabilityTlv = openmsg.getCapabilityTlv(); + ListIterator listIterator = capabilityTlv.listIterator(); + List unSupportedCapabilityTlv = new LinkedList<>(); + ListIterator unSupportedCaplistIterator = unSupportedCapabilityTlv.listIterator(); + BgpValueType tempTlv; boolean isLargeAsCapabilityCfg = h.bgpconfig.getLargeASCapability(); boolean isLsCapabilityCfg = h.bgpconfig.getLsCapability(); while (listIterator.hasNext()) { - BGPValueType tlv = listIterator.next(); + BgpValueType tlv = listIterator.next(); if (tlv.getType() == MULTI_PROTOCOL_EXTN_CAPA_TYPE) { isMultiProtocolcapabilityExists = true; } @@ -728,11 +785,11 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { if (isFourOctetCapabilityExits) { if (capAsNum > MAX_AS2_NUM) { if (openmsg.getAsNumber() != AS_TRANS) { - throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null); + throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.BAD_PEER_AS, null); } } else { if (capAsNum != openmsg.getAsNumber()) { - throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null); + throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.BAD_PEER_AS, null); } } } @@ -754,11 +811,10 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { if (unSupportedCaplistIterator.hasNext()) { ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); while (unSupportedCaplistIterator.hasNext()) { - BGPValueType tlv = unSupportedCaplistIterator.next(); + BgpValueType tlv = unSupportedCaplistIterator.next(); tlv.write(buffer); } - throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, - BGPErrorType.UNSUPPORTED_CAPABILITY, buffer); + throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.UNSUPPORTED_CAPABILITY, buffer); } else { return true; } @@ -771,18 +827,18 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * @param openMsg open message * @return true or false */ - private boolean asNumberValidation(BGPChannelHandler h, BGPOpenMsg openMsg) { + private boolean asNumberValidation(BgpChannelHandler h, BgpOpenMsg openMsg) { log.debug("AS Num validation"); int capAsNum = 0; boolean isFourOctetCapabilityExits = false; - BGPPeerCfg peerCfg = h.bgpconfig.displayPeers(peerAddr); - List capabilityTlv = openMsg.getCapabilityTlv(); - ListIterator listIterator = capabilityTlv.listIterator(); + BgpPeerCfg peerCfg = h.bgpconfig.displayPeers(peerAddr); + List capabilityTlv = openMsg.getCapabilityTlv(); + ListIterator listIterator = capabilityTlv.listIterator(); while (listIterator.hasNext()) { - BGPValueType tlv = listIterator.next(); + BgpValueType tlv = listIterator.next(); if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) { isFourOctetCapabilityExits = true; capAsNum = ((FourOctetAsNumCapabilityTlv) tlv).getInt(); @@ -838,7 +894,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler { * @param openMsg open message * @return true or false */ - private boolean bgpIdValidation(BGPOpenMsg openMsg) { + private boolean bgpIdValidation(BgpOpenMsg openMsg) { String openMsgBgpId = Ip4Address.valueOf(openMsg.getBgpId()).toString(); InetAddress ipAddress; diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPConfig.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java similarity index 83% rename from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPConfig.java rename to framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java index 56877a16..716cc0c5 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPConfig.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java @@ -21,17 +21,17 @@ import java.util.Set; import java.util.TreeMap; import org.onlab.packet.Ip4Address; -import org.onosproject.bgp.controller.BGPCfg; -import org.onosproject.bgp.controller.BGPPeerCfg; +import org.onosproject.bgp.controller.BgpCfg; +import org.onosproject.bgp.controller.BgpPeerCfg; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Provides BGP configuration of this BGP speaker. */ -public class BGPConfig implements BGPCfg { +public class BgpConfig implements BgpCfg { - protected static final Logger log = LoggerFactory.getLogger(BGPConfig.class); + protected static final Logger log = LoggerFactory.getLogger(BgpConfig.class); private static final short DEFAULT_HOLD_TIMER = 120; private static final short DEFAULT_CONN_RETRY_TIME = 120; @@ -47,12 +47,12 @@ public class BGPConfig implements BGPCfg { private int maxConnRetryCount; private Ip4Address routerId = null; - private TreeMap bgpPeerTree = new TreeMap<>(); + private TreeMap bgpPeerTree = new TreeMap<>(); /** * Constructor to initialize the values. */ - public BGPConfig() { + public BgpConfig() { this.holdTime = DEFAULT_HOLD_TIMER; this.maxConnRetryTime = DEFAULT_CONN_RETRY_TIME; @@ -142,13 +142,13 @@ public class BGPConfig implements BGPCfg { @Override public boolean addPeer(String routerid, int remoteAs, short holdTime) { - BGPPeerConfig lspeer = new BGPPeerConfig(); + BgpPeerConfig lspeer = new BgpPeerConfig(); if (this.bgpPeerTree.get(routerid) == null) { lspeer.setPeerRouterId(routerid); lspeer.setAsNumber(remoteAs); lspeer.setHoldtime(holdTime); - lspeer.setState(BGPPeerCfg.State.IDLE); + lspeer.setState(BgpPeerCfg.State.IDLE); lspeer.setSelfInnitConnection(false); if (this.getAsNumber() == remoteAs) { @@ -168,7 +168,7 @@ public class BGPConfig implements BGPCfg { @Override public boolean connectPeer(String routerid) { - BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid); + BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid); if (lspeer != null) { lspeer.setSelfInnitConnection(true); @@ -181,7 +181,7 @@ public class BGPConfig implements BGPCfg { @Override public boolean removePeer(String routerid) { - BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid); + BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid); if (lspeer != null) { @@ -200,12 +200,12 @@ public class BGPConfig implements BGPCfg { @Override public boolean disconnectPeer(String routerid) { - BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid); + BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid); if (lspeer != null) { //TODO DISCONNECT PEER - lspeer.setState(BGPPeerCfg.State.IDLE); + lspeer.setState(BgpPeerCfg.State.IDLE); lspeer.setSelfInnitConnection(false); log.debug("Disconnected : " + routerid + " successfully"); @@ -217,8 +217,8 @@ public class BGPConfig implements BGPCfg { } @Override - public void setPeerConnState(String routerid, BGPPeerCfg.State state) { - BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid); + public void setPeerConnState(String routerid, BgpPeerCfg.State state) { + BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid); if (lspeer != null) { lspeer.setState(state); @@ -232,21 +232,21 @@ public class BGPConfig implements BGPCfg { } @Override - public BGPPeerCfg.State getPeerConnState(String routerid) { - BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid); + public BgpPeerCfg.State getPeerConnState(String routerid) { + BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid); if (lspeer != null) { return lspeer.getState(); } else { - return BGPPeerCfg.State.INVALID; //No instance + return BgpPeerCfg.State.INVALID; //No instance } } @Override public boolean isPeerConnectable(String routerid) { - BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid); + BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid); - if ((lspeer != null) && lspeer.getState().equals(BGPPeerCfg.State.IDLE)) { + if ((lspeer != null) && lspeer.getState().equals(BgpPeerCfg.State.IDLE)) { return true; } @@ -254,21 +254,21 @@ public class BGPConfig implements BGPCfg { } @Override - public TreeMap getPeerTree() { + public TreeMap getPeerTree() { return this.bgpPeerTree; } @Override - public TreeMap displayPeers() { + public TreeMap displayPeers() { if (this.bgpPeerTree.isEmpty()) { log.debug("There are no BGP peers"); } else { - Set> set = this.bgpPeerTree.entrySet(); - Iterator> list = set.iterator(); - BGPPeerCfg lspeer; + Set> set = this.bgpPeerTree.entrySet(); + Iterator> list = set.iterator(); + BgpPeerCfg lspeer; while (list.hasNext()) { - Entry me = list.next(); + Entry me = list.next(); lspeer = me.getValue(); log.debug("Peer neighbor IP :" + me.getKey()); log.debug(", AS Number : " + lspeer.getAsNumber()); @@ -280,10 +280,10 @@ public class BGPConfig implements BGPCfg { } @Override - public BGPPeerCfg displayPeers(String routerid) { + public BgpPeerCfg displayPeers(String routerid) { if (this.bgpPeerTree.isEmpty()) { - log.debug("There are no BGP peers"); + log.debug("There are no Bgp peers"); } else { return this.bgpPeerTree.get(routerid); } @@ -312,7 +312,7 @@ public class BGPConfig implements BGPCfg { @Override public boolean isPeerConfigured(String routerid) { - BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid); + BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid); return (lspeer != null) ? true : false; } diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConnectPeerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConnectPeerImpl.java new file mode 100755 index 00000000..27db618d --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConnectPeerImpl.java @@ -0,0 +1,133 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.onosproject.bgp.controller.impl; + +import java.net.InetSocketAddress; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.jboss.netty.bootstrap.ClientBootstrap; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.onosproject.bgp.controller.BgpCfg; +import org.onosproject.bgp.controller.BgpController; +import org.onosproject.bgp.controller.BgpPeerCfg; +import org.onosproject.bgp.controller.BgpConnectPeer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implements connection initiation to peer on peer configuration and manage channel using netty channel handler. + */ +public class BgpConnectPeerImpl implements BgpConnectPeer { + private static final Logger log = LoggerFactory.getLogger(BgpConnectPeerImpl.class); + + private ScheduledExecutorService connectExecutor = null; + private final String peerHost; + private static final int RETRY_INTERVAL = 4; + private final int peerPort; + private int connectRetryCounter = 0; + private int connectRetryTime; + private ChannelPipelineFactory pfact; + private ClientBootstrap peerBootstrap; + private BgpCfg bgpconfig; + + /** + * Initialize timer and initiate pipeline factory. + * + * @param bgpController parent BGP controller + * @param remoteHost remote host to connect + * @param remotePort remote port to connect + */ + public BgpConnectPeerImpl(BgpController bgpController, String remoteHost, int remotePort) { + + this.bgpconfig = bgpController.getConfig(); + this.pfact = new BgpPipelineFactory(bgpController, false); + this.peerBootstrap = Controller.peerBootstrap(); + this.peerBootstrap.setPipelineFactory(pfact); + this.peerHost = remoteHost; + this.peerPort = remotePort; + this.connectRetryTime = 0; + } + + @Override + public void disconnectPeer() { + if (connectExecutor != null) { + connectExecutor.shutdown(); + connectExecutor = null; + } + } + + @Override + public void connectPeer() { + scheduleConnectionRetry(this.connectRetryTime); + } + + /** + * Retry connection with exponential back-off mechanism. + * + * @param retryDelay retry delay + */ + private void scheduleConnectionRetry(long retryDelay) { + if (this.connectExecutor == null) { + this.connectExecutor = Executors.newSingleThreadScheduledExecutor(); + } + this.connectExecutor.schedule(new ConnectionRetry(), retryDelay, TimeUnit.MINUTES); + } + + /** + * Implements BGP connection and manages connection to peer with back-off mechanism in case of failure. + */ + class ConnectionRetry implements Runnable { + @Override + public void run() { + log.debug("Connect to peer {}", peerHost); + + InetSocketAddress connectToSocket = new InetSocketAddress(peerHost, peerPort); + + try { + bgpconfig.setPeerConnState(peerHost, BgpPeerCfg.State.CONNECT); + peerBootstrap.connect(connectToSocket).addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (!future.isSuccess()) { + bgpconfig.setPeerConnState(peerHost, BgpPeerCfg.State.ACTIVE); + connectRetryCounter++; + log.error("Connection failed, ConnectRetryCounter {} remote host {}", connectRetryCounter, + peerHost); + /* + * Reconnect to peer on failure is exponential till 4 mins, later on retry after every 4 + * mins. + */ + if (connectRetryTime < RETRY_INTERVAL) { + connectRetryTime = (connectRetryTime != 0) ? connectRetryTime * 2 : 1; + } + scheduleConnectionRetry(connectRetryTime); + } else { + + connectRetryCounter++; + log.info("Connected to remote host {}, Connect Counter {}", peerHost, connectRetryCounter); + disconnectPeer(); + return; + } + } + }); + } catch (Exception e) { + log.info("Connect peer exception : " + e.toString()); + disconnectPeer(); + } + } + } +} diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java similarity index 68% rename from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java rename to framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java index 35c31ab7..6a14e85c 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java @@ -26,34 +26,32 @@ import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Service; -import org.onosproject.bgp.controller.BGPCfg; -import org.onosproject.bgp.controller.BGPController; -import org.onosproject.bgp.controller.BGPId; -import org.onosproject.bgp.controller.BGPPeer; -import org.onosproject.bgp.controller.BgpLinkListener; +import org.onosproject.bgp.controller.BgpCfg; +import org.onosproject.bgp.controller.BgpController; +import org.onosproject.bgp.controller.BgpId; +import org.onosproject.bgp.controller.BgpPeer; import org.onosproject.bgp.controller.BgpNodeListener; import org.onosproject.bgp.controller.BgpPeerManager; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPMessage; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component(immediate = true) @Service -public class BGPControllerImpl implements BGPController { +public class BgpControllerImpl implements BgpController { - private static final Logger log = LoggerFactory.getLogger(BGPControllerImpl.class); + private static final Logger log = LoggerFactory.getLogger(BgpControllerImpl.class); - protected ConcurrentHashMap connectedPeers = new ConcurrentHashMap(); + protected ConcurrentHashMap connectedPeers = new ConcurrentHashMap(); - protected BGPPeerManagerImpl peerManager = new BGPPeerManagerImpl(); + protected BgpPeerManagerImpl peerManager = new BgpPeerManagerImpl(); protected Set bgpNodeListener = new CopyOnWriteArraySet<>(); - protected Set bgpLinkListener = new CopyOnWriteArraySet<>(); final Controller ctrl = new Controller(this); - private BGPConfig bgpconfig = new BGPConfig(); + private BgpConfig bgpconfig = new BgpConfig(); @Activate public void activate() { @@ -70,12 +68,12 @@ public class BGPControllerImpl implements BGPController { } @Override - public Iterable getPeers() { + public Iterable getPeers() { return this.connectedPeers.values(); } @Override - public BGPPeer getPeer(BGPId bgpId) { + public BgpPeer getPeer(BgpId bgpId) { return this.connectedPeers.get(bgpId); } @@ -95,27 +93,12 @@ public class BGPControllerImpl implements BGPController { } @Override - public void addLinkListener(BgpLinkListener listener) { - this.bgpLinkListener.add(listener); - } - - @Override - public void removeLinkListener(BgpLinkListener listener) { - this.bgpLinkListener.remove(listener); - } - - @Override - public Set linkListener() { - return bgpLinkListener; - } - - @Override - public void writeMsg(BGPId bgpId, BGPMessage msg) { + public void writeMsg(BgpId bgpId, BgpMessage msg) { this.getPeer(bgpId).sendMessage(msg); } @Override - public void processBGPPacket(BGPId bgpId, BGPMessage msg) throws BGPParseException { + public void processBGPPacket(BgpId bgpId, BgpMessage msg) throws BgpParseException { switch (msg.getType()) { case OPEN: @@ -138,8 +121,8 @@ public class BGPControllerImpl implements BGPController { @Override public void closeConnectedPeers() { - BGPPeer bgpPeer; - for (BGPId id : this.connectedPeers.keySet()) { + BgpPeer bgpPeer; + for (BgpId id : this.connectedPeers.keySet()) { bgpPeer = getPeer(id); bgpPeer.disconnectPeer(); } @@ -149,13 +132,13 @@ public class BGPControllerImpl implements BGPController { * Implementation of an BGP Peer which is responsible for keeping track of connected peers and the state in which * they are. */ - public class BGPPeerManagerImpl implements BgpPeerManager { + public class BgpPeerManagerImpl implements BgpPeerManager { - private final Logger log = LoggerFactory.getLogger(BGPPeerManagerImpl.class); + private final Logger log = LoggerFactory.getLogger(BgpPeerManagerImpl.class); private final Lock peerLock = new ReentrantLock(); @Override - public boolean addConnectedPeer(BGPId bgpId, BGPPeer bgpPeer) { + public boolean addConnectedPeer(BgpId bgpId, BgpPeer bgpPeer) { if (connectedPeers.get(bgpId) != null) { this.log.error("Trying to add connectedPeer but found previous " + "value for bgp ip: {}", @@ -169,7 +152,7 @@ public class BGPControllerImpl implements BGPController { } @Override - public boolean isPeerConnected(BGPId bgpId) { + public boolean isPeerConnected(BgpId bgpId) { if (connectedPeers.get(bgpId) == null) { this.log.error("Is peer connected: bgpIp {}.", bgpId.toString()); return false; @@ -179,12 +162,12 @@ public class BGPControllerImpl implements BGPController { } @Override - public void removeConnectedPeer(BGPId bgpId) { + public void removeConnectedPeer(BgpId bgpId) { connectedPeers.remove(bgpId); } @Override - public BGPPeer getPeer(BGPId bgpId) { + public BgpPeer getPeer(BgpId bgpId) { return connectedPeers.get(bgpId); } @@ -196,26 +179,35 @@ public class BGPControllerImpl implements BGPController { * @param pktStats packet statistics. * @return BGPPeer peer instance. */ - public BGPPeer getBGPPeerInstance(BGPController bgpController, BgpSessionInfoImpl sessionInfo, - BGPPacketStatsImpl pktStats) { - BGPPeer bgpPeer = new BGPPeerImpl(bgpController, sessionInfo, pktStats); + public BgpPeer getBgpPeerInstance(BgpController bgpController, BgpSessionInfoImpl sessionInfo, + BgpPacketStatsImpl pktStats) { + BgpPeer bgpPeer = new BgpPeerImpl(bgpController, sessionInfo, pktStats); return bgpPeer; } } + /** + * Returns controller. + * + * @return controller + */ + public Controller controller() { + return this.ctrl; + } + @Override - public ConcurrentHashMap connectedPeers() { + public ConcurrentHashMap connectedPeers() { return connectedPeers; } @Override - public BGPPeerManagerImpl peerManager() { + public BgpPeerManagerImpl peerManager() { return peerManager; } @Override - public BGPCfg getConfig() { + public BgpCfg getConfig() { return this.bgpconfig; } diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPKeepAliveTimer.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpKeepAliveTimer.java similarity index 89% rename from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPKeepAliveTimer.java rename to framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpKeepAliveTimer.java index 1c95804a..524ac4c1 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPKeepAliveTimer.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpKeepAliveTimer.java @@ -25,11 +25,11 @@ import org.slf4j.LoggerFactory; /** * Implement sending keepalive message to connected peer periodically based on negotiated holdtime. */ -public class BGPKeepAliveTimer { +public class BgpKeepAliveTimer { private Timer keepAliveTimer; - private BGPChannelHandler handler; - private static final Logger log = LoggerFactory.getLogger(BGPKeepAliveTimer.class); + private BgpChannelHandler handler; + private static final Logger log = LoggerFactory.getLogger(BgpKeepAliveTimer.class); /** * Gets keepalive timer object. @@ -46,7 +46,7 @@ public class BGPKeepAliveTimer { * @param h channel handler * @param seconds time interval. */ - public BGPKeepAliveTimer(BGPChannelHandler h, int seconds) { + public BgpKeepAliveTimer(BgpChannelHandler h, int seconds) { this.handler = h; this.keepAliveTimer = new Timer(); this.keepAliveTimer.schedule(new SendKeepAlive(), 0, seconds * 1000); diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageDecoder.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageDecoder.java similarity index 75% rename from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageDecoder.java rename to framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageDecoder.java index 636b78cc..431c6210 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageDecoder.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageDecoder.java @@ -22,20 +22,20 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.onosproject.bgpio.protocol.BGPMessage; +import org.onosproject.bgpio.protocol.BgpMessage; import org.onlab.util.HexDump; -import org.onosproject.bgpio.protocol.BGPFactories; -import org.onosproject.bgpio.protocol.BGPMessageReader; -import org.onosproject.bgpio.types.BGPHeader; +import org.onosproject.bgpio.protocol.BgpFactories; +import org.onosproject.bgpio.protocol.BgpMessageReader; +import org.onosproject.bgpio.types.BgpHeader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Decode an bgp message from a Channel, for use in a netty pipeline. */ -public class BGPMessageDecoder extends FrameDecoder { +public class BgpMessageDecoder extends FrameDecoder { - protected static final Logger log = LoggerFactory.getLogger(BGPMessageDecoder.class); + protected static final Logger log = LoggerFactory.getLogger(BgpMessageDecoder.class); @Override protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { @@ -47,12 +47,12 @@ public class BGPMessageDecoder extends FrameDecoder { HexDump.dump(buffer); - BGPMessageReader reader = BGPFactories.getGenericReader(); - List msgList = new LinkedList(); + BgpMessageReader reader = BgpFactories.getGenericReader(); + List msgList = new LinkedList(); while (buffer.readableBytes() > 0) { - BGPHeader bgpHeader = new BGPHeader(); - BGPMessage message = reader.readFrom(buffer, bgpHeader); + BgpHeader bgpHeader = new BgpHeader(); + BgpMessage message = reader.readFrom(buffer, bgpHeader); msgList.add(message); } return msgList; diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageEncoder.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageEncoder.java similarity index 87% rename from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageEncoder.java rename to framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageEncoder.java index f0d38c3d..3e56d6ff 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageEncoder.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageEncoder.java @@ -22,7 +22,7 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; -import org.onosproject.bgpio.protocol.BGPMessage; +import org.onosproject.bgpio.protocol.BgpMessage; import org.onlab.util.HexDump; import org.slf4j.Logger; @@ -32,8 +32,8 @@ import org.slf4j.LoggerFactory; * Encode an bgp message for output into a ChannelBuffer, for use in a * netty pipeline. */ -public class BGPMessageEncoder extends OneToOneEncoder { - protected static final Logger log = LoggerFactory.getLogger(BGPMessageEncoder.class); +public class BgpMessageEncoder extends OneToOneEncoder { + protected static final Logger log = LoggerFactory.getLogger(BgpMessageEncoder.class); @Override protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { @@ -44,12 +44,12 @@ public class BGPMessageEncoder extends OneToOneEncoder { } @SuppressWarnings("unchecked") - List msglist = (List) msg; + List msglist = (List) msg; ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); log.debug("SENDING MESSAGE"); - for (BGPMessage pm : msglist) { + for (BgpMessage pm : msglist) { pm.writeTo(buf); } diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPacketStatsImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPacketStatsImpl.java similarity index 94% rename from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPacketStatsImpl.java rename to framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPacketStatsImpl.java index 09f4d452..7494c814 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPacketStatsImpl.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPacketStatsImpl.java @@ -15,7 +15,7 @@ */ package org.onosproject.bgp.controller.impl; -import org.onosproject.bgp.controller.BGPPacketStats; +import org.onosproject.bgp.controller.BgpPacketStats; /** * A representation of a packet context which allows any provider @@ -23,7 +23,7 @@ import org.onosproject.bgp.controller.BGPPacketStats; * event if blocked has been called. This packet context can be used * to react to the packet in event with a packet out. */ -public class BGPPacketStatsImpl implements BGPPacketStats { +public class BgpPacketStatsImpl implements BgpPacketStats { private int inPacketCount; private int outPacketCount; @@ -33,7 +33,7 @@ public class BGPPacketStatsImpl implements BGPPacketStats { /** * Resets parameter. */ - public BGPPacketStatsImpl() { + public BgpPacketStatsImpl() { this.inPacketCount = 0; this.outPacketCount = 0; this.wrongPacketCount = 0; diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerConfig.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerConfig.java similarity index 95% rename from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerConfig.java rename to framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerConfig.java index 14a68cf6..a8eaee3c 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerConfig.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerConfig.java @@ -17,12 +17,12 @@ package org.onosproject.bgp.controller.impl; import org.onlab.packet.Ip4Address; import org.onosproject.bgp.controller.BgpConnectPeer; -import org.onosproject.bgp.controller.BGPPeerCfg; +import org.onosproject.bgp.controller.BgpPeerCfg; /** * BGP Peer configuration information. */ -public class BGPPeerConfig implements BGPPeerCfg { +public class BgpPeerConfig implements BgpPeerCfg { private int asNumber; private short holdTime; private boolean isIBgp; @@ -34,7 +34,7 @@ public class BGPPeerConfig implements BGPPeerCfg { /** * Constructor to initialize the values. */ - BGPPeerConfig() { + BgpPeerConfig() { state = State.IDLE; selfInitiated = false; } diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java new file mode 100644 index 00000000..57a924a8 --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java @@ -0,0 +1,297 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.bgp.controller.impl; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.Collections; +import java.util.List; +import java.util.ListIterator; +import java.util.concurrent.RejectedExecutionException; + +import org.jboss.netty.channel.Channel; +import org.onlab.packet.IpAddress; +import org.onosproject.bgp.controller.BgpController; +import org.onosproject.bgp.controller.BgpPeer; +import org.onosproject.bgp.controller.BgpSessionInfo; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.BgpFactories; +import org.onosproject.bgpio.protocol.BgpFactory; +import org.onosproject.bgpio.protocol.BgpLSNlri; +import org.onosproject.bgpio.protocol.BgpMessage; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.types.MpReachNlri; +import org.onosproject.bgpio.types.MpUnReachNlri; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * BGPPeerImpl implements BGPPeer, maintains peer information and store updates in RIB . + */ +public class BgpPeerImpl implements BgpPeer { + + protected final Logger log = LoggerFactory.getLogger(BgpPeerImpl.class); + + private static final String SHUTDOWN_MSG = "Worker has already been shutdown"; + + private BgpController bgpController; + private Channel channel; + protected String channelId; + private boolean connected; + protected boolean isHandShakeComplete = false; + private BgpSessionInfo sessionInfo; + private BgpPacketStatsImpl pktStats; + private AdjRibIn adjRib; + private VpnAdjRibIn vpnAdjRib; + + + @Override + public BgpSessionInfo sessionInfo() { + return sessionInfo; + } + + /** + * Initialize peer. + * + *@param bgpController controller instance + *@param sessionInfo bgp session info + *@param pktStats packet statistics + */ + public BgpPeerImpl(BgpController bgpController, BgpSessionInfo sessionInfo, BgpPacketStatsImpl pktStats) { + this.bgpController = bgpController; + this.sessionInfo = sessionInfo; + this.pktStats = pktStats; + this.adjRib = new AdjRibIn(); + this.vpnAdjRib = new VpnAdjRibIn(); + } + + + @Override + public void buildAdjRibIn(List pathAttr) throws BgpParseException { + ListIterator iterator = pathAttr.listIterator(); + while (iterator.hasNext()) { + BgpValueType attr = iterator.next(); + if (attr instanceof MpReachNlri) { + List nlri = ((MpReachNlri) attr).mpReachNlri(); + callAdd(this, nlri, pathAttr); + } + if (attr instanceof MpUnReachNlri) { + List nlri = ((MpUnReachNlri) attr).mpUnReachNlri(); + callRemove(this, nlri); + } + } + } + + /** + * Updates NLRI identifier node in a tree separately based on afi and safi. + * + * @param peerImpl BGP peer instance + * @param nlri MpReachNlri path attribute + * @param pathAttr list of BGP path attributes + * @throws BgpParseException throws exception + */ + public void callAdd(BgpPeerImpl peerImpl, List nlri, List pathAttr) + throws BgpParseException { + ListIterator listIterator = nlri.listIterator(); + while (listIterator.hasNext()) { + BgpLSNlri nlriInfo = listIterator.next(); + if (nlriInfo instanceof BgpNodeLSNlriVer4) { + PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr); + if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) { + adjRib.add(nlriInfo, details); + } else { + vpnAdjRib.addVpn(nlriInfo, details, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher()); + } + } else if (nlriInfo instanceof BgpLinkLsNlriVer4) { + PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr); + if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) { + adjRib.add(nlriInfo, details); + } else { + vpnAdjRib.addVpn(nlriInfo, details, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher()); + } + } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) { + PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr); + if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) { + adjRib.add(nlriInfo, details); + } else { + vpnAdjRib.addVpn(nlriInfo, details, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher()); + } + } + } + } + + /** + * Sets BGP path attribute and NLRI details. + * + * @param nlriInfo MpReachNlri path attribute + * @param pathAttr list of BGP path attributes + * @return details object of PathAttrNlriDetails + * @throws BgpParseException throw exception + */ + public PathAttrNlriDetails setPathAttrDetails(BgpLSNlri nlriInfo, List pathAttr) + throws BgpParseException { + PathAttrNlriDetails details = new PathAttrNlriDetails(); + details.setProtocolID(nlriInfo.getProtocolId()); + details.setIdentifier(nlriInfo.getIdentifier()); + details.setPathAttribute(pathAttr); + return details; + } + + /** + * Removes NLRI identifier node in a tree separately based on afi and safi. + * + * @param peerImpl BGP peer instance + * @param nlri NLRI information + */ + public void callRemove(BgpPeerImpl peerImpl, List nlri) { + ListIterator listIterator = nlri.listIterator(); + while (listIterator.hasNext()) { + BgpLSNlri nlriInfo = listIterator.next(); + if (nlriInfo instanceof BgpNodeLSNlriVer4) { + if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) { + adjRib.remove(nlriInfo); + } else { + vpnAdjRib.removeVpn(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher()); + } + } else if (nlriInfo instanceof BgpLinkLsNlriVer4) { + if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) { + adjRib.remove(nlriInfo); + } else { + vpnAdjRib.removeVpn(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher()); + } + } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) { + if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) { + adjRib.remove(nlriInfo); + } else { + vpnAdjRib.removeVpn(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher()); + } + } + } + } + + /** + * Return the adjacency RIB-IN. + * + * @return adjRib the adjacency RIB-IN + */ + public AdjRibIn adjRib() { + return adjRib; + } + + /** + * Return the adjacency RIB-IN with VPN. + * + * @return vpnAdjRib the adjacency RIB-IN with VPN + */ + public VpnAdjRibIn vpnAdjRib() { + return vpnAdjRib; + } + + // ************************ + // Channel related + // ************************ + + @Override + public final void disconnectPeer() { + this.channel.close(); + } + + @Override + public final void sendMessage(BgpMessage m) { + log.debug("Sending message to {}", channel.getRemoteAddress()); + try { + channel.write(Collections.singletonList(m)); + this.pktStats.addOutPacket(); + } catch (RejectedExecutionException e) { + log.warn(e.getMessage()); + if (!e.getMessage().contains(SHUTDOWN_MSG)) { + throw e; + } + } + } + + @Override + public final void sendMessage(List msgs) { + try { + channel.write(msgs); + this.pktStats.addOutPacket(msgs.size()); + } catch (RejectedExecutionException e) { + log.warn(e.getMessage()); + if (!e.getMessage().contains(SHUTDOWN_MSG)) { + throw e; + } + } + } + + @Override + public final boolean isConnected() { + return this.connected; + } + + @Override + public final void setConnected(boolean connected) { + this.connected = connected; + }; + + @Override + public final void setChannel(Channel channel) { + this.channel = channel; + final SocketAddress address = channel.getRemoteAddress(); + if (address instanceof InetSocketAddress) { + final InetSocketAddress inetAddress = (InetSocketAddress) address; + final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress()); + if (ipAddress.isIp4()) { + channelId = ipAddress.toString() + ':' + inetAddress.getPort(); + } else { + channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort(); + } + } + }; + + @Override + public final Channel getChannel() { + return this.channel; + }; + + @Override + public String channelId() { + return channelId; + } + + @Override + public BgpFactory factory() { + return BgpFactories.getFactory(sessionInfo.remoteBgpVersion()); + } + + @Override + public boolean isHandshakeComplete() { + return isHandShakeComplete; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).omitNullValues() + .add("channel", channelId()) + .add("BgpId", sessionInfo().remoteBgpId()).toString(); + } +} diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPipelineFactory.java similarity index 85% rename from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java rename to framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPipelineFactory.java index e6f09f20..28e1041c 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPipelineFactory.java @@ -23,18 +23,18 @@ import org.jboss.netty.handler.timeout.ReadTimeoutHandler; import org.jboss.netty.util.ExternalResourceReleasable; import org.jboss.netty.util.HashedWheelTimer; import org.jboss.netty.util.Timer; -import org.onosproject.bgp.controller.BGPController; +import org.onosproject.bgp.controller.BgpController; /** * Creates a ChannelPipeline for a server-side bgp channel. */ -public class BGPPipelineFactory +public class BgpPipelineFactory implements ChannelPipelineFactory, ExternalResourceReleasable { static final Timer TIMER = new HashedWheelTimer(); protected ReadTimeoutHandler readTimeoutHandler; private boolean isBgpServ; - private BGPController bgpController; + private BgpController bgpController; /** * Constructor to initialize the values. @@ -42,7 +42,7 @@ public class BGPPipelineFactory * @param bgpController parent controller * @param isBgpServ if it is a server or remote peer */ - public BGPPipelineFactory(BGPController bgpController, boolean isBgpServ) { + public BgpPipelineFactory(BgpController bgpController, boolean isBgpServ) { super(); this.isBgpServ = isBgpServ; this.bgpController = bgpController; @@ -52,11 +52,11 @@ public class BGPPipelineFactory @Override public ChannelPipeline getPipeline() throws Exception { - BGPChannelHandler handler = new BGPChannelHandler(bgpController); + BgpChannelHandler handler = new BgpChannelHandler(bgpController); ChannelPipeline pipeline = Channels.pipeline(); - pipeline.addLast("bgpmessagedecoder", new BGPMessageDecoder()); - pipeline.addLast("bgpmessageencoder", new BGPMessageEncoder()); + pipeline.addLast("bgpmessagedecoder", new BgpMessageDecoder()); + pipeline.addLast("bgpmessageencoder", new BgpMessageEncoder()); pipeline.addLast("holdTime", readTimeoutHandler); if (isBgpServ) { pipeline.addLast("PassiveHandler", handler); diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java new file mode 100644 index 00000000..d3065f43 --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java @@ -0,0 +1,242 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgp.controller.impl; + +import java.util.Comparator; +import java.util.List; +import java.util.ListIterator; + +import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetailsLocalRib; +import org.onosproject.bgpio.types.AsPath; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.types.LocalPref; +import org.onosproject.bgpio.types.Med; +import org.onosproject.bgpio.types.Origin; +import org.onosproject.bgpio.types.Origin.ORIGINTYPE; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation of BGP best path Selection process. + */ +public final class BgpSelectionAlgo implements Comparator { + private static final Logger log = LoggerFactory.getLogger(BgpSelectionAlgo.class); + LocalPref obj1LocPref = null; + AsPath obj1Aspath = null; + Origin obj1Origin = null; + Med obj1Med = null; + LocalPref obj2LocPref = null; + AsPath obj2Aspath = null; + Origin obj2Origin = null; + Med obj2Med = null; + + @Override + public int compare(PathAttrNlriDetailsLocalRib pathNlriDetails1, PathAttrNlriDetailsLocalRib pathNlriDetails2) { + if (pathNlriDetails1 == null) { + return -1; + } + if (pathNlriDetails2 == null) { + return 1; + } + if (pathNlriDetails1.equals(pathNlriDetails2)) { + return 0; + } + + List o1 = pathNlriDetails1.localRibNlridetails().pathAttributes(); + List o2 = pathNlriDetails2.localRibNlridetails().pathAttributes(); + ListIterator listIteratorObj1 = o1.listIterator(); + ListIterator listIteratorObj2 = o2.listIterator(); + storeAttr(listIteratorObj1, listIteratorObj2); + + // prefer attribute with higher local preference + if (obj1LocPref != null || obj2LocPref != null && (obj1LocPref != null && !obj1LocPref.equals(obj2LocPref))) { + return compareLocalPref(obj1LocPref, obj2LocPref); + } + + // prefer attribute with shortest Aspath + if (!obj1Aspath.equals(obj2Aspath)) { + Integer obj1Size = countASSize(obj1Aspath); + Integer obj2Size = countASSize(obj2Aspath); + if (obj1Size != obj2Size) { + return compareAsPath(obj1Size, obj2Size); + } + } + + // prefer attribute with lowest origin type + if (!obj1Origin.equals(obj2Origin)) { + return compareOrigin(obj1Origin, obj2Origin); + } + + // prefer attribute with lowest MED + if (obj1Med != null || obj2Med != null && (obj1Med != null && !obj1Med.equals(obj2Med))) { + return compareMed(obj1Med, obj2Med); + } + + if ((pathNlriDetails1 != null || pathNlriDetails2 != null) && (pathNlriDetails1 != null && !pathNlriDetails1 + .equals(pathNlriDetails2))) { + return comparePeerDetails(pathNlriDetails1, pathNlriDetails2); + } + return 0; + } + + /** + * Compares local preference of two objects and returns object with higher preference. + * + * @param obj1LocPref local preference object1 + * @param obj2LocPref local preference object2 + * @return object with higher preference + */ + int compareLocalPref(LocalPref obj1LocPref, LocalPref obj2LocPref) { + return ((Integer) (obj1LocPref.localPref())).compareTo((Integer) (obj2LocPref.localPref())); + } + + /** + * Compares AsPath of two objects and returns object with shortest AsPath. + * + * @param obj1Size object1 AS count + * @param obj2Size object2 AS count + * @return + */ + int compareAsPath(Integer obj1Size, Integer obj2Size) { + return obj1Size.compareTo(obj2Size); + } + + /** + * Compare Origin of two objects and returns object with lowest origin value. + * + * @param obj1Origin Origin object1 + * @param obj2Origin Origin object1 + * @return object with lowest origin value + */ + int compareOrigin(Origin obj1Origin, Origin obj2Origin) { + if (obj1Origin.origin() == ORIGINTYPE.IGP) { + return 1; + } + if (obj2Origin.origin() == ORIGINTYPE.IGP) { + return -1; + } + if (obj1Origin.origin() == ORIGINTYPE.EGP) { + return 1; + } else { + return -1; + } + } + + /** + * Compare Med of two objects and returns object with lowestMed value. + * + * @param obj1Med Med object1 + * @param obj2Med Med object2 + * @return returns object with lowestMed value + */ + int compareMed(Med obj1Med, Med obj2Med) { + return ((Integer) (obj2Med.med())).compareTo((Integer) (obj1Med.med())); + } + + /** + * Compares EBGP over IBGP, BGP identifier value and peer address. + * + * @param pathNlriDetails1 PathAttrNlriDetailsLocalRib object1 + * @param pathNlriDetails2 PathAttrNlriDetailsLocalRib object2 + * @return object which as EBGP over IBGP, lowest BGP identifier value and lowest peer address + */ + int comparePeerDetails(PathAttrNlriDetailsLocalRib pathNlriDetails1, PathAttrNlriDetailsLocalRib pathNlriDetails2) { + // consider EBGP over IBGP + if (pathNlriDetails1.isLocalRibIbgpSession() != pathNlriDetails2.isLocalRibIbgpSession()) { + if (pathNlriDetails1 == null || pathNlriDetails1.isLocalRibIbgpSession()) { + return -1; + } + if (pathNlriDetails2 == null || pathNlriDetails2.isLocalRibIbgpSession()) { + return 1; + } + } + // prefer lowest BGP identifier value. + if (pathNlriDetails1.localRibIdentifier() != pathNlriDetails2.localRibIdentifier()) { + return ((Integer) pathNlriDetails2.localRibIdentifier()) + .compareTo(pathNlriDetails1.localRibIdentifier()); + } + //prefer lowest peer address + if (pathNlriDetails1.localRibIpAddress() != pathNlriDetails2.localRibIpAddress()) { + return pathNlriDetails2.localRibIpAddress().compareTo(pathNlriDetails1.localRibIpAddress()); + } + return 0; + } + + /** + * Returns ASes count of AsPath attribute , if AS_SET is present then count as 1. + * + * @param aspath object of AsPath + * @return count of ASes + */ + Integer countASSize(AsPath aspath) { + boolean isASSet = false; + int count = 0; + if (!aspath.asPathSet().isEmpty()) { + isASSet = true; + } + if (!aspath.asPathSeq().isEmpty()) { + count = aspath.asPathSeq().size(); + } + return isASSet ? ++count : count; + } + + /** + * Stores BGP basic attributes of two objects. + * + * @param listIteratorObj1 list iterator of object1 + * @param listIteratorObj2 list iterator of object2 + */ + void storeAttr(ListIterator listIteratorObj1, ListIterator listIteratorObj2) { + while (listIteratorObj1.hasNext()) { + BgpValueType pathAttributeObj1 = listIteratorObj1.next(); + switch (pathAttributeObj1.getType()) { + case LocalPref.LOCAL_PREF_TYPE: + obj1LocPref = (LocalPref) pathAttributeObj1; + break; + case AsPath.ASPATH_TYPE: + obj1Aspath = (AsPath) pathAttributeObj1; + break; + case Origin.ORIGIN_TYPE: + obj1Origin = (Origin) pathAttributeObj1; + break; + case Med.MED_TYPE: + obj1Med = (Med) pathAttributeObj1; + break; + default: + log.debug("Got other type, Not required: " + pathAttributeObj1.getType()); + } + } + while (listIteratorObj2.hasNext()) { + BgpValueType pathAttributeObj2 = listIteratorObj2.next(); + switch (pathAttributeObj2.getType()) { + case LocalPref.LOCAL_PREF_TYPE: + obj2LocPref = (LocalPref) pathAttributeObj2; + break; + case AsPath.ASPATH_TYPE: + obj2Aspath = (AsPath) pathAttributeObj2; + break; + case Origin.ORIGIN_TYPE: + obj2Origin = (Origin) pathAttributeObj2; + break; + case Med.MED_TYPE: + obj2Med = (Med) pathAttributeObj2; + break; + default: + log.debug("Got other type, Not required: " + pathAttributeObj2.getType()); + } + } + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java new file mode 100755 index 00000000..33623dc2 --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java @@ -0,0 +1,93 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onosproject.bgp.controller.impl; + +import org.onosproject.bgp.controller.BgpId; +import org.onosproject.bgp.controller.BgpSessionInfo; +import org.onosproject.bgpio.protocol.BgpVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class maintains BGP peer session info. + */ +public class BgpSessionInfoImpl implements BgpSessionInfo { + + protected final Logger log = LoggerFactory.getLogger(BgpSessionInfoImpl.class); + private BgpId remoteBgpId; + private BgpVersion remoteBgpVersion; + private long remoteBgpASNum; + private short remoteBgpholdTime; + private int remoteBgpIdentifier; + private short negotiatedholdTime; + private boolean isIbgpSession; + + /** + * Initialize session info. + * + *@param remoteBgpId remote peer id + *@param remoteBgpVersion remote peer version + *@param remoteBgpASNum remote peer AS number + *@param remoteBgpholdTime remote peer hold time + *@param remoteBgpIdentifier remote peer identifier + *@param negotiatedholdTime negotiated hold time + *@param isIbgpSession session type ibgp/ebgp + */ + public BgpSessionInfoImpl(BgpId remoteBgpId, BgpVersion remoteBgpVersion, long remoteBgpASNum, + short remoteBgpholdTime, int remoteBgpIdentifier, short negotiatedholdTime, + boolean isIbgpSession) { + this.remoteBgpId = remoteBgpId; + this.remoteBgpVersion = remoteBgpVersion; + this.remoteBgpASNum = remoteBgpASNum; + this.remoteBgpholdTime = remoteBgpholdTime; + this.remoteBgpIdentifier = remoteBgpIdentifier; + this.negotiatedholdTime = negotiatedholdTime; + this.isIbgpSession = isIbgpSession; + } + + @Override + public boolean isIbgpSession() { + return isIbgpSession; + } + + @Override + public short negotiatedholdTime() { + return negotiatedholdTime; + } + + @Override + public BgpId remoteBgpId() { + return remoteBgpId; + } + + @Override + public BgpVersion remoteBgpVersion() { + return remoteBgpVersion; + } + + @Override + public long remoteBgpASNum() { + return remoteBgpASNum; + } + + @Override + public short remoteBgpHoldTime() { + return remoteBgpholdTime; + } + + @Override + public int remoteBgpIdentifier() { + return remoteBgpIdentifier; + } +} diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java index 017c39e5..f02cee8a 100755 --- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java @@ -26,15 +26,16 @@ import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.group.ChannelGroup; import org.jboss.netty.channel.group.DefaultChannelGroup; import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; -import org.onosproject.bgp.controller.BGPController; -import org.onosproject.bgpio.protocol.BGPFactories; -import org.onosproject.bgpio.protocol.BGPFactory; -import org.onosproject.bgpio.protocol.BGPVersion; +import org.onosproject.bgp.controller.BgpController; +import org.onosproject.bgpio.protocol.BgpFactories; +import org.onosproject.bgpio.protocol.BgpFactory; +import org.onosproject.bgpio.protocol.BgpVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,12 +47,15 @@ public class Controller { private static final Logger log = LoggerFactory.getLogger(Controller.class); - private static final BGPFactory FACTORY4 = BGPFactories.getFactory(BGPVersion.BGP_4); + private static final BgpFactory FACTORY4 = BgpFactories.getFactory(BgpVersion.BGP_4); private ChannelGroup cg; + public Channel serverChannel; // Configuration options private static final short BGP_PORT_NUM = 179; + private static final short PORT_NUM_ZERO = 0; + private static boolean isPortNumSet = false; private final int workerThreads = 16; private final int peerWorkerThreads = 16; @@ -61,7 +65,7 @@ public class Controller { private NioServerSocketChannelFactory serverExecFactory; private NioClientSocketChannelFactory peerExecFactory; private static ClientBootstrap peerBootstrap; - private BGPController bgpController; + private BgpController bgpController; // Perf. related configuration private static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024; @@ -71,7 +75,7 @@ public class Controller { * * @param bgpController bgp controller instance */ - public Controller(BGPController bgpController) { + public Controller(BgpController bgpController) { this.bgpController = bgpController; } @@ -80,7 +84,7 @@ public class Controller { * * @return instance of factory version */ - static BGPFactory getBGPMessageFactory4() { + static BgpFactory getBgpMessageFactory4() { return FACTORY4; } @@ -114,12 +118,13 @@ public class Controller { bootstrap.setOption("child.tcpNoDelay", true); bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE); - ChannelPipelineFactory pfact = new BGPPipelineFactory(bgpController, true); + ChannelPipelineFactory pfact = new BgpPipelineFactory(bgpController, true); bootstrap.setPipelineFactory(pfact); InetSocketAddress sa = new InetSocketAddress(getBgpPortNum()); cg = new DefaultChannelGroup(); - cg.add(bootstrap.bind(sa)); + serverChannel = bootstrap.bind(sa); + cg.add(serverChannel); log.info("Listening for Peer connection on {}", sa); } catch (Exception e) { throw new RuntimeException(e); @@ -234,6 +239,16 @@ public class Controller { * @return port number */ public static short getBgpPortNum() { + if (isPortNumSet) { + return PORT_NUM_ZERO; + } return BGP_PORT_NUM; } + + /** + * sets the isPortNumSet as true. + */ + public void setBgpPortNum() { + isPortNumSet = true; + } } \ No newline at end of file diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/VpnAdjRibIn.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/VpnAdjRibIn.java new file mode 100644 index 00000000..8a9ea91c --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/VpnAdjRibIn.java @@ -0,0 +1,209 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.bgp.controller.impl; + +import java.util.Map; +import java.util.TreeMap; + +import org.onosproject.bgpio.protocol.BgpLSNlri; +import org.onosproject.bgpio.protocol.linkstate.BgpLinkLSIdentifier; +import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSIdentifier; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4; +import org.onosproject.bgpio.protocol.linkstate.BgpPrefixLSIdentifier; +import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails; +import org.onosproject.bgpio.types.RouteDistinguisher; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of Adj-RIB-In with VPN for each peer. + */ +public class VpnAdjRibIn { + private Map nodeTree = new TreeMap<>(); + private Map linkTree = new TreeMap<>(); + private Map prefixTree = new TreeMap<>(); + + private Map> vpnNodeTree + = new TreeMap<>(); + private Map> vpnLinkTree + = new TreeMap<>(); + private Map> vpnPrefixTree + = new TreeMap<>(); + /** + * Returns the adjacency node. + * + * @return node adjacency RIB node + */ + public Map nodeTree() { + return nodeTree; + } + + /** + * Returns the adjacency link. + * + * @return link adjacency RIB node + */ + public Map linkTree() { + return linkTree; + } + + /** + * Returns the adjacency prefix. + * + * @return prefix adjacency RIB node + */ + public Map prefixTree() { + return prefixTree; + } + + /** + * Returns the adjacency vpnNode. + * + * @return vpnNode adjacency RIB node + */ + public Map> vpnNodeTree() { + return vpnNodeTree; + } + + /** + * Returns the adjacency vpnLink. + * + * @return vpnLink adjacency RIB node + */ + public Map> vpnLinkTree() { + return vpnLinkTree; + } + + /** + * Returns the adjacency vpnPrefix. + * + * @return vpnPrefix adjacency RIB node + */ + public Map> vpnPrefixTree() { + return vpnPrefixTree; + } + + /** + * Update vpn nlri identifier into the tree if nlri identifier exists in tree otherwise add this to the tree. + * + * @param nlri NLRI info + * @param details has pathattribute , protocolID and identifier + */ + public void add(BgpLSNlri nlri, PathAttrNlriDetails details) { + if (nlri instanceof BgpNodeLSNlriVer4) { + BgpNodeLSIdentifier nodeLSIdentifier = ((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors(); + if (nodeTree.containsKey(nodeLSIdentifier)) { + nodeTree.replace(nodeLSIdentifier, details); + } else { + nodeTree.put(nodeLSIdentifier, details); + } + } else if (nlri instanceof BgpLinkLsNlriVer4) { + BgpLinkLSIdentifier linkLSIdentifier = ((BgpLinkLsNlriVer4) nlri).getLinkIdentifier(); + if (linkTree.containsKey(linkLSIdentifier)) { + linkTree.replace(linkLSIdentifier, details); + } else { + linkTree.put(linkLSIdentifier, details); + } + } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) { + BgpPrefixLSIdentifier prefixIdentifier = ((BgpPrefixIPv4LSNlriVer4) nlri).getPrefixIdentifier(); + if (prefixTree.containsKey(prefixIdentifier)) { + prefixTree.replace(prefixIdentifier, details); + } else { + prefixTree.put(prefixIdentifier, details); + } + } + } + + /** + * Update nlri identifier mapped with route distinguisher if it exists in tree otherwise add nlri infomation mapped + * to respective route distinguisher in tree. + * + * @param nlri NLRI info + * @param details has pathattribute , protocolID and identifier + * @param routeDistinguisher unique for for each vpn + */ + public void addVpn(BgpLSNlri nlri, PathAttrNlriDetails details, RouteDistinguisher routeDistinguisher) { + add(nlri, details); + if (nlri instanceof BgpNodeLSNlriVer4) { + if (!vpnNodeTree.containsKey(routeDistinguisher)) { + vpnNodeTree.put(routeDistinguisher, nodeTree); + } + } else if (nlri instanceof BgpLinkLsNlriVer4) { + if (!vpnLinkTree.containsKey(routeDistinguisher)) { + vpnLinkTree.put(routeDistinguisher, linkTree); + } + } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) { + if (!vpnPrefixTree.containsKey(routeDistinguisher)) { + vpnPrefixTree.put(routeDistinguisher, prefixTree); + } + } + } + + /** + * Removes vpn nlri identifier mapped to route distinguisher if it exists in tree. + * + * @param nlri NLRI Info + * @param routeDistinguisher unique for for each vpn + */ + public void removeVpn(BgpLSNlri nlri, RouteDistinguisher routeDistinguisher) { + if (nlri instanceof BgpNodeLSNlriVer4) { + if (vpnNodeTree.containsKey(routeDistinguisher)) { + BgpNodeLSIdentifier nodeLSIdentifier = ((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors(); + if (nodeTree.containsKey(nodeLSIdentifier)) { + nodeTree.remove(nodeLSIdentifier); + } + if ((vpnNodeTree.get(routeDistinguisher)).isEmpty()) { + vpnNodeTree.remove(routeDistinguisher); + } + } + } else if (nlri instanceof BgpLinkLsNlriVer4) { + if (vpnLinkTree.containsKey(routeDistinguisher)) { + BgpLinkLSIdentifier linkLSIdentifier = ((BgpLinkLsNlriVer4) nlri).getLinkIdentifier(); + if (linkTree.containsKey(linkLSIdentifier)) { + linkTree.remove(linkLSIdentifier); + } + if ((vpnLinkTree.get(routeDistinguisher)).isEmpty()) { + vpnLinkTree.remove(routeDistinguisher); + } + } + } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) { + if (vpnPrefixTree.containsKey(routeDistinguisher)) { + BgpPrefixLSIdentifier prefixIdentifier = ((BgpPrefixIPv4LSNlriVer4) nlri).getPrefixIdentifier(); + if (prefixTree.containsKey(prefixIdentifier)) { + prefixTree.remove(prefixIdentifier); + } + if ((vpnPrefixTree.get(routeDistinguisher)).isEmpty()) { + vpnPrefixTree.remove(routeDistinguisher); + } + } + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues().add("nodeTree", nodeTree) + .add("linkTree", linkTree) + .add("prefixTree", prefixTree) + .add("vpnNodeTree", vpnNodeTree) + .add("vpnLinkTree", vpnLinkTree) + .add("vpnPrefixTree", vpnPrefixTree) + .toString(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java new file mode 100755 index 00000000..36b1d6fc --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java @@ -0,0 +1,300 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgp; + +import com.google.common.net.InetAddresses; +import org.jboss.netty.bootstrap.ClientBootstrap; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFactory; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +import org.onlab.junit.TestUtils; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.LinkedList; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.onosproject.bgp.controller.BgpCfg; +import org.onosproject.bgp.controller.impl.BgpControllerImpl; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv; +import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv; + +/** + * Test case for BGPControllerImpl. + */ +public class BgpControllerImplTest { + + protected static final Logger log = LoggerFactory + .getLogger(BgpControllerImplTest.class); + + private static final String IP_LOOPBACK_ID1 = "127.0.0.1"; + + private static final int MESSAGE_TIMEOUT_MS = 3000; + public byte version; + public short asNumber; + public short holdTime; + public int bgpId = InetAddresses.coerceToInteger(InetAddresses.forString(IP_LOOPBACK_ID1)); + public boolean isLargeAsCapabilitySet = false; + public LinkedList capabilityTlv = new LinkedList<>(); + + @Before + public void setUp() throws Exception { + peer1 = new BgpPeerTest(version, asNumber, + holdTime, bgpId, isLargeAsCapabilitySet, + capabilityTlv); + + bgpControllerImpl = new BgpControllerImpl(); + + // NOTE: We use port 0 to bind on any available port + bgpControllerImpl.controller().setBgpPortNum(); + bgpControllerImpl.activate(); + + Channel serverChannel = TestUtils.getField(bgpControllerImpl.controller(), + "serverChannel"); + SocketAddress socketAddress = serverChannel.getLocalAddress(); + InetSocketAddress inetSocketAddress = + (InetSocketAddress) socketAddress; + InetAddress connectToAddress = InetAddresses.forString("127.0.0.1"); + connectToSocket = new InetSocketAddress(connectToAddress, + inetSocketAddress.getPort()); + + bgpControllerImpl.getConfig().setRouterId("1.1.1.1"); + bgpControllerImpl.getConfig().setAsNumber(200); + bgpControllerImpl.getConfig().setHoldTime((short) 120); + bgpControllerImpl.getConfig().setState(BgpCfg.State.IP_AS_CONFIGURED); + + bgpControllerImpl.getConfig().addPeer("127.0.0.1", 200); + } + + @After + public void tearDown() throws Exception { + bgpControllerImpl.deactivate(); + bgpControllerImpl = null; + } + + private BgpControllerImpl bgpControllerImpl; + + BgpPeerTest peer1; + + // The socket that the remote peers should connect to + private InetSocketAddress connectToSocket; + + @Test + public void bgpOpenMessageTest1() throws InterruptedException { + peer1.peerChannelHandler.asNumber = 200; + peer1.peerChannelHandler.version = 4; + peer1.peerChannelHandler.holdTime = 120; + peer1.connect(connectToSocket); + boolean result; + result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + } + + @Test + public void bgpOpenMessageTest2() throws InterruptedException { + // Open message with as number which is not configured at peer + peer1.peerChannelHandler.asNumber = 500; + peer1.peerChannelHandler.version = 4; + peer1.peerChannelHandler.holdTime = 120; + peer1.connect(connectToSocket); + + boolean result; + result = peer1.peerFrameDecoder.receivedNotificationMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + } + + @Test + public void bgpOpenMessageTest3() throws InterruptedException { + // Open message with invalid hold time value + peer1.peerChannelHandler.asNumber = 200; + peer1.peerChannelHandler.version = 4; + peer1.peerChannelHandler.holdTime = 1; + peer1.connect(connectToSocket); + + boolean result; + result = peer1.peerFrameDecoder.receivedNotificationMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + } + + @Test + public void bgpOpenMessageTest4() throws InterruptedException { + // Open message with invalid as number + peer1.peerChannelHandler.asNumber = 200; + peer1.peerChannelHandler.version = 4; + peer1.peerChannelHandler.holdTime = 120; + peer1.peerChannelHandler.isLargeAsCapabilitySet = true; + BgpValueType tempTlv = new FourOctetAsNumCapabilityTlv(766545); + peer1.peerChannelHandler.capabilityTlv.add(tempTlv); + peer1.connect(connectToSocket); + + boolean result; + result = peer1.peerFrameDecoder.receivedNotificationMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + } + + @Test + public void bgpOpenMessageTest5() throws InterruptedException { + // Open message with LS capability + short afi = 16388; + byte res = 0; + byte safi = 71; + peer1.peerChannelHandler.asNumber = 200; + peer1.peerChannelHandler.version = 4; + peer1.peerChannelHandler.holdTime = 120; + bgpControllerImpl.getConfig().setLsCapability(true); + BgpValueType tempTlv1 = new MultiProtocolExtnCapabilityTlv(afi, res, safi); + peer1.peerChannelHandler.capabilityTlv.add(tempTlv1); + peer1.connect(connectToSocket); + + boolean result; + result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + } + + @Test + public void bgpOpenMessageTest6() throws InterruptedException { + // Open message with as4 capability + peer1.peerChannelHandler.asNumber = 200; + peer1.peerChannelHandler.version = 4; + peer1.peerChannelHandler.holdTime = 120; + peer1.peerChannelHandler.isLargeAsCapabilitySet = true; + bgpControllerImpl.getConfig().setLargeASCapability(true); + BgpValueType tempTlv = new FourOctetAsNumCapabilityTlv(200); + peer1.peerChannelHandler.capabilityTlv.add(tempTlv); + peer1.connect(connectToSocket); + + boolean result; + result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + + result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + } + + @Test + public void bgpOpenMessageTest7() throws InterruptedException { + // Open message with both LS capability and as4 capability + short afi = 16388; + byte res = 0; + byte safi = 71; + peer1.peerChannelHandler.asNumber = 200; + peer1.peerChannelHandler.version = 4; + peer1.peerChannelHandler.holdTime = 120; + + peer1.peerChannelHandler.isLargeAsCapabilitySet = true; + bgpControllerImpl.getConfig().setLargeASCapability(true); + BgpValueType tempTlv = new FourOctetAsNumCapabilityTlv(200); + peer1.peerChannelHandler.capabilityTlv.add(tempTlv); + + bgpControllerImpl.getConfig().setLsCapability(true); + BgpValueType tempTlv1 = new MultiProtocolExtnCapabilityTlv(afi, res, safi); + peer1.peerChannelHandler.capabilityTlv.add(tempTlv1); + peer1.connect(connectToSocket); + + boolean result; + result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await( + MESSAGE_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + assertThat(result, is(true)); + } + + /** + * A class to capture the state for a BGP peer. + */ + private final class BgpPeerTest { + private ClientBootstrap peerBootstrap; + private BgpPeerFrameDecoderTest peerFrameDecoder = + new BgpPeerFrameDecoderTest(); + private BgpPeerChannelHandlerTest peerChannelHandler; + + private BgpPeerTest(byte version, short asNumber, + short holdTime, int bgpId, boolean isLargeAsCapabilitySet, + LinkedList capabilityTlv) { + peerChannelHandler = new BgpPeerChannelHandlerTest(version, + asNumber, holdTime, bgpId, isLargeAsCapabilitySet, capabilityTlv); + } + + /** + * Starts the BGP peer. + * + * @param connectToSocket the socket to connect to + */ + private void connect(InetSocketAddress connectToSocket) + throws InterruptedException { + + ChannelFactory channelFactory = + new NioClientSocketChannelFactory( + Executors.newCachedThreadPool(), + Executors.newCachedThreadPool()); + ChannelPipelineFactory pipelineFactory = () -> { + ChannelPipeline pipeline = Channels.pipeline(); + pipeline.addLast("BgpPeerFrameDecoderTest", + peerFrameDecoder); + pipeline.addLast("BgpPeerChannelHandlerTest", + peerChannelHandler); + return pipeline; + }; + + peerBootstrap = new ClientBootstrap(channelFactory); + peerBootstrap.setOption("child.keepAlive", true); + peerBootstrap.setOption("child.tcpNoDelay", true); + peerBootstrap.setPipelineFactory(pipelineFactory); + peerBootstrap.connect(connectToSocket); + } + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerChannelHandlerTest.java b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerChannelHandlerTest.java new file mode 100755 index 00000000..26ed36d8 --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerChannelHandlerTest.java @@ -0,0 +1,107 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgp; + +import java.util.LinkedList; +import java.util.concurrent.TimeUnit; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.SimpleChannelHandler; +import org.onosproject.bgpio.protocol.ver4.BgpKeepaliveMsgVer4; +import org.onosproject.bgpio.protocol.ver4.BgpOpenMsgVer4; +import org.onosproject.bgpio.types.BgpHeader; +import org.onosproject.bgpio.types.BgpValueType; + +public class BgpPeerChannelHandlerTest extends SimpleChannelHandler { + public static final int OPEN_MSG_MINIMUM_LENGTH = 29; + public static final byte[] MARKER = new byte[] {(byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff}; + public static final BgpHeader DEFAULT_OPEN_HEADER = new BgpHeader(MARKER, + (short) OPEN_MSG_MINIMUM_LENGTH, (byte) 0X01); + LinkedList capabilityTlv = new LinkedList<>(); + public byte version; + public short asNumber; + public short holdTime; + public int bgpId; + public boolean isLargeAsCapabilitySet; + + final BgpOpenMsgVer4 openMessage = new BgpOpenMsgVer4(); + ChannelHandlerContext savedCtx; + + /** + * Constructor to initialize all variables of BGP Open message. + * + * @param version BGP version in open message + * @param asNumber AS number in open message + * @param holdTime hold time in open message + * @param bgpId BGP identifier in open message + * @param capabilityTlv capabilities in open message + */ + public BgpPeerChannelHandlerTest(byte version, + short asNumber, + short holdTime, + int bgpId, + boolean isLargeAsCapabilitySet, + LinkedList capabilityTlv) { + this.version = version; + this.asNumber = asNumber; + this.holdTime = holdTime; + this.bgpId = bgpId; + this.isLargeAsCapabilitySet = isLargeAsCapabilitySet; + this.capabilityTlv = capabilityTlv; + } + + /** + * closes the channel. + */ + void closeChannel() { + savedCtx.getChannel().close(); + } + + @Override + public void channelConnected(ChannelHandlerContext ctx, + ChannelStateEvent channelEvent) throws InterruptedException { + this.savedCtx = ctx; + + BgpOpenMsgVer4 openMsg = new BgpOpenMsgVer4(DEFAULT_OPEN_HEADER, + this.version, + this.asNumber, + this.holdTime, + this.bgpId, + this.capabilityTlv); + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + openMsg.writeTo(buffer); + ctx.getChannel().write(buffer); + + TimeUnit.MILLISECONDS.sleep(100); + + BgpKeepaliveMsgVer4 keepaliveMsg = new BgpKeepaliveMsgVer4(); + ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer(); + keepaliveMsg.writeTo(buffer1); + ctx.getChannel().write(buffer1); + } + + @Override + public void channelDisconnected(ChannelHandlerContext ctx, + ChannelStateEvent channelEvent) { + //Do Nothing + } +} diff --git a/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerFrameDecoderTest.java b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerFrameDecoderTest.java new file mode 100755 index 00000000..7767053f --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerFrameDecoderTest.java @@ -0,0 +1,168 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.bgp; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.concurrent.CountDownLatch; + +/** + * Class to decode the message received. + */ +public class BgpPeerFrameDecoderTest extends FrameDecoder { + static final byte OPEN_MSG_TYPE = 0x1; + static final byte KEEPALIVE_MSG_TYPE = 0x4; + static final byte UPDATE_MSG_TYPE = 0x2; + static final byte NOTIFICATION_MSG_TYPE = 0x3; + static final int MINIMUM_COMMON_HEADER_LENGTH = 19; + static final int MINIMUM_OPEN_MSG_LENGTH = 29; + static final int MINIMUM_HEADER_MARKER_LENGTH = 16; + static final int HEADER_AND_MSG_LEN = 18; + + protected static final Logger log = LoggerFactory + .getLogger(BgpPeerFrameDecoderTest.class); + final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1); + final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1); + final CountDownLatch receivedNotificationMessageLatch = new CountDownLatch(1); + + @Override + protected Object decode(ChannelHandlerContext ctx, + Channel channel, + ChannelBuffer cb) throws Exception { + + if (cb.readableBytes() < MINIMUM_COMMON_HEADER_LENGTH) { + log.debug("Error: Packet length is less then minimum length"); + return null; + } + + byte[] marker = new byte[MINIMUM_HEADER_MARKER_LENGTH]; + cb.readBytes(marker); + for (int i = 0; i < marker.length; i++) { + if (marker[i] != (byte) 0xff) { + log.debug("Error: Marker must be set all ones"); + ctx.getChannel().close(); + return null; + } + } + + short length = cb.readShort(); + if (length < MINIMUM_COMMON_HEADER_LENGTH) { + log.debug("Error: Bad message length"); + ctx.getChannel().close(); + return null; + } + + if (length != (cb.readableBytes() + HEADER_AND_MSG_LEN)) { + log.debug("Error: Bad message length"); + ctx.getChannel().close(); + return null; + } + + byte type = cb.readByte(); + int len = length - MINIMUM_COMMON_HEADER_LENGTH; + + ChannelBuffer message = cb.readBytes(len); + + switch (type) { + case OPEN_MSG_TYPE: + processBgpOpen(ctx, message); + break; + case UPDATE_MSG_TYPE: + break; + case NOTIFICATION_MSG_TYPE: + processBgpNotification(ctx, message); + break; + case KEEPALIVE_MSG_TYPE: + processBgpKeepalive(ctx, message); + break; + default: + ctx.getChannel().close(); + return null; + } + + return null; + } + + /** + * Processes BGP open message. + * + * @param ctx Channel handler context + * @param message open message + */ + private void processBgpOpen(ChannelHandlerContext ctx, + ChannelBuffer message) { + int minLength = + MINIMUM_OPEN_MSG_LENGTH - MINIMUM_COMMON_HEADER_LENGTH; + if (message.readableBytes() < minLength) { + log.debug("Error: Bad message length"); + ctx.getChannel().close(); + return; + } + + message.readByte(); // read version + message.readShort(); // read AS number + message.readShort(); // read Hold timer + message.readInt(); // read BGP Identifier + // Optional Parameters + int optParamLen = message.readUnsignedByte(); + if (message.readableBytes() < optParamLen) { + log.debug("Error: Bad message length"); + ctx.getChannel().close(); + return; + } + message.readBytes(optParamLen); + + // Open message received + receivedOpenMessageLatch.countDown(); + } + + /** + * Processes BGP keepalive message. + * + * @param ctx Channel handler context + * @param message keepalive message + */ + private void processBgpKeepalive(ChannelHandlerContext ctx, + ChannelBuffer message) { + + // Keepalive message received + receivedKeepaliveMessageLatch.countDown(); + } + + /** + * Processes BGP notification message. + * + * @param ctx Channel handler context + * @param message notification message + */ + private void processBgpNotification(ChannelHandlerContext ctx, + ChannelBuffer message) { + byte[] data; + message.readByte(); //read error code + message.readByte(); // read error sub code + if (message.readableBytes() > 0) { + data = new byte[message.readableBytes()]; + message.readBytes(data, 0, message.readableBytes()); + } + + // Notification message received + receivedNotificationMessageLatch.countDown(); + } +} \ No newline at end of file diff --git a/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/controller/impl/BgpSelectionAlgoTest.java b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/controller/impl/BgpSelectionAlgoTest.java new file mode 100644 index 00000000..7c0fa417 --- /dev/null +++ b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/controller/impl/BgpSelectionAlgoTest.java @@ -0,0 +1,595 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.controller.impl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpAddress.Version; +import org.onosproject.bgpio.exceptions.BgpParseException; +import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType; +import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails; +import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetailsLocalRib; +import org.onosproject.bgpio.types.AsPath; +import org.onosproject.bgpio.types.BgpValueType; +import org.onosproject.bgpio.types.LocalPref; +import org.onosproject.bgpio.types.Med; +import org.onosproject.bgpio.types.Origin; +import org.onosproject.bgp.controller.impl.BgpSelectionAlgo; + +/** + * Test cases for BGP Selection Algorithm. + */ +public class BgpSelectionAlgoTest { + + /** + * firstPathAttribute and secondPathAttribute has same AS count and firstPathAttribute + * has shortest Origin value than secondPathAttribute. + */ + @Test + public void selectionAlgoTest1() throws BgpParseException { + byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a }; + LinkedList pathAttributes1 = new LinkedList<>(); + BgpValueType pathAttribute1; + //origin with IGP + byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute1 = Origin.read(buffer); + pathAttributes1.add(pathAttribute1); + //AsPath with AS_SEQ with one AS + byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xea }; + buffer.writeBytes(asPath); + pathAttribute1 = AsPath.read(buffer); + pathAttributes1.add(pathAttribute1); + + IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp); + int bgpId = 168427777; + short locRIBASNum = 100; + boolean isIbgp = false; + PathAttrNlriDetails attrList1 = new PathAttrNlriDetails(); + attrList1.setIdentifier(0); + attrList1.setPathAttribute(pathAttributes1); + attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE); + PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList1); + + peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b }; + LinkedList pathAttributes2 = new LinkedList<>(); + BgpValueType pathAttribute2; + //origin with INCOMPLETE + origin = new byte[] {0x40, 0x01, 0x01, 0x02 }; + buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute2 = Origin.read(buffer); + pathAttributes2.add(pathAttribute2); + //AsPath with AS_SEQ with one AS + asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute2 = AsPath.read(buffer); + pathAttributes2.add(pathAttribute2); + + ipAddress = IpAddress.valueOf(Version.INET, peerIp); + bgpId = 536936448; + locRIBASNum = 200; + isIbgp = true; + PathAttrNlriDetails attrList2 = new PathAttrNlriDetails(); + attrList2.setIdentifier(0); + attrList2.setPathAttribute(pathAttributes2); + attrList2.setProtocolID(ProtocolType.OSPF_V2); + PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList2); + BgpSelectionAlgo algo = new BgpSelectionAlgo(); + int result = algo.compare(list1, list2); + assertThat(result, is(1)); + } + + /** + * firstPathAttribute has 1 AS count and secondPathAttribute has 2 AS count + * and firstPathAttribute has shortest Origin value than secondPathAttribute. + */ + @Test + public void selectionAlgoTest2() throws BgpParseException { + + byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a }; + LinkedList pathAttributes1 = new LinkedList<>(); + BgpValueType pathAttribute1; + byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute1 = Origin.read(buffer); + pathAttributes1.add(pathAttribute1); + byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute1 = AsPath.read(buffer); + pathAttributes1.add(pathAttribute1); + + IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp); + int bgpId = 168427777; + short locRIBASNum = 100; + boolean isIbgp = false; + PathAttrNlriDetails attrList1 = new PathAttrNlriDetails(); + attrList1.setIdentifier(0); + attrList1.setPathAttribute(pathAttributes1); + attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE); + PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList1); + + peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b }; + LinkedList pathAttributes2 = new LinkedList<>(); + BgpValueType pathAttribute2; + origin = new byte[] {0x40, 0x01, 0x01, 0x02 }; + buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute2 = Origin.read(buffer); + pathAttributes2.add(pathAttribute2); + asPath = new byte[] {0x40, 0x02, 0x08, 0x02, 0x01, (byte) 0xfd, + (byte) 0xea, 0x02, 0x01, (byte) 0xfd, (byte) 0xea }; + buffer.writeBytes(asPath); + pathAttribute2 = AsPath.read(buffer); + pathAttributes2.add(pathAttribute2); + + ipAddress = IpAddress.valueOf(Version.INET, peerIp); + bgpId = 536936448; + locRIBASNum = 200; + isIbgp = true; + PathAttrNlriDetails attrList2 = new PathAttrNlriDetails(); + attrList2.setIdentifier(0); + attrList2.setPathAttribute(pathAttributes2); + attrList2.setProtocolID(ProtocolType.OSPF_V2); + PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList2); + BgpSelectionAlgo algo = new BgpSelectionAlgo(); + int result = algo.compare(list1, list2); + assertThat(result, is(-1)); + } + + /** + * firstPathAttribute and secondPathAttribute has same AS value + * and firstPathAttribute has shortest Origin value than secondPathAttribute. + */ + @Test + public void selectionAlgoTest3() throws BgpParseException { + + byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a }; + LinkedList pathAttributes1 = new LinkedList<>(); + BgpValueType pathAttribute1; + byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute1 = Origin.read(buffer); + pathAttributes1.add(pathAttribute1); + byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute1 = AsPath.read(buffer); + pathAttributes1.add(pathAttribute1); + + IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp); + int bgpId = 168427777; + short locRIBASNum = 100; + boolean isIbgp = false; + PathAttrNlriDetails attrList1 = new PathAttrNlriDetails(); + attrList1.setIdentifier(0); + attrList1.setPathAttribute(pathAttributes1); + attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE); + PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList1); + + peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b }; + LinkedList pathAttributes2 = new LinkedList<>(); + BgpValueType pathAttribute2; + origin = new byte[] {0x40, 0x01, 0x01, 0x02 }; + buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute2 = Origin.read(buffer); + pathAttributes2.add(pathAttribute2); + asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute2 = AsPath.read(buffer); + pathAttributes2.add(pathAttribute2); + + ipAddress = IpAddress.valueOf(Version.INET, peerIp); + bgpId = 536936448; + locRIBASNum = 200; + isIbgp = true; + PathAttrNlriDetails attrList2 = new PathAttrNlriDetails(); + attrList2.setIdentifier(0); + attrList2.setPathAttribute(pathAttributes2); + attrList2.setProtocolID(ProtocolType.OSPF_V2); + PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList2); + BgpSelectionAlgo algo = new BgpSelectionAlgo(); + int result = algo.compare(list1, list2); + assertThat(result, is(1)); + } + + /** + * firstPathAttribute has lowest med than secondPathAttribute. + */ + @Test + public void selectionAlgoTest4() throws BgpParseException { + + byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a }; + LinkedList pathAttributes1 = new LinkedList<>(); + BgpValueType pathAttribute1; + byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute1 = Origin.read(buffer); + pathAttributes1.add(pathAttribute1); + byte[] med = new byte[] {(byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, + 0x00 }; + buffer.writeBytes(med); + pathAttribute1 = Med.read(buffer); + pathAttributes1.add(pathAttribute1); + byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute1 = AsPath.read(buffer); + pathAttributes1.add(pathAttribute1); + + IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp); + int bgpId = 168427777; + short locRIBASNum = 100; + boolean isIbgp = false; + PathAttrNlriDetails attrList1 = new PathAttrNlriDetails(); + attrList1.setIdentifier(0); + attrList1.setPathAttribute(pathAttributes1); + attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE); + PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList1); + + peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b }; + LinkedList pathAttributes2 = new LinkedList<>(); + BgpValueType pathAttribute2; + origin = new byte[] {0x40, 0x01, 0x01, 0x02 }; + buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute2 = Origin.read(buffer); + pathAttributes2.add(pathAttribute2); + med = new byte[] {(byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01 }; + buffer.writeBytes(med); + pathAttribute2 = Med.read(buffer); + pathAttributes2.add(pathAttribute2); + asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute2 = AsPath.read(buffer); + pathAttributes2.add(pathAttribute2); + + ipAddress = IpAddress.valueOf(Version.INET, peerIp); + bgpId = 536936448; + locRIBASNum = 200; + isIbgp = true; + PathAttrNlriDetails attrList2 = new PathAttrNlriDetails(); + attrList2.setIdentifier(0); + attrList2.setPathAttribute(pathAttributes2); + attrList2.setProtocolID(ProtocolType.OSPF_V2); + PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList2); + BgpSelectionAlgo algo = new BgpSelectionAlgo(); + int result = algo.compare(list1, list2); + assertThat(result, is(1)); + } + + /** + * secondPathAttribute has higher local preference than firstPathAttribute. + */ + @Test + public void selectionAlgoTest5() throws BgpParseException { + + byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a }; + LinkedList pathAttributes1 = new LinkedList<>(); + BgpValueType pathAttribute1; + byte[] locPref = new byte[] {(byte) 0x00, 0x05, 0x04, 0x00, 0x00, + 0x00, 0x01 }; + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(locPref); + pathAttribute1 = LocalPref.read(buffer); + pathAttributes1.add(pathAttribute1); + + IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp); + int bgpId = 168427777; + short locRIBASNum = 100; + boolean isIbgp = false; + PathAttrNlriDetails attrList1 = new PathAttrNlriDetails(); + attrList1.setIdentifier(0); + attrList1.setPathAttribute(pathAttributes1); + attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE); + PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList1); + + peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b }; + LinkedList pathAttributes2 = new LinkedList<>(); + BgpValueType pathAttribute2; + locPref = new byte[] {(byte) 0x00, 0x05, 0x04, 0x00, 0x00, 0x00, 0x0a }; + buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(locPref); + pathAttribute2 = LocalPref.read(buffer); + pathAttributes2.add(pathAttribute2); + + ipAddress = IpAddress.valueOf(Version.INET, peerIp); + bgpId = 536936448; + locRIBASNum = 200; + isIbgp = true; + PathAttrNlriDetails attrList2 = new PathAttrNlriDetails(); + attrList2.setIdentifier(0); + attrList2.setPathAttribute(pathAttributes2); + attrList2.setProtocolID(ProtocolType.OSPF_V2); + PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList2); + BgpSelectionAlgo algo = new BgpSelectionAlgo(); + int result = algo.compare(list1, list2); + assertThat(result, is(-1)); + } + + /** + * secondPathAttribute is EBGP than firstPathAttribute is IBGP. + */ + @Test + public void selectionAlgoTest6() throws BgpParseException { + + byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a }; + LinkedList pathAttributes1 = new LinkedList<>(); + BgpValueType pathAttribute1; + byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute1 = Origin.read(buffer); + pathAttributes1.add(pathAttribute1); + byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute1 = AsPath.read(buffer); + pathAttributes1.add(pathAttribute1); + + IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp); + int bgpId = 168427777; + short locRIBASNum = 100; + boolean isIbgp = true; + PathAttrNlriDetails attrList1 = new PathAttrNlriDetails(); + attrList1.setIdentifier(0); + attrList1.setPathAttribute(pathAttributes1); + attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE); + PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList1); + + peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b }; + LinkedList pathAttributes2 = new LinkedList<>(); + BgpValueType pathAttribute2; + origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute2 = Origin.read(buffer); + pathAttributes2.add(pathAttribute2); + asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute2 = AsPath.read(buffer); + pathAttributes2.add(pathAttribute2); + + ipAddress = IpAddress.valueOf(Version.INET, peerIp); + bgpId = 536936448; + locRIBASNum = 200; + isIbgp = false; + PathAttrNlriDetails attrList2 = new PathAttrNlriDetails(); + attrList2.setIdentifier(0); + attrList2.setPathAttribute(pathAttributes2); + attrList2.setProtocolID(ProtocolType.OSPF_V2); + PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, false, attrList2); + BgpSelectionAlgo algo = new BgpSelectionAlgo(); + int result = algo.compare(list1, list2); + assertThat(result, is(-1)); + } + + /** + * firstPathAttribute has lower BGPID than secondPathAttribute. + */ + @Test + public void selectionAlgoTest7() throws BgpParseException { + + byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a }; + LinkedList pathAttributes1 = new LinkedList<>(); + BgpValueType pathAttribute1; + byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute1 = Origin.read(buffer); + pathAttributes1.add(pathAttribute1); + byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute1 = AsPath.read(buffer); + pathAttributes1.add(pathAttribute1); + + IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp); + //A0A0A00 + Integer bgpId = 168430080; + short locRIBASNum = 100; + boolean isIbgp = false; + PathAttrNlriDetails attrList1 = new PathAttrNlriDetails(); + attrList1.setIdentifier(0); + attrList1.setPathAttribute(pathAttributes1); + attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE); + PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList1); + + peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b }; + LinkedList pathAttributes2 = new LinkedList<>(); + BgpValueType pathAttribute2; + origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute2 = Origin.read(buffer); + pathAttributes2.add(pathAttribute2); + asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute2 = AsPath.read(buffer); + pathAttributes2.add(pathAttribute2); + + ipAddress = IpAddress.valueOf(Version.INET, peerIp); + //B0A0A00 + bgpId = 185207296; + locRIBASNum = 200; + isIbgp = false; + PathAttrNlriDetails attrList2 = new PathAttrNlriDetails(); + attrList2.setIdentifier(0); + attrList2.setPathAttribute(pathAttributes2); + attrList2.setProtocolID(ProtocolType.OSPF_V2); + PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList2); + BgpSelectionAlgo algo = new BgpSelectionAlgo(); + int result = algo.compare(list1, list2); + assertThat(result, is(1)); + } + + /** + * secondPathAttribute has lowest peer address than firstPathAttribute. + */ + @Test + public void selectionAlgoTest8() throws BgpParseException { + + byte[] peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b }; + LinkedList pathAttributes1 = new LinkedList<>(); + BgpValueType pathAttribute1; + byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute1 = Origin.read(buffer); + pathAttributes1.add(pathAttribute1); + byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute1 = AsPath.read(buffer); + pathAttributes1.add(pathAttribute1); + + IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp); + //A0A0A00 + Integer bgpId = 168430080; + short locRIBASNum = 100; + boolean isIbgp = false; + PathAttrNlriDetails attrList1 = new PathAttrNlriDetails(); + attrList1.setIdentifier(0); + attrList1.setPathAttribute(pathAttributes1); + attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE); + PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList1); + + peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a }; + LinkedList pathAttributes2 = new LinkedList<>(); + BgpValueType pathAttribute2; + origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute2 = Origin.read(buffer); + pathAttributes2.add(pathAttribute2); + asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute2 = AsPath.read(buffer); + pathAttributes2.add(pathAttribute2); + + ipAddress = IpAddress.valueOf(Version.INET, peerIp); + //A0A0A00 + bgpId = 168430080; + locRIBASNum = 200; + isIbgp = false; + PathAttrNlriDetails attrList2 = new PathAttrNlriDetails(); + attrList2.setIdentifier(0); + attrList2.setPathAttribute(pathAttributes2); + attrList2.setProtocolID(ProtocolType.OSPF_V2); + PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList2); + BgpSelectionAlgo algo = new BgpSelectionAlgo(); + int result = algo.compare(list1, list2); + assertThat(result, is(-1)); + } + + /** + * firstPathAttribute and secondPathAttribute are same. + */ + @Test + public void selectionAlgoTest9() throws BgpParseException { + + byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a }; + LinkedList pathAttributes1 = new LinkedList<>(); + BgpValueType pathAttribute1; + byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute1 = Origin.read(buffer); + pathAttributes1.add(pathAttribute1); + byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute1 = AsPath.read(buffer); + pathAttributes1.add(pathAttribute1); + + IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp); + //A0A0A00 + Integer bgpId = 168430080; + short locRIBASNum = 100; + boolean isIbgp = false; + PathAttrNlriDetails attrList1 = new PathAttrNlriDetails(); + attrList1.setIdentifier(0); + attrList1.setPathAttribute(pathAttributes1); + attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE); + PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList1); + + peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a }; + LinkedList pathAttributes2 = new LinkedList<>(); + BgpValueType pathAttribute2; + origin = new byte[] {0x40, 0x01, 0x01, 0x00 }; + buffer = ChannelBuffers.dynamicBuffer(); + buffer.writeBytes(origin); + pathAttribute2 = Origin.read(buffer); + pathAttributes2.add(pathAttribute2); + asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, + (byte) 0xe9 }; + buffer.writeBytes(asPath); + pathAttribute2 = AsPath.read(buffer); + pathAttributes2.add(pathAttribute2); + + ipAddress = IpAddress.valueOf(Version.INET, peerIp); + //A0A0A00 + bgpId = 168430080; + locRIBASNum = 200; + isIbgp = false; + PathAttrNlriDetails attrList2 = new PathAttrNlriDetails(); + attrList2.setIdentifier(0); + attrList2.setPathAttribute(pathAttributes2); + attrList2.setProtocolID(ProtocolType.OSPF_V2); + PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib( + ipAddress, bgpId, locRIBASNum, isIbgp, attrList2); + BgpSelectionAlgo algo = new BgpSelectionAlgo(); + int result = algo.compare(list1, list2); + assertThat(result, is(0)); + } +} diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/ConnectivityIntentCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/ConnectivityIntentCommand.java index fbce9648..713b4b5a 100644 --- a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/ConnectivityIntentCommand.java +++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/ConnectivityIntentCommand.java @@ -26,6 +26,7 @@ import org.onlab.util.Bandwidth; import org.onosproject.cli.AbstractShellCommand; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; +import org.onosproject.net.EncapsulationType; import org.onosproject.net.Link; import org.onosproject.net.PortNumber; import org.onosproject.net.flow.DefaultTrafficSelector; @@ -36,10 +37,10 @@ import org.onosproject.net.intent.Constraint; import org.onosproject.net.intent.Intent; import org.onosproject.net.intent.Key; import org.onosproject.net.intent.constraint.BandwidthConstraint; +import org.onosproject.net.intent.constraint.EncapsulationConstraint; import org.onosproject.net.intent.constraint.LambdaConstraint; import org.onosproject.net.intent.constraint.LinkTypeConstraint; import org.onosproject.net.intent.constraint.PartialFailureConstraint; -import org.onosproject.net.resource.link.BandwidthResource; import java.util.LinkedList; import java.util.List; @@ -117,14 +118,6 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { required = false, multiValued = true) private List extHdrStringList = null; - @Option(name = "-b", aliases = "--bandwidth", description = "Bandwidth", - required = false, multiValued = false) - private String bandwidthString = null; - - @Option(name = "-l", aliases = "--lambda", description = "Lambda", - required = false, multiValued = false) - private boolean lambda = false; - @Option(name = "-a", aliases = "--appId", description = "Application Id", required = false, multiValued = false) private String appId = null; @@ -133,10 +126,6 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { required = false, multiValued = false) private String intentKey = null; - @Option(name = "--partial", description = "Allow partial installation", - required = false, multiValued = false) - private boolean partial = false; - // Treatments @Option(name = "--setEthSrc", description = "Rewrite Source MAC Address", @@ -177,6 +166,24 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { required = false, multiValued = false) private int priority = Intent.DEFAULT_INTENT_PRIORITY; + // Constraints + @Option(name = "-b", aliases = "--bandwidth", description = "Bandwidth", + required = false, multiValued = false) + private String bandwidthString = null; + + @Option(name = "-l", aliases = "--lambda", description = "Lambda", + required = false, multiValued = false) + private boolean lambda = false; + + @Option(name = "--partial", description = "Allow partial installation", + required = false, multiValued = false) + private boolean partial = false; + + @Option(name = "-e", aliases = "--encapsulation", description = "Encapsulation type", + required = false, multiValued = false) + private String encapsulationString = null; + + /** * Constructs a traffic selector based on the command line arguments * presented to the command. @@ -365,7 +372,7 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { // Check for a bandwidth specification if (!isNullOrEmpty(bandwidthString)) { final Bandwidth bandwidth = Bandwidth.bps(Double.parseDouble(bandwidthString)); - constraints.add(new BandwidthConstraint(new BandwidthResource(bandwidth))); + constraints.add(new BandwidthConstraint(bandwidth)); } // Check for a lambda specification @@ -374,10 +381,17 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand { } constraints.add(new LinkTypeConstraint(lambda, Link.Type.OPTICAL)); + // Check for partial failure specification if (partial) { constraints.add(new PartialFailureConstraint()); } + // Check for encapsulation specification + if (!isNullOrEmpty(encapsulationString)) { + final EncapsulationType encapType = EncapsulationType.valueOf(encapsulationString); + constraints.add(new EncapsulationConstraint(encapType)); + } + return constraints; } diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/EncapTypeCompleter.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/EncapTypeCompleter.java new file mode 100644 index 00000000..b14615d4 --- /dev/null +++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/EncapTypeCompleter.java @@ -0,0 +1,28 @@ +package org.onosproject.cli.net; + +import org.apache.karaf.shell.console.Completer; +import org.apache.karaf.shell.console.completer.StringsCompleter; +import org.onosproject.net.EncapsulationType; + +import java.util.List; +import java.util.SortedSet; + +/** + * Encapsulation type completer. + */ +public class EncapTypeCompleter implements Completer { + + @Override + public int complete(String buffer, int cursor, List candidates) { + // Delegate string completer + StringsCompleter delegate = new StringsCompleter(); + SortedSet strings = delegate.getStrings(); + + for (EncapsulationType encapType : EncapsulationType.values()) { + strings.add(encapType.toString()); + } + + // Now let the completer do the work for figuring out what to offer. + return delegate.complete(buffer, cursor, candidates); + } +} diff --git a/framework/src/onos/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml index 9bd5dd9f..1f350c5b 100644 --- a/framework/src/onos/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml +++ b/framework/src/onos/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml @@ -201,6 +201,7 @@ + @@ -216,6 +217,7 @@ + @@ -252,6 +254,7 @@ + @@ -266,6 +269,7 @@ + @@ -499,5 +503,6 @@ + diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/EncapsulationType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/EncapsulationType.java new file mode 100644 index 00000000..63ff46d3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/EncapsulationType.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.net; + +public enum EncapsulationType { + /** + * Indicates an MPLS encapsulation. + */ + MPLS, + /** + * Indicates a VLAN encapsulation. + */ + VLAN, +}; + + diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/TributarySlot.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/TributarySlot.java new file mode 100644 index 00000000..d8a10c81 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/TributarySlot.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.net; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of ODU Tributary Slot simply designated by an index number of slot. + */ +public class TributarySlot { + + private final long index; + + /** + * Creates an instance representing the TributarySlot specified by the given index number. + * + * @param index index number of wavelength + */ + public TributarySlot(long index) { + this.index = index; + } + + public static TributarySlot of(long index) { + return new TributarySlot(index); + } + + /** + * Returns the index number of TributarySlot. + * + * @return the index number of TributarySlot + */ + public long index() { + return index; + } + + @Override + public int hashCode() { + return Long.hashCode(index); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TributarySlot)) { + return false; + } + + final TributarySlot that = (TributarySlot) obj; + return this.index == that.index; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("index", index) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionResolver.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java similarity index 80% rename from framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionResolver.java rename to framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java index 54cbc7ac..85f0216d 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionResolver.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java @@ -18,14 +18,14 @@ package org.onosproject.net.behaviour; import com.google.common.annotations.Beta; import org.onosproject.net.driver.HandlerBehaviour; -import org.onosproject.net.flow.instructions.ExtensionInstruction; -import org.onosproject.net.flow.instructions.ExtensionType; +import org.onosproject.net.flow.instructions.ExtensionTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; /** * Provides access to the extension implemented by this driver. */ @Beta -public interface ExtensionResolver extends HandlerBehaviour { +public interface ExtensionTreatmentResolver extends HandlerBehaviour { /** * Gets an extension instruction instance of the specified type, if supported @@ -36,5 +36,5 @@ public interface ExtensionResolver extends HandlerBehaviour { * @throws UnsupportedOperationException if the extension type is not * supported by this driver */ - ExtensionInstruction getExtensionInstruction(ExtensionType type); + ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type); } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java index e3b4c198..a1b97ffd 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java @@ -29,6 +29,7 @@ public interface TunnelConfig extends HandlerBehaviour { * * @param tunnel tunnel descriptor */ + @Deprecated void createTunnel(TunnelDescription tunnel); /** diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java index 3757d327..5f2c9f3a 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java @@ -332,6 +332,26 @@ public abstract class Config { return list; } + /** + * Gets the specified array property as a list of items. + * + * @param name property name + * @param function mapper from string to item + * @param defaultValue default value if property not set + * @param type of item + * @return list of items + */ + protected List getList(String name, Function function, List defaultValue) { + List list = Lists.newArrayList(); + JsonNode jsonNode = object.path(name); + if (jsonNode.isMissingNode()) { + return defaultValue; + } + ArrayNode arrayNode = (ArrayNode) jsonNode; + arrayNode.forEach(i -> list.add(function.apply(i.asText()))); + return list; + } + /** * Sets the specified property as an array of items in a given collection or * clears it if null is given. diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicFeatureConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicFeatureConfig.java new file mode 100644 index 00000000..fcf24bc6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicFeatureConfig.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.net.config.basics; + +import org.onosproject.net.config.Config; + +/** + * Base abstraction for configuring feature on subject. + * + * @param Subject type + */ +public abstract class BasicFeatureConfig extends Config { + + private static final String ENABLED = "enabled"; + + private final boolean defaultValue; + + protected BasicFeatureConfig(boolean defaultValue) { + this.defaultValue = defaultValue; + } + + /** + * Indicates whether the feature for the subject is enabled. + * + * @return true if feature is enabled + */ + public boolean enabled() { + return get(ENABLED, defaultValue); + } + + /** + * Specifies whether the feature for the subject is to be enabled. + * + * @param enabled true to enable; false to disable; null to clear + * @return self + */ + public BasicFeatureConfig enabled(Boolean enabled) { + return (BasicFeatureConfig) setOrClear(ENABLED, enabled); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java index a842d600..d3c2449c 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java @@ -340,7 +340,7 @@ public final class DefaultTrafficSelector implements TrafficSelector { @Override public Builder matchMplsBos(boolean mplsBos) { - return add(Criteria.matchMplsLabel(mplsBos)); + return add(Criteria.matchMplsBos(mplsBos)); } @Override @@ -373,6 +373,11 @@ public final class DefaultTrafficSelector implements TrafficSelector { return add(Criteria.matchArpSha(addr)); } + @Override + public Builder matchArpOp(int arpOp) { + return add(Criteria.matchArpOp(arpOp)); + } + @Override public TrafficSelector build() { return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values())); diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java index 4615a82b..22bff7dd 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java @@ -30,7 +30,7 @@ import org.onosproject.core.GroupId; import org.onosproject.net.DeviceId; import org.onosproject.net.IndexedLambda; import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.instructions.ExtensionInstruction; +import org.onosproject.net.flow.instructions.ExtensionTreatment; import org.onosproject.net.flow.instructions.Instruction; import org.onosproject.net.flow.instructions.Instructions; import org.onosproject.net.meter.MeterId; @@ -489,7 +489,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { } @Override - public TrafficTreatment.Builder extension(ExtensionInstruction extension, + public TrafficTreatment.Builder extension(ExtensionTreatment extension, DeviceId deviceId) { return add(Instructions.extension(extension, deviceId)); } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java index 9fe88d5a..b92281f5 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java @@ -418,6 +418,14 @@ public interface TrafficSelector { */ Builder matchArpSha(MacAddress addr); + /** + * Matches a arp operation type. + * + * @param arpOp a arp operation type + * @return a selection builder + */ + Builder matchArpOp(int arpOp); + /** * Builds an immutable traffic selector. * diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java index f1a676ab..06b6ffa0 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java @@ -26,7 +26,7 @@ import org.onlab.packet.VlanId; import org.onosproject.core.GroupId; import org.onosproject.net.DeviceId; import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.instructions.ExtensionInstruction; +import org.onosproject.net.flow.instructions.ExtensionTreatment; import org.onosproject.net.flow.instructions.Instruction; import org.onosproject.net.flow.instructions.Instructions; import org.onosproject.net.meter.MeterId; @@ -430,7 +430,7 @@ public interface TrafficTreatment { * @param deviceId device ID * @return a treatment builder */ - Builder extension(ExtensionInstruction extension, DeviceId deviceId); + Builder extension(ExtensionTreatment extension, DeviceId deviceId); /** * Builds an immutable traffic treatment descriptor. diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpOpCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpOpCriterion.java new file mode 100644 index 00000000..8c5398c6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpOpCriterion.java @@ -0,0 +1,78 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.net.flow.criteria; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Implementation of arp operation type criterion. + */ +public final class ArpOpCriterion implements Criterion { + private final int arpOp; + private final Type type; + + /** + * Constructor. + * + * @param arpOp the arp operation type to match. + * @param type the match type. Should be the following: + * Type.ARP_OP + */ + ArpOpCriterion(int arpOp, Type type) { + this.arpOp = arpOp; + this.type = type; + } + + @Override + public Type type() { + return this.type; + } + + /** + * Gets the arp operation type to match. + * + * @return the arp operation type to match + */ + public int arpOp() { + return this.arpOp; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("arpOp", arpOp).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), arpOp); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ArpOpCriterion) { + ArpOpCriterion that = (ArpOpCriterion) obj; + return Objects.equals(arpOp, that.arpOp) && + Objects.equals(type, that.type); + } + return false; + } +} \ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java index 554b8e74..a28a4ab9 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java @@ -229,6 +229,16 @@ public final class Criteria { return new TcpPortCriterion(tcpPort, Type.TCP_DST); } + /** + * Creates a match on TCP flags using the specified value. + * + * @param flags TCP flags + * @return match criterion + */ + public static Criterion matchTcpFlags(int flags) { + return new TcpFlagsCriterion(flags); + } + /** * Creates a match on UDP source port field using the specified value. * @@ -438,10 +448,20 @@ public final class Criteria { * @param mplsBos boolean value indicating true (BOS=1) or false (BOS=0) * @return match criterion */ - public static Criterion matchMplsLabel(boolean mplsBos) { + public static Criterion matchMplsBos(boolean mplsBos) { return new MplsBosCriterion(mplsBos); } + /** + * Creates a match on MPLS TC. + * + * @param mplsTc MPLS TC (3 bits) + * @return match criterion + */ + public static Criterion matchMplsTc(byte mplsTc) { + return new MplsTcCriterion(mplsTc); + } + /** * Creates a match on Tunnel ID. * @@ -549,6 +569,16 @@ public final class Criteria { return new ArpHaCriterion(mac, Type.ARP_SHA); } + /** + * Creates a match on arp operation type field using the specified value. + * + * @param arpOp arp operation type value + * @return match criterion + */ + public static Criterion matchArpOp(int arpOp) { + return new ArpOpCriterion(arpOp, Type.ARP_OP); + } + public static Criterion dummy() { return new DummyCriterion(); } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java index 10cb629f..26665246 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java @@ -28,92 +28,136 @@ public interface Criterion { enum Type { /** Switch input port. */ IN_PORT, + /** Switch physical input port. */ IN_PHY_PORT, + /** Metadata passed between tables. */ METADATA, + /** Ethernet destination address. */ ETH_DST, + /** Ethernet source address. */ ETH_SRC, + /** Ethernet frame type. */ ETH_TYPE, + /** VLAN id. */ VLAN_VID, + /** VLAN priority. */ VLAN_PCP, + /** IP DSCP (6 bits in ToS field). */ IP_DSCP, + /** IP ECN (2 bits in ToS field). */ IP_ECN, + /** IP protocol. */ IP_PROTO, + /** IPv4 source address. */ IPV4_SRC, + /** IPv4 destination address. */ IPV4_DST, + /** TCP source port. */ TCP_SRC, + /** TCP destination port. */ TCP_DST, + /** UDP source port. */ UDP_SRC, + /** UDP destination port. */ UDP_DST, + /** SCTP source port. */ SCTP_SRC, + /** SCTP destination port. */ SCTP_DST, + /** ICMP type. */ ICMPV4_TYPE, + /** ICMP code. */ ICMPV4_CODE, + /** ARP opcode. */ ARP_OP, + /** ARP source IPv4 address. */ ARP_SPA, + /** ARP target IPv4 address. */ ARP_TPA, + /** ARP source hardware address. */ ARP_SHA, + /** ARP target hardware address. */ ARP_THA, + /** IPv6 source address. */ IPV6_SRC, + /** IPv6 destination address. */ IPV6_DST, + /** IPv6 Flow Label. */ IPV6_FLABEL, + /** ICMPv6 type. */ ICMPV6_TYPE, + /** ICMPv6 code. */ ICMPV6_CODE, + /** Target address for ND. */ IPV6_ND_TARGET, + /** Source link-layer for ND. */ IPV6_ND_SLL, + /** Target link-layer for ND. */ IPV6_ND_TLL, + /** MPLS label. */ MPLS_LABEL, + /** MPLS TC. */ MPLS_TC, - /** MPLS BoS bit. */ + + /** MPLS BoS bit. */ MPLS_BOS, + /** PBB I-SID. */ PBB_ISID, + /** Logical Port Metadata. */ TUNNEL_ID, + /** IPv6 Extension Header pseudo-field. */ IPV6_EXTHDR, + /** Unassigned value: 40. */ UNASSIGNED_40, + /** PBB UCA header field. */ PBB_UCA, + /** TCP flags. */ TCP_FLAGS, + /** Output port from action set metadata. */ ACTSET_OUTPUT, + /** Packet type value. */ PACKET_TYPE, @@ -123,16 +167,17 @@ public interface Criterion { // /** Optical channel signal ID (lambda). */ OCH_SIGID, + /** Optical channel signal type (fixed or flexible). */ OCH_SIGTYPE, + /** ODU (Optical channel Data Unit) signal ID. */ ODU_SIGID, + /** ODU (Optical channel Data Unit) signal type. */ ODU_SIGTYPE, - /** - * An empty criterion. - */ + /** An empty criterion. */ DUMMY } @@ -182,4 +227,41 @@ public interface Criterion { return this.value; } } + + enum TCPFlags { + + /** ECN-nonce concealment protection. */ + NS((short) (1 << 0)), + /** Congestion Window Reduced. */ + CWR((short) (1 << 1)), + /** ECN-Echo. **/ + ECE((short) (1 << 2)), + /** Urgent pointer field is significant. */ + URG((short) (1 << 3)), + /** Acknowledgment field is significant. */ + ACK((short) (1 << 4)), + /** Push the buffered data to the receiving application. */ + PSH((short) (1 << 5)), + /** Reset the connection. */ + RST((short) (1 << 6)), + /** Synchronize sequence numbers. */ + SYN((short) (1 << 7)), + /** No more data from sender. */ + FIN((short) (1 << 8)); + + private short value; + + TCPFlags(short value) { + this.value = value; + } + + /** + * Gets the value as an integer. + * + * @return the value as an integer + */ + public short getValue() { + return this.value; + } + } } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsTcCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsTcCriterion.java new file mode 100644 index 00000000..8ad62358 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsTcCriterion.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.net.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of MPLS TC criterion (3 bits). + */ +public final class MplsTcCriterion implements Criterion { + private static final byte MASK = 0x7; + private final byte mplsTc; + + /** + * Constructor. + * + * @param mplsTc the MPLS TC to match (3 bits) + */ + MplsTcCriterion(byte mplsTc) { + this.mplsTc = (byte) (mplsTc & MASK); + } + + @Override + public Type type() { + return Type.MPLS_TC; + } + + /** + * Gets the MPLS TC to match. + * + * @return the MPLS TC to match (3 bits) + */ + public byte tc() { + return mplsTc; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("tc", Long.toHexString(mplsTc)).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), mplsTc); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof MplsTcCriterion) { + MplsTcCriterion that = (MplsTcCriterion) obj; + return Objects.equals(mplsTc, that.mplsTc) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpFlagsCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpFlagsCriterion.java new file mode 100644 index 00000000..e0b53958 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpFlagsCriterion.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.net.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of TCP flags criterion (12 bits unsigned integer). + */ +public final class TcpFlagsCriterion implements Criterion { + private static final int MASK = 0xfffff; + private final int flags; // TCP flags: 12 bits + + /** + * Constructor. + * + * @param flags the TCP flags to match (12 bits) + */ + TcpFlagsCriterion(int flags) { + this.flags = flags & MASK; + } + + @Override + public Type type() { + return Type.TCP_FLAGS; + } + + /** + * Gets the TCP flags to match. + * + * @return the TCP flags to match (12 bits) + */ + public int flags() { + return flags; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("flags", Long.toHexString(flags)).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), flags); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TcpFlagsCriterion) { + TcpFlagsCriterion that = (TcpFlagsCriterion) obj; + return Objects.equals(flags, that.flags) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java similarity index 96% rename from framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionInstruction.java rename to framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java index 9f22f888..ac7c771f 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionInstruction.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java @@ -23,7 +23,7 @@ import java.util.List; /** * Abstract implementation of the set/get property methods of ExtensionInstruction. */ -public abstract class AbstractExtensionInstruction implements ExtensionInstruction { +public abstract class AbstractExtensionTreatment implements ExtensionTreatment { private static final String INVALID_KEY = "Invalid property key: "; private static final String INVALID_TYPE = "Given type does not match field type: "; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java similarity index 96% rename from framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionInstruction.java rename to framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java index 89e0cc5e..0e8885ed 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionInstruction.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java @@ -21,14 +21,14 @@ import java.util.List; /** * An extensible instruction type. */ -public interface ExtensionInstruction { +public interface ExtensionTreatment { /** * Gets the type of the extension instruction. * * @return type */ - ExtensionType type(); + ExtensionTreatmentType type(); /** * Sets a property on the extension instruction. diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java similarity index 73% rename from framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java rename to framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java index 3e1cb75c..38fbc279 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java @@ -25,25 +25,27 @@ import java.util.Objects; * Type of extension instructions. */ @Beta -public final class ExtensionType { +public final class ExtensionTreatmentType { /** * A list of well-known named extension instruction type codes. + * These numbers have no impact on the actual OF type id. */ - public enum ExtensionTypes { + public enum ExtensionTreatmentTypes { // TODO fix type numbers to include experimenter id - NICIRA_SET_TUNNEL_DST(31), - NICIRA_RESUBMIT(32); + NICIRA_SET_TUNNEL_DST(0), + NICIRA_RESUBMIT(1), + NICIRA_SET_NSH_SPI(32); - private ExtensionType type; + private ExtensionTreatmentType type; /** * Creates a new named extension instruction type. * * @param type type code */ - ExtensionTypes(int type) { - this.type = new ExtensionType(type); + ExtensionTreatmentTypes(int type) { + this.type = new ExtensionTreatmentType(type); } /** @@ -51,7 +53,7 @@ public final class ExtensionType { * * @return extension type object */ - public ExtensionType type() { + public ExtensionTreatmentType type() { return type; } } @@ -63,7 +65,7 @@ public final class ExtensionType { * * @param type type code */ - public ExtensionType(int type) { + public ExtensionTreatmentType(int type) { this.type = type; } @@ -77,8 +79,8 @@ public final class ExtensionType { if (this == obj) { return true; } - if (obj instanceof ExtensionType) { - final ExtensionType that = (ExtensionType) obj; + if (obj instanceof ExtensionTreatmentType) { + final ExtensionTreatmentType that = (ExtensionTreatmentType) obj; return this.type == that.type; } return false; @@ -86,7 +88,7 @@ public final class ExtensionType { @Override public String toString() { - return MoreObjects.toStringHelper(ExtensionType.class) + return MoreObjects.toStringHelper(ExtensionTreatmentType.class) .add("type", type) .toString(); } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java index 126e722e..4643b315 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java @@ -489,7 +489,7 @@ public final class Instructions { * @param deviceId device ID * @return extension instruction */ - public static ExtensionInstructionWrapper extension(ExtensionInstruction extension, + public static ExtensionInstructionWrapper extension(ExtensionTreatment extension, DeviceId deviceId) { checkNotNull(extension, "Extension instruction cannot be null"); checkNotNull(deviceId, "Device ID cannot be null"); @@ -858,16 +858,16 @@ public final class Instructions { * Extension instruction. */ public static class ExtensionInstructionWrapper implements Instruction { - private final ExtensionInstruction extensionInstruction; + private final ExtensionTreatment extensionTreatment; private final DeviceId deviceId; - ExtensionInstructionWrapper(ExtensionInstruction extension, DeviceId deviceId) { - extensionInstruction = extension; + ExtensionInstructionWrapper(ExtensionTreatment extension, DeviceId deviceId) { + extensionTreatment = extension; this.deviceId = deviceId; } - public ExtensionInstruction extensionInstruction() { - return extensionInstruction; + public ExtensionTreatment extensionInstruction() { + return extensionTreatment; } public DeviceId deviceId() { @@ -882,14 +882,14 @@ public final class Instructions { @Override public String toString() { return toStringHelper(type().toString()) - .add("extension", extensionInstruction) + .add("extension", extensionTreatment) .add("deviceId", deviceId) .toString(); } @Override public int hashCode() { - return Objects.hash(type().ordinal(), extensionInstruction, deviceId); + return Objects.hash(type().ordinal(), extensionTreatment, deviceId); } @Override @@ -899,7 +899,7 @@ public final class Instructions { } if (obj instanceof ExtensionInstructionWrapper) { ExtensionInstructionWrapper that = (ExtensionInstructionWrapper) obj; - return Objects.equals(extensionInstruction, that.extensionInstruction) + return Objects.equals(extensionTreatment, that.extensionTreatment) && Objects.equals(deviceId, that.deviceId); } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java index 0abf5abe..af481805 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java @@ -16,6 +16,7 @@ package org.onosproject.net.flowobjective; import com.google.common.annotations.Beta; + import org.onosproject.core.ApplicationId; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; @@ -119,6 +120,53 @@ public final class DefaultForwardingObjective implements ForwardingObjective { return context; } + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return Objects.hash(selector, flag, permanent, + timeout, appId, priority, nextId, + treatment, op); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof DefaultForwardingObjective)) { + return false; + } + final DefaultForwardingObjective other = (DefaultForwardingObjective) obj; + boolean nextEq = false, treatmentEq = false; + if (this.selector.equals(other.selector) && + this.flag == other.flag && + this.permanent == other.permanent && + this.timeout == other.timeout && + this.appId.equals(other.appId) && + this.priority == other.priority && + this.op == other.op) { + if (this.nextId != null && other.nextId != null) { + nextEq = this.nextId == other.nextId; + } + if (this.treatment != null && other.treatment != null) { + treatmentEq = this.treatment.equals(other.treatment); + } + if (nextEq && treatmentEq) { + return true; + } + } + return false; + } + /** * Returns a new builder. * diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java index 20e89295..4701589f 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java @@ -18,6 +18,7 @@ package org.onosproject.net.flowobjective; import com.google.common.annotations.Beta; import com.google.common.collect.ImmutableList; import org.onosproject.core.ApplicationId; +import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import java.util.Collection; @@ -39,6 +40,7 @@ public final class DefaultNextObjective implements NextObjective { private final Integer id; private final Operation op; private final Optional context; + private final TrafficSelector meta; private DefaultNextObjective(Builder builder) { this.treatments = builder.treatments; @@ -47,6 +49,7 @@ public final class DefaultNextObjective implements NextObjective { this.id = builder.id; this.op = builder.op; this.context = Optional.ofNullable(builder.context); + this.meta = builder.meta; } @Override @@ -94,6 +97,11 @@ public final class DefaultNextObjective implements NextObjective { return context; } + @Override + public TrafficSelector meta() { + return meta; + } + /** * Returns a new builder. * @@ -111,6 +119,7 @@ public final class DefaultNextObjective implements NextObjective { private List treatments; private Operation op; private ObjectiveContext context; + private TrafficSelector meta; private final ImmutableList.Builder listBuilder = ImmutableList.builder(); @@ -171,6 +180,12 @@ public final class DefaultNextObjective implements NextObjective { return this; } + @Override + public Builder setMeta(TrafficSelector meta) { + this.meta = meta; + return this; + } + @Override public NextObjective add() { treatments = listBuilder.build(); @@ -218,5 +233,55 @@ public final class DefaultNextObjective implements NextObjective { return new DefaultNextObjective(this); } + + @Override + public NextObjective addToExisting() { + treatments = listBuilder.build(); + op = Operation.ADD_TO_EXISTING; + checkNotNull(appId, "Must supply an application id"); + checkNotNull(id, "id cannot be null"); + checkNotNull(type, "The type cannot be null"); + checkArgument(!treatments.isEmpty(), "Must have at least one treatment"); + + return new DefaultNextObjective(this); + } + + @Override + public NextObjective removeFromExisting() { + treatments = listBuilder.build(); + op = Operation.REMOVE_FROM_EXISTING; + checkNotNull(appId, "Must supply an application id"); + checkNotNull(id, "id cannot be null"); + checkNotNull(type, "The type cannot be null"); + + return new DefaultNextObjective(this); + } + + @Override + public NextObjective addToExisting(ObjectiveContext context) { + treatments = listBuilder.build(); + op = Operation.ADD_TO_EXISTING; + this.context = context; + checkNotNull(appId, "Must supply an application id"); + checkNotNull(id, "id cannot be null"); + checkNotNull(type, "The type cannot be null"); + checkArgument(!treatments.isEmpty(), "Must have at least one treatment"); + + return new DefaultNextObjective(this); + } + + @Override + public NextObjective removeFromExisting(ObjectiveContext context) { + treatments = listBuilder.build(); + op = Operation.REMOVE_FROM_EXISTING; + this.context = context; + checkNotNull(appId, "Must supply an application id"); + checkNotNull(id, "id cannot be null"); + checkNotNull(type, "The type cannot be null"); + + return new DefaultNextObjective(this); + } + } + } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java index 1350d7a1..08916eb2 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java @@ -17,6 +17,7 @@ package org.onosproject.net.flowobjective; import com.google.common.annotations.Beta; import org.onosproject.core.ApplicationId; +import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import java.util.Collection; @@ -34,7 +35,7 @@ import java.util.Collection; * - Failover * - Simple * - * These types will indicate to the driver what the intended behaviour is. + * These types will indicate to the driver what the intended behavior is. * For example, a broadcast next objective with a collection of output * treatments will indicate to a driver that all output actions are expected * to be executed simultaneously. The driver is then free to implement this @@ -83,6 +84,16 @@ public interface NextObjective extends Objective { */ Type type(); + /** + * Auxiliary optional information provided to the device-driver.Typically + * conveys information about selectors (matches) that are intended to + * use this Next Objective. + * + * @return a selector intended to pass meta information to the device driver. + * Value may be null if no meta information is provided. + */ + TrafficSelector meta(); + /** * A next step builder. */ @@ -130,6 +141,14 @@ public interface NextObjective extends Objective { @Override Builder withPriority(int priority); + /** + * Set meta information related to this next objective. + * + * @param selector match conditions + * @return an objective builder + */ + Builder setMeta(TrafficSelector selector); + /** * Builds the next objective that will be added. * @@ -162,6 +181,40 @@ public interface NextObjective extends Objective { */ NextObjective remove(ObjectiveContext context); + /** + * Build the next objective that will be added, with {@link Operation} + * ADD_TO_EXISTING. + * + * @return a next objective + */ + NextObjective addToExisting(); + + /** + * Build the next objective that will be removed, with {@link Operation} + * REMOVE_FROM_EXISTING. + * + * @return a next objective + */ + NextObjective removeFromExisting(); + + /** + * Builds the next objective that will be added, with {@link Operation} + * ADD_TO_EXISTING. The context will be used to notify the calling application. + * + * @param context an objective context + * @return a next objective + */ + NextObjective addToExisting(ObjectiveContext context); + + /** + * Builds the next objective that will be removed, with {@link Operation} + * REMOVE_FROM_EXISTING. The context will be used to notify the calling application. + * + * @param context an objective context + * @return a next objective + */ + NextObjective removeFromExisting(ObjectiveContext context); + } } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java index 6ac7a7a2..b1d73a7c 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java @@ -21,7 +21,7 @@ import org.onosproject.core.ApplicationId; import java.util.Optional; /** - * Base representation of an flow description. + * Base representation of a flow-objective description. */ @Beta public interface Objective { @@ -35,14 +35,30 @@ public interface Objective { */ enum Operation { /** - * Adds the objective. + * Adds the objective. Can be used for any flow objective. For forwarding + * and filtering objectives, existing objectives with identical selector + * and priority fields (but different treatments or next) will be replaced. + * For next objectives, if modification is desired, ADD will not + * do anything - use ADD_TO_EXISTING. */ ADD, /** - * Removes the objective. + * Removes the objective. Can be used for any flow objective. */ - REMOVE + REMOVE, + + /** + * Add to an existing Next Objective. Should not be used for any other + * objective. + */ + ADD_TO_EXISTING, + + /** + * Remove from an existing Next Objective. Should not be used for any + * other objective. + */ + REMOVE_FROM_EXISTING } /** @@ -129,6 +145,7 @@ public interface Objective { * @return an objective builder */ Builder withPriority(int priority); + } } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java index 7f00ae70..e1eacd1e 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java @@ -25,6 +25,7 @@ import java.util.Arrays; public class DefaultGroupKey implements GroupKey { private final byte[] key; + protected static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); public DefaultGroupKey(byte[] key) { this.key = checkNotNull(key); @@ -52,4 +53,20 @@ public class DefaultGroupKey implements GroupKey { return Arrays.hashCode(this.key); } + /** + * Returns a hex string representation of the byte array that is used + * as a group key. This solution was adapted from + * http://stackoverflow.com/questions/9655181/ + */ + @Override + public String toString() { + char[] hexChars = new char[key.length * 2]; + for (int j = 0; j < key.length; j++) { + int v = key[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + } + return "GroupKey:0x" + new String(hexChars); + } + } \ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java index c1467241..306597b3 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java @@ -114,6 +114,8 @@ public final class HostToHostIntent extends ConnectivityIntent { return this; } + + /** * Builds a host to host intent from the accumulated parameters. * diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java index 444feee4..1b4a2600 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java @@ -17,9 +17,9 @@ package org.onosproject.net.intent.constraint; import com.google.common.annotations.Beta; +import org.onlab.util.Bandwidth; import org.onlab.util.DataRateUnit; import org.onosproject.net.Link; -import org.onosproject.net.resource.link.BandwidthResource; import org.onosproject.net.resource.link.BandwidthResourceRequest; import org.onosproject.net.resource.link.LinkResourceService; import org.onosproject.net.resource.ResourceRequest; @@ -36,14 +36,14 @@ import static com.google.common.base.Preconditions.checkNotNull; @Beta public final class BandwidthConstraint extends BooleanConstraint { - private final BandwidthResource bandwidth; + private final Bandwidth bandwidth; /** * Creates a new bandwidth constraint. * * @param bandwidth required bandwidth */ - public BandwidthConstraint(BandwidthResource bandwidth) { + public BandwidthConstraint(Bandwidth bandwidth) { this.bandwidth = checkNotNull(bandwidth, "Bandwidth cannot be null"); } @@ -55,7 +55,7 @@ public final class BandwidthConstraint extends BooleanConstraint { * @return {@link BandwidthConstraint} instance with given bandwidth requirement */ public static BandwidthConstraint of(double v, DataRateUnit unit) { - return new BandwidthConstraint(BandwidthResource.of(v, unit)); + return new BandwidthConstraint(Bandwidth.of(v, unit)); } // Constructor for serialization @@ -68,7 +68,7 @@ public final class BandwidthConstraint extends BooleanConstraint { for (ResourceRequest request : resourceService.getAvailableResources(link)) { if (request.type() == ResourceType.BANDWIDTH) { BandwidthResourceRequest brr = (BandwidthResourceRequest) request; - if (brr.bandwidth().toDouble() >= bandwidth.toDouble()) { + if (brr.bandwidth().toDouble() >= bandwidth.bps()) { return true; } } @@ -81,7 +81,7 @@ public final class BandwidthConstraint extends BooleanConstraint { * * @return required bandwidth */ - public BandwidthResource bandwidth() { + public Bandwidth bandwidth() { return bandwidth; } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/EncapsulationConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/EncapsulationConstraint.java new file mode 100644 index 00000000..e8539398 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/EncapsulationConstraint.java @@ -0,0 +1,83 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.net.intent.constraint; + + +import org.onosproject.net.EncapsulationType; +import org.onosproject.net.Link; +import org.onosproject.net.resource.link.LinkResourceService; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Encapsulation to manage core transportation. + */ +public class EncapsulationConstraint extends BooleanConstraint { + + private EncapsulationType encapType; + + /** + * Creates a new encapsulation constraint. + * + * @param encapType the encapsulation type {@link EncapsulationType} + */ + public EncapsulationConstraint(EncapsulationType encapType) { + checkNotNull(encapType, "EncapsulationType cannot be null"); + this.encapType = encapType; + } + + + @Override + public boolean isValid(Link link, LinkResourceService resourceService) { + //TODO: validate the availability of the resources for each link in the path. + //e.g., availability of MPLSlabels, VLANID + + return true; + } + + /** + * Returns the encapsulation type required by this constraint. + * + * @return encapType + */ + public EncapsulationType encapType() { + return encapType; + } + + @Override + public int hashCode() { + return encapType.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final EncapsulationConstraint other = (EncapsulationConstraint) obj; + return this.encapType() == other.encapType(); + } + + @Override + public String toString() { + return toStringHelper(this).add("encapType", encapType).toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java index 7811a004..eba28984 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java @@ -16,8 +16,8 @@ package org.onosproject.net.intent.constraint; import com.google.common.annotations.Beta; +import org.onosproject.net.IndexedLambda; import org.onosproject.net.Link; -import org.onosproject.net.resource.link.LambdaResource; import org.onosproject.net.resource.link.LinkResourceService; import org.onosproject.net.resource.ResourceRequest; import org.onosproject.net.resource.ResourceType; @@ -32,14 +32,14 @@ import static com.google.common.base.MoreObjects.toStringHelper; @Beta public class LambdaConstraint extends BooleanConstraint { - private final LambdaResource lambda; + private final IndexedLambda lambda; /** * Creates a new optical lambda constraint. * * @param lambda optional lambda to indicate a specific lambda */ - public LambdaConstraint(LambdaResource lambda) { + public LambdaConstraint(IndexedLambda lambda) { this.lambda = lambda; } @@ -63,7 +63,7 @@ public class LambdaConstraint extends BooleanConstraint { * * @return required lambda */ - public LambdaResource lambda() { + public IndexedLambda lambda() { return lambda; } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java index cdcd4072..28c429bd 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java @@ -16,8 +16,8 @@ package org.onosproject.net.newresource; import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableList; -import java.util.Arrays; import java.util.List; /** @@ -26,50 +26,42 @@ import java.util.List; @Beta public interface ResourceAdminService { /** - * Registers resources as the children of the parent resource path. + * Registers the specified resources. * - * @param parent parent resource path under which the resource are registered - * @param children resources to be registered as the children of the parent - * @param type of resources + * @param resources resources to be registered * @return true if registration is successfully done, false otherwise. Registration * succeeds when each resource is not registered or unallocated. */ - default boolean registerResources(ResourcePath parent, T... children) { - return registerResources(parent, Arrays.asList(children)); + default boolean registerResources(ResourcePath... resources) { + return registerResources(ImmutableList.copyOf(resources)); } /** - * Registers resources as the children of the parent resource path. + * Registers the specified resources. * - * @param parent parent resource path under which the resource are registered - * @param children resources to be registered as the children of the parent - * @param type of resources + * @param resources resources to be registered * @return true if registration is successfully done, false otherwise. Registration * succeeds when each resource is not registered or unallocated. */ - boolean registerResources(ResourcePath parent, List children); + boolean registerResources(List resources); /** - * Unregisters resources as the children of the parent resource path. + * Unregisters the specified resources. * - * @param parent parent resource path under which the resource are unregistered - * @param children resources to be unregistered as the children of the parent - * @param type of resources + * @param resources resources to be unregistered * @return true if unregistration is successfully done, false otherwise. Unregistration * succeeds when each resource is not registered or unallocated. */ - default boolean unregisterResources(ResourcePath parent, T... children) { - return unregisterResources(parent, Arrays.asList(children)); + default boolean unregisterResources(ResourcePath... resources) { + return unregisterResources(ImmutableList.copyOf(resources)); } /** - * Unregisters resources as the children of the parent resource path. + * Unregisters the specified resources. * - * @param parent parent resource path under which the resource are unregistered - * @param children resources to be unregistered as the children of the parent - * @param type of resources + * @param resources resources to be unregistered * @return true if unregistration is successfully done, false otherwise. Unregistration * succeeds when each resource is not registered or unallocated. */ - boolean unregisterResources(ResourcePath parent, List children); + boolean unregisterResources(List resources); } diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java index d87682a9..c0c4e34f 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java @@ -56,6 +56,7 @@ public abstract class ResourcePath { * Creates an resource path which represents a discrete-type resource from the specified components. * * @param components components of the path. The order represents hierarchical structure of the resource. + * @return resource path instance */ public static ResourcePath discrete(Object... components) { if (components.length == 0) { @@ -70,6 +71,7 @@ public abstract class ResourcePath { * * @param value amount of the resource * @param components components of the path. The order represents hierarchical structure of the resource. + * @return resource path instance */ public static ResourcePath continuous(double value, Object... components) { return new Continuous(ImmutableList.copyOf(components), value); @@ -141,12 +143,27 @@ public abstract class ResourcePath { return Optional.ofNullable(parent); } + /** + * Returns a child resource path of this instance with specifying the child object. + * The child resource path is discrete-type. + * + * @param child child object + * @return a child resource path + */ public ResourcePath child(Object child) { checkState(this instanceof Discrete); return new Discrete((Discrete) this, child); } + /** + * Returns a child resource path of this instance with specifying a child object and + * value. The child resource path is continuous-type. + * + * @param child child object + * @param value value + * @return a child resource path + */ public ResourcePath child(Object child, double value) { checkState(this instanceof Discrete); @@ -197,6 +214,7 @@ public abstract class ResourcePath { * implementation only. It is not for resource API user. *

*/ + @Beta public static final class Discrete extends ResourcePath { private Discrete() { super(); @@ -218,6 +236,7 @@ public abstract class ResourcePath { * Note: This class is exposed to the public, but intended to be used in the resource API * implementation only. It is not for resource API user. */ + @Beta public static final class Continuous extends ResourcePath { // Note: value is not taken into account for equality private final double value; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java index b57465f2..583570f5 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java @@ -201,7 +201,7 @@ public final class DefaultLinkResourceRequest implements LinkResourceRequest { return addLambdaRequest(); } else if (constraint instanceof BandwidthConstraint) { BandwidthConstraint bw = (BandwidthConstraint) constraint; - return addBandwidthRequest(bw.bandwidth().toDouble()); + return addBandwidthRequest(bw.bandwidth().bps()); } return this; } diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/config/ConfigTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/config/ConfigTest.java new file mode 100644 index 00000000..34b0fe7b --- /dev/null +++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/config/ConfigTest.java @@ -0,0 +1,141 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.net.config; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.onosproject.net.config.Config.FieldPresence.MANDATORY; +import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL; + +/** + * Test of the base network config class. + */ +public class ConfigTest { + + private static final String SUBJECT = "subject"; + private static final String KEY = "key"; + + private static final String TEXT = "text"; + private static final String LONG = "long"; + private static final String DOUBLE = "double"; + private static final String MAC = "mac"; + private static final String IP = "ip"; + + private final ObjectMapper mapper = new ObjectMapper(); + private final ConfigApplyDelegate delegate = new TestDelegate(); + + private Config cfg; + private JsonNode json; + + @Before + public void setUp() { + json = new ObjectMapper().createObjectNode() + .put(TEXT, "foo").put(LONG, 5).put(DOUBLE, 0.5) + .put(MAC, "ab:cd:ef:ca:fe:ed").put(IP, "12.34.56.78"); + cfg = new TestConfig(); + cfg.init(SUBJECT, KEY, json, mapper, delegate); + } + + @Test + public void hasOnlyFields() { + assertTrue("has unexpected fields", cfg.hasOnlyFields(TEXT, LONG, DOUBLE, MAC, IP)); + assertFalse("did not detect unexpected fields", cfg.hasOnlyFields(TEXT, LONG, DOUBLE, MAC)); + assertTrue("is not proper text", cfg.isString(TEXT, MANDATORY)); + } + + @Test + public void isString() { + assertTrue("is not proper text", cfg.isString(TEXT, MANDATORY)); + assertTrue("is not proper text", cfg.isString(TEXT, MANDATORY, "^f.*")); + assertTrue("is not proper text", cfg.isString(TEXT, OPTIONAL, "^f.*")); + assertTrue("is not proper text", cfg.isString(TEXT, OPTIONAL)); + assertTrue("is not proper text", cfg.isString("none", OPTIONAL)); + assertFalse("did not detect missing field", cfg.isString("none", MANDATORY)); + } + + @Test + public void isNumber() { + assertTrue("is not proper number", cfg.isNumber(LONG, MANDATORY)); + assertTrue("is not proper number", cfg.isNumber(LONG, MANDATORY, 0)); + assertTrue("is not proper number", cfg.isNumber(LONG, MANDATORY, 0, 10)); + assertTrue("is not proper number", cfg.isNumber(LONG, MANDATORY, 5, 6)); + assertFalse("is not in range", cfg.isNumber(LONG, MANDATORY, 6, 10)); + assertFalse("is not in range", cfg.isNumber(LONG, MANDATORY, 4, 5)); + assertTrue("is not proper number", cfg.isNumber(LONG, OPTIONAL, 0, 10)); + assertTrue("is not proper number", cfg.isNumber(LONG, OPTIONAL)); + assertTrue("is not proper number", cfg.isNumber("none", OPTIONAL)); + assertFalse("did not detect missing field", cfg.isNumber("none", MANDATORY)); + } + + @Test + public void isDecimal() { + assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, MANDATORY)); + assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, MANDATORY, 0.0)); + assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, MANDATORY, 0.0, 1.0)); + assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, MANDATORY, 0.5, 0.6)); + assertFalse("is not in range", cfg.isDecimal(DOUBLE, MANDATORY, 0.6, 1.0)); + assertFalse("is not in range", cfg.isDecimal(DOUBLE, MANDATORY, 0.4, 0.5)); + assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, OPTIONAL, 0.0, 1.0)); + assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, OPTIONAL)); + assertTrue("is not proper decimal", cfg.isDecimal("none", OPTIONAL)); + assertFalse("did not detect missing field", cfg.isDecimal("none", MANDATORY)); + } + + @Test + public void isMacAddress() { + assertTrue("is not proper mac", cfg.isMacAddress(MAC, MANDATORY)); + assertTrue("is not proper mac", cfg.isMacAddress(MAC, OPTIONAL)); + assertTrue("is not proper mac", cfg.isMacAddress("none", OPTIONAL)); + assertFalse("did not detect missing field", cfg.isMacAddress("none", MANDATORY)); + } + + @Test(expected = IllegalArgumentException.class) + public void badMacAddress() { + assertTrue("is not proper mac", cfg.isMacAddress(TEXT, MANDATORY)); + } + + + @Test + public void isIpAddress() { + assertTrue("is not proper ip", cfg.isIpAddress(IP, MANDATORY)); + assertTrue("is not proper ip", cfg.isIpAddress(IP, OPTIONAL)); + assertTrue("is not proper ip", cfg.isIpAddress("none", OPTIONAL)); + assertFalse("did not detect missing field", cfg.isMacAddress("none", MANDATORY)); + } + + @Test(expected = IllegalArgumentException.class) + public void badIpAddress() { + assertTrue("is not proper ip", cfg.isIpAddress(TEXT, MANDATORY)); + } + + + // TODO: Add tests for other helper methods + + private class TestConfig extends Config { + } + + private class TestDelegate implements ConfigApplyDelegate { + @Override + public void onApply(Config config) { + } + } +} \ No newline at end of file diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java index d86744df..56a6ff63 100644 --- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java +++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java @@ -42,6 +42,7 @@ import org.onosproject.net.OduSignalType; import org.onosproject.net.PortNumber; import com.google.common.testing.EqualsTester; + /** * Unit tests for the Criteria class and its subclasses. */ @@ -135,6 +136,24 @@ public class CriteriaTest { Criterion sameAsMatchUdpPort1 = Criteria.matchUdpSrc(tpPort1); Criterion matchUdpPort2 = Criteria.matchUdpDst(tpPort2); + + int tcpFlags1 = + Criterion.TCPFlags.NS.getValue() | + Criterion.TCPFlags.CWR.getValue() | + Criterion.TCPFlags.ECE.getValue() | + Criterion.TCPFlags.URG.getValue() | + Criterion.TCPFlags.ACK.getValue() | + Criterion.TCPFlags.PSH.getValue() | + Criterion.TCPFlags.RST.getValue() | + Criterion.TCPFlags.SYN.getValue(); + + int tcpFlags2 = tcpFlags1 | + Criterion.TCPFlags.FIN.getValue(); + + Criterion matchTcpFlags1 = Criteria.matchTcpFlags(tcpFlags1); + Criterion sameAsmatchTcpFlags1 = Criteria.matchTcpFlags(tcpFlags1); + Criterion matchTcpFlags2 = Criteria.matchTcpFlags(tcpFlags2); + Criterion matchSctpPort1 = Criteria.matchSctpSrc(tpPort1); Criterion sameAsMatchSctpPort1 = Criteria.matchSctpSrc(tpPort1); Criterion matchSctpPort2 = Criteria.matchSctpDst(tpPort2); @@ -174,28 +193,28 @@ public class CriteriaTest { private Ip6Address ip6TargetAddress1 = Ip6Address.valueOf(IPV6_ADDR1); private Ip6Address ip6TargetAddress2 = Ip6Address.valueOf(IPV6_ADDR2); Criterion matchIpv6TargetAddr1 = - Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1); + Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1); Criterion sameAsMatchIpv6TargetAddr1 = - Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1); + Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1); Criterion matchIpv6TargetAddr2 = - Criteria.matchIPv6NDTargetAddress(ip6TargetAddress2); + Criteria.matchIPv6NDTargetAddress(ip6TargetAddress2); private static final String LL_MAC1 = "00:00:00:00:00:01"; private static final String LL_MAC2 = "00:00:00:00:00:02"; private MacAddress llMac1 = MacAddress.valueOf(LL_MAC1); private MacAddress llMac2 = MacAddress.valueOf(LL_MAC2); Criterion matchSrcLlAddr1 = - Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1); + Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1); Criterion sameAsMatchSrcLlAddr1 = - Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1); + Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1); Criterion matchSrcLlAddr2 = - Criteria.matchIPv6NDSourceLinkLayerAddress(llMac2); + Criteria.matchIPv6NDSourceLinkLayerAddress(llMac2); Criterion matchTargetLlAddr1 = - Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1); + Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1); Criterion sameAsMatchTargetLlAddr1 = - Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1); + Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1); Criterion matchTargetLlAddr2 = - Criteria.matchIPv6NDTargetLinkLayerAddress(llMac2); + Criteria.matchIPv6NDTargetLinkLayerAddress(llMac2); MplsLabel mpls1 = MplsLabel.mplsLabel(1); MplsLabel mpls2 = MplsLabel.mplsLabel(2); @@ -219,13 +238,13 @@ public class CriteriaTest { Criterion.IPv6ExthdrFlags.HOP.getValue() | Criterion.IPv6ExthdrFlags.UNREP.getValue(); int ipv6ExthdrFlags2 = ipv6ExthdrFlags1 | - Criterion.IPv6ExthdrFlags.UNSEQ.getValue(); + Criterion.IPv6ExthdrFlags.UNSEQ.getValue(); Criterion matchIpv6ExthdrFlags1 = - Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1); + Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1); Criterion sameAsMatchIpv6ExthdrFlags1 = - Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1); + Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1); Criterion matchIpv6ExthdrFlags2 = - Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags2); + Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags2); Criterion matchOchSignalType1 = Criteria.matchOchSignalType(OchSignalType.FIXED_GRID); Criterion sameAsMatchOchSignalType1 = Criteria.matchOchSignalType(OchSignalType.FIXED_GRID); @@ -242,8 +261,8 @@ public class CriteriaTest { Criterion matchOchSignal2 = Criteria.matchLambda(Lambda.ochSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 4, 8)); - final OduSignalId odu1 = oduSignalId(1, 80, new byte [] {1, 1, 2, 2, 1, 2, 2, 1, 2, 2}); - final OduSignalId odu2 = oduSignalId(3, 8, new byte [] {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}); + final OduSignalId odu1 = oduSignalId(1, 80, new byte[]{1, 1, 2, 2, 1, 2, 2, 1, 2, 2}); + final OduSignalId odu2 = oduSignalId(3, 8, new byte[]{1, 0, 0, 0, 0, 0, 0, 0, 0, 0}); Criterion matchOduSignalId1 = Criteria.matchOduSignalId(odu1); Criterion sameAsMatchOduSignalId1 = Criteria.matchOduSignalId(odu1); Criterion matchOduSignalId2 = Criteria.matchOduSignalId(odu2); @@ -259,9 +278,9 @@ public class CriteriaTest { * it to the proper type. * * @param criterion Criterion object to convert - * @param type Enumerated type value for the Criterion class - * @param clazz Desired Criterion class - * @param The type the caller wants returned + * @param type Enumerated type value for the Criterion class + * @param clazz Desired Criterion class + * @param The type the caller wants returned * @return converted object */ @SuppressWarnings("unchecked") @@ -297,6 +316,7 @@ public class CriteriaTest { assertThatClassIsImmutable(IPCriterion.class); assertThatClassIsImmutable(TcpPortCriterion.class); assertThatClassIsImmutable(UdpPortCriterion.class); + assertThatClassIsImmutable(TcpFlagsCriterion.class); assertThatClassIsImmutable(SctpPortCriterion.class); assertThatClassIsImmutable(IcmpTypeCriterion.class); assertThatClassIsImmutable(IcmpCodeCriterion.class); @@ -395,8 +415,8 @@ public class CriteriaTest { Criterion matchEthDst = Criteria.matchEthDst(mac1); EthCriterion ethCriterion = checkAndConvert(matchEthDst, - Criterion.Type.ETH_DST, - EthCriterion.class); + Criterion.Type.ETH_DST, + EthCriterion.class); assertThat(ethCriterion.mac(), is(equalTo(mac1))); } @@ -461,8 +481,8 @@ public class CriteriaTest { Criterion matchVlanId = Criteria.matchVlanId(vlanId1); VlanIdCriterion vlanIdCriterion = checkAndConvert(matchVlanId, - Criterion.Type.VLAN_VID, - VlanIdCriterion.class); + Criterion.Type.VLAN_VID, + VlanIdCriterion.class); assertThat(vlanIdCriterion.vlanId(), is(equalTo(vlanId1))); } @@ -487,8 +507,8 @@ public class CriteriaTest { Criterion matchVlanPcp = Criteria.matchVlanPcp(vlanPcp1); VlanPcpCriterion vlanPcpCriterion = checkAndConvert(matchVlanPcp, - Criterion.Type.VLAN_PCP, - VlanPcpCriterion.class); + Criterion.Type.VLAN_PCP, + VlanPcpCriterion.class); assertThat(vlanPcpCriterion.priority(), is(equalTo(vlanPcp1))); } @@ -513,8 +533,8 @@ public class CriteriaTest { Criterion matchIPDscp = Criteria.matchIPDscp(ipDscp1); IPDscpCriterion ipDscpCriterion = checkAndConvert(matchIPDscp, - Criterion.Type.IP_DSCP, - IPDscpCriterion.class); + Criterion.Type.IP_DSCP, + IPDscpCriterion.class); assertThat(ipDscpCriterion.ipDscp(), is(equalTo(ipDscp1))); } @@ -539,8 +559,8 @@ public class CriteriaTest { Criterion matchIPEcn = Criteria.matchIPEcn(ipEcn1); IPEcnCriterion ipEcnCriterion = checkAndConvert(matchIPEcn, - Criterion.Type.IP_ECN, - IPEcnCriterion.class); + Criterion.Type.IP_ECN, + IPEcnCriterion.class); assertThat(ipEcnCriterion.ipEcn(), is(equalTo(ipEcn1))); } @@ -565,8 +585,8 @@ public class CriteriaTest { Criterion matchIPProtocol = Criteria.matchIPProtocol(protocol1); IPProtocolCriterion ipProtocolCriterion = checkAndConvert(matchIPProtocol, - Criterion.Type.IP_PROTO, - IPProtocolCriterion.class); + Criterion.Type.IP_PROTO, + IPProtocolCriterion.class); assertThat(ipProtocolCriterion.protocol(), is(equalTo(protocol1))); } @@ -604,8 +624,8 @@ public class CriteriaTest { Criterion matchIPDst = Criteria.matchIPDst(ip1); IPCriterion ipCriterion = checkAndConvert(matchIPDst, - Criterion.Type.IPV4_DST, - IPCriterion.class); + Criterion.Type.IPV4_DST, + IPCriterion.class); assertThat(ipCriterion.ip(), is(equalTo(ip1))); } @@ -617,8 +637,8 @@ public class CriteriaTest { Criterion matchIpv6Src = Criteria.matchIPv6Src(ipv61); IPCriterion ipCriterion = checkAndConvert(matchIpv6Src, - Criterion.Type.IPV6_SRC, - IPCriterion.class); + Criterion.Type.IPV6_SRC, + IPCriterion.class); assertThat(ipCriterion.ip(), is(ipv61)); } @@ -630,8 +650,8 @@ public class CriteriaTest { Criterion matchIPv6Dst = Criteria.matchIPv6Dst(ipv61); IPCriterion ipCriterion = checkAndConvert(matchIPv6Dst, - Criterion.Type.IPV6_DST, - IPCriterion.class); + Criterion.Type.IPV6_DST, + IPCriterion.class); assertThat(ipCriterion.ip(), is(equalTo(ipv61))); } @@ -674,8 +694,8 @@ public class CriteriaTest { Criterion matchTcpDst = Criteria.matchTcpDst(tpPort1); TcpPortCriterion tcpPortCriterion = checkAndConvert(matchTcpDst, - Criterion.Type.TCP_DST, - TcpPortCriterion.class); + Criterion.Type.TCP_DST, + TcpPortCriterion.class); assertThat(tcpPortCriterion.tcpPort(), is(equalTo(tpPort1))); } @@ -713,8 +733,8 @@ public class CriteriaTest { Criterion matchUdpDst = Criteria.matchUdpDst(tpPort1); UdpPortCriterion udpPortCriterion = checkAndConvert(matchUdpDst, - Criterion.Type.UDP_DST, - UdpPortCriterion.class); + Criterion.Type.UDP_DST, + UdpPortCriterion.class); assertThat(udpPortCriterion.udpPort(), is(equalTo(tpPort1))); } @@ -729,6 +749,19 @@ public class CriteriaTest { .testEquals(); } + // TcpFlagsCriterion class + + /** + * Test the equals() method of the TcpFlagsCriterion class. + */ + @Test + public void testTcpFlagsCriterionEquals() { + new EqualsTester() + .addEqualityGroup(matchTcpFlags1, sameAsmatchTcpFlags1) + .addEqualityGroup(matchTcpFlags2) + .testEquals(); + } + // SctpPortCriterion class /** @@ -752,8 +785,8 @@ public class CriteriaTest { Criterion matchSctpDst = Criteria.matchSctpDst(tpPort1); SctpPortCriterion sctpPortCriterion = checkAndConvert(matchSctpDst, - Criterion.Type.SCTP_DST, - SctpPortCriterion.class); + Criterion.Type.SCTP_DST, + SctpPortCriterion.class); assertThat(sctpPortCriterion.sctpPort(), is(equalTo(tpPort1))); } @@ -911,7 +944,7 @@ public class CriteriaTest { @Test public void testMatchIPv6NDTargetAddressMethod() { Criterion matchTargetAddress = - Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1); + Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1); IPv6NDTargetAddressCriterion targetAddressCriterion = checkAndConvert(matchTargetAddress, Criterion.Type.IPV6_ND_TARGET, @@ -940,11 +973,11 @@ public class CriteriaTest { @Test public void testMatchIPv6NDSourceLinkLayerAddressMethod() { Criterion matchSrcLlAddr = - Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1); + Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1); IPv6NDLinkLayerAddressCriterion srcLlCriterion = checkAndConvert(matchSrcLlAddr, - Criterion.Type.IPV6_ND_SLL, - IPv6NDLinkLayerAddressCriterion.class); + Criterion.Type.IPV6_ND_SLL, + IPv6NDLinkLayerAddressCriterion.class); assertThat(srcLlCriterion.mac(), is(equalTo(llMac1))); } @@ -954,11 +987,11 @@ public class CriteriaTest { @Test public void testMatchIPv6NDTargetLinkLayerAddressMethod() { Criterion matchTargetLlAddr = - Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1); + Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1); IPv6NDLinkLayerAddressCriterion targetLlCriterion = checkAndConvert(matchTargetLlAddr, - Criterion.Type.IPV6_ND_TLL, - IPv6NDLinkLayerAddressCriterion.class); + Criterion.Type.IPV6_ND_TLL, + IPv6NDLinkLayerAddressCriterion.class); assertThat(targetLlCriterion.mac(), is(equalTo(llMac1))); } @@ -988,8 +1021,8 @@ public class CriteriaTest { Criterion matchMplsLabel = Criteria.matchMplsLabel(mpls1); MplsCriterion mplsCriterion = checkAndConvert(matchMplsLabel, - Criterion.Type.MPLS_LABEL, - MplsCriterion.class); + Criterion.Type.MPLS_LABEL, + MplsCriterion.class); assertThat(mplsCriterion.label(), is(equalTo(mpls1))); } @@ -1025,10 +1058,10 @@ public class CriteriaTest { */ @Test public void testTunnelIdCriterionEquals() { - new EqualsTester() - .addEqualityGroup(matchTunnelId1, sameAsMatchTunnelId1) - .addEqualityGroup(matchTunnelId2) - .testEquals(); + new EqualsTester() + .addEqualityGroup(matchTunnelId1, sameAsMatchTunnelId1) + .addEqualityGroup(matchTunnelId2) + .testEquals(); } // IPv6ExthdrFlagsCriterion class @@ -1039,11 +1072,11 @@ public class CriteriaTest { @Test public void testMatchIPv6ExthdrFlagsMethod() { Criterion matchExthdrFlags = - Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1); + Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1); IPv6ExthdrFlagsCriterion exthdrFlagsCriterion = checkAndConvert(matchExthdrFlags, - Criterion.Type.IPV6_EXTHDR, - IPv6ExthdrFlagsCriterion.class); + Criterion.Type.IPV6_EXTHDR, + IPv6ExthdrFlagsCriterion.class); assertThat(exthdrFlagsCriterion.exthdrFlags(), is(equalTo(ipv6ExthdrFlags1))); } diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java index 88fa7f4f..dd371c15 100644 --- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java +++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java @@ -22,11 +22,11 @@ import java.util.Set; import org.junit.Test; import org.onosproject.net.ConnectPoint; +import org.onosproject.net.IndexedLambda; import org.onosproject.net.Link; import org.onosproject.net.NetTestTools; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.intent.constraint.LambdaConstraint; -import org.onosproject.net.resource.link.LambdaResource; import com.google.common.collect.ImmutableSet; import com.google.common.testing.EqualsTester; @@ -132,7 +132,7 @@ public class LinkCollectionIntentTest extends IntentTest { final LinkedList constraints = new LinkedList<>(); links1.add(link("src", 1, "dst", 2)); - constraints.add(new LambdaConstraint(LambdaResource.valueOf(23))); + constraints.add(new LambdaConstraint(new IndexedLambda(23))); final LinkCollectionIntent collectionIntent = LinkCollectionIntent.builder() .appId(APP_ID) diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/constraint/ConstraintObjectsTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/constraint/ConstraintObjectsTest.java index 743fc252..d2e99400 100644 --- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/constraint/ConstraintObjectsTest.java +++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/constraint/ConstraintObjectsTest.java @@ -17,9 +17,8 @@ package org.onosproject.net.intent.constraint; import org.junit.Test; import org.onlab.util.Bandwidth; +import org.onosproject.net.IndexedLambda; import org.onosproject.net.Link; -import org.onosproject.net.resource.link.BandwidthResource; -import org.onosproject.net.resource.link.LambdaResource; import com.google.common.testing.EqualsTester; @@ -39,21 +38,18 @@ public class ConstraintObjectsTest { private final Bandwidth sameAsBandwidth1 = Bandwidth.bps(100.0); private final Bandwidth bandwidth2 = Bandwidth.bps(200.0); - final BandwidthConstraint bandwidthConstraint1 = - new BandwidthConstraint(new BandwidthResource(bandwidth1)); - final BandwidthConstraint bandwidthConstraintSameAs1 = - new BandwidthConstraint(new BandwidthResource(sameAsBandwidth1)); - final BandwidthConstraint bandwidthConstraint2 = - new BandwidthConstraint(new BandwidthResource(bandwidth2)); + final BandwidthConstraint bandwidthConstraint1 = new BandwidthConstraint(bandwidth1); + final BandwidthConstraint bandwidthConstraintSameAs1 = new BandwidthConstraint(sameAsBandwidth1); + final BandwidthConstraint bandwidthConstraint2 = new BandwidthConstraint(bandwidth2); /** * Checks that the objects were created properly. */ @Test public void testBandwidthConstraintCreation() { - assertThat(bandwidthConstraint1.bandwidth().toDouble(), is(equalTo(100.0))); - assertThat(bandwidthConstraintSameAs1.bandwidth().toDouble(), is(equalTo(100.0))); - assertThat(bandwidthConstraint2.bandwidth().toDouble(), is(equalTo(200.0))); + assertThat(bandwidthConstraint1.bandwidth().bps(), is(equalTo(100.0))); + assertThat(bandwidthConstraintSameAs1.bandwidth().bps(), is(equalTo(100.0))); + assertThat(bandwidthConstraint2.bandwidth().bps(), is(equalTo(200.0))); } /** @@ -70,20 +66,20 @@ public class ConstraintObjectsTest { // Lambda Constraint final LambdaConstraint lambdaConstraint1 = - new LambdaConstraint(LambdaResource.valueOf(100)); + new LambdaConstraint(new IndexedLambda(100)); final LambdaConstraint lambdaConstraintSameAs1 = - new LambdaConstraint(LambdaResource.valueOf(100)); + new LambdaConstraint(new IndexedLambda(100)); final LambdaConstraint lambdaConstraint2 = - new LambdaConstraint(LambdaResource.valueOf(200)); + new LambdaConstraint(new IndexedLambda(200)); /** * Checks that the objects were created properly. */ @Test public void testLambdaConstraintCreation() { - assertThat(lambdaConstraint1.lambda().toInt(), is(equalTo(100))); - assertThat(lambdaConstraintSameAs1.lambda().toInt(), is(equalTo(100))); - assertThat(lambdaConstraint2.lambda().toInt(), is(equalTo(200))); + assertThat(lambdaConstraint1.lambda().index(), is(equalTo(100L))); + assertThat(lambdaConstraintSameAs1.lambda().index(), is(equalTo(100L))); + assertThat(lambdaConstraint2.lambda().index(), is(equalTo(200L))); } /** diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java index 3433b3b7..c7af4e5b 100644 --- a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java @@ -38,6 +38,7 @@ import org.onosproject.net.driver.Driver; import org.onosproject.net.flow.FlowEntry; import org.onosproject.net.flow.FlowRule; import org.onosproject.net.flow.TableStatisticsEntry; +import org.onosproject.net.device.PortStatistics; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flow.criteria.Criterion; @@ -102,6 +103,7 @@ public class CodecManager implements CodecService { registerCodec(GroupBucket.class, new GroupBucketCodec()); registerCodec(Load.class, new LoadCodec()); registerCodec(TableStatisticsEntry.class, new TableStatisticsEntryCodec()); + registerCodec(PortStatistics.class, new PortStatisticsCodec()); log.info("Started"); } diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/DecodeConstraintCodecHelper.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/DecodeConstraintCodecHelper.java index 5746003c..40c553d9 100644 --- a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/DecodeConstraintCodecHelper.java +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/DecodeConstraintCodecHelper.java @@ -32,8 +32,6 @@ import org.onosproject.net.intent.constraint.LatencyConstraint; import org.onosproject.net.intent.constraint.LinkTypeConstraint; import org.onosproject.net.intent.constraint.ObstacleConstraint; import org.onosproject.net.intent.constraint.WaypointConstraint; -import org.onosproject.net.resource.link.BandwidthResource; -import org.onosproject.net.resource.link.LambdaResource; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -106,7 +104,7 @@ public final class DecodeConstraintCodecHelper { ConstraintCodec.LAMBDA + ConstraintCodec.MISSING_MEMBER_MESSAGE) .asLong(); - return new LambdaConstraint(LambdaResource.valueOf(new IndexedLambda(lambda))); + return new LambdaConstraint(new IndexedLambda(lambda)); } /** @@ -185,7 +183,7 @@ public final class DecodeConstraintCodecHelper { ConstraintCodec.BANDWIDTH + ConstraintCodec.MISSING_MEMBER_MESSAGE) .asDouble(); - return new BandwidthConstraint(new BandwidthResource(Bandwidth.bps(bandwidth))); + return new BandwidthConstraint(Bandwidth.bps(bandwidth)); } /** diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/DecodeCriterionCodecHelper.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/DecodeCriterionCodecHelper.java index 69c5e791..88cc3328 100644 --- a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/DecodeCriterionCodecHelper.java +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/DecodeCriterionCodecHelper.java @@ -15,11 +15,8 @@ */ package org.onosproject.codec.impl; -import static org.onlab.util.Tools.nullIsIllegal; - -import java.util.HashMap; -import java.util.Map; - +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.onlab.packet.Ip6Address; import org.onlab.packet.IpPrefix; import org.onlab.packet.MacAddress; @@ -37,8 +34,10 @@ import org.onosproject.net.PortNumber; import org.onosproject.net.flow.criteria.Criteria; import org.onosproject.net.flow.criteria.Criterion; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import java.util.HashMap; +import java.util.Map; + +import static org.onlab.util.Tools.nullIsIllegal; /** * Decode portion of the criterion codec. @@ -106,12 +105,16 @@ public final class DecodeCriterionCodecHelper { private class EthTypeDecoder implements CriterionDecoder { @Override public Criterion decodeCriterion(ObjectNode json) { - int ethType = nullIsIllegal(json.get(CriterionCodec.ETH_TYPE), - CriterionCodec.ETH_TYPE + MISSING_MEMBER_MESSAGE).asInt(); + int ethType; + if (json.get(CriterionCodec.ETH_TYPE).isInt()) { + ethType = nullIsIllegal(json.get(CriterionCodec.ETH_TYPE), + CriterionCodec.ETH_TYPE + MISSING_MEMBER_MESSAGE).asInt(); + } else { + ethType = Integer.decode(json.get(CriterionCodec.ETH_TYPE).textValue()); + } return Criteria.matchEthType(ethType); } } - private class EthDstDecoder implements CriterionDecoder { @Override public Criterion decodeCriterion(ObjectNode json) { diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeConstraintCodecHelper.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeConstraintCodecHelper.java index 61f4dbf4..ec4ee444 100644 --- a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeConstraintCodecHelper.java +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeConstraintCodecHelper.java @@ -128,7 +128,7 @@ public final class EncodeConstraintCodecHelper { final BandwidthConstraint bandwidthConstraint = (BandwidthConstraint) constraint; return context.mapper().createObjectNode() - .put("bandwidth", bandwidthConstraint.bandwidth().toDouble()); + .put("bandwidth", bandwidthConstraint.bandwidth().bps()); } /** @@ -142,7 +142,7 @@ public final class EncodeConstraintCodecHelper { (LambdaConstraint) constraint; return context.mapper().createObjectNode() - .put("lambda", lambdaConstraint.lambda().toInt()); + .put("lambda", lambdaConstraint.lambda().index()); } /** diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java index 8fc6bbcf..33dd46a3 100644 --- a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java @@ -15,8 +15,7 @@ */ package org.onosproject.codec.impl; -import java.util.EnumMap; - +import com.fasterxml.jackson.databind.node.ObjectNode; import org.onlab.util.HexString; import org.onosproject.codec.CodecContext; import org.onosproject.net.OchSignal; @@ -50,7 +49,7 @@ import org.onosproject.net.flow.criteria.UdpPortCriterion; import org.onosproject.net.flow.criteria.VlanIdCriterion; import org.onosproject.net.flow.criteria.VlanPcpCriterion; -import com.fasterxml.jackson.databind.node.ObjectNode; +import java.util.EnumMap; import static com.google.common.base.Preconditions.checkNotNull; @@ -69,7 +68,7 @@ public final class EncodeCriterionCodecHelper { * Initializes the formatter lookup map for the criterion subclasses. * * @param criterion Criterion to encode - * @param context context of the JSON encoding + * @param context context of the JSON encoding */ public EncodeCriterionCodecHelper(Criterion criterion, CodecContext context) { this.criterion = criterion; @@ -171,7 +170,8 @@ public final class EncodeCriterionCodecHelper { public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) { final EthTypeCriterion ethTypeCriterion = (EthTypeCriterion) criterion; - return root.put(CriterionCodec.ETH_TYPE, ethTypeCriterion.ethType().toShort()); + return root.put(CriterionCodec.ETH_TYPE, "0x" + + Integer.toHexString(ethTypeCriterion.ethType().toShort() & 0xffff)); } } diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/FlowEntryCodec.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/FlowEntryCodec.java index 923bdf2b..3f581bed 100644 --- a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/FlowEntryCodec.java +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/FlowEntryCodec.java @@ -39,6 +39,7 @@ public final class FlowEntryCodec extends JsonCodec { final ObjectNode result = context.mapper().createObjectNode() .put("id", Long.toString(flowEntry.id().value())) + .put("tableId", flowEntry.tableId()) .put("appId", service.getAppId(flowEntry.appId()).name()) .put("groupId", flowEntry.groupId().id()) .put("priority", flowEntry.priority()) diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/PortStatisticsCodec.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/PortStatisticsCodec.java new file mode 100644 index 00000000..e8b3c4c6 --- /dev/null +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/PortStatisticsCodec.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.codec.impl; + +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.net.device.PortStatistics; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Port statistics entry JSON codec. + */ +public final class PortStatisticsCodec extends JsonCodec { + + @Override + public ObjectNode encode(PortStatistics entry, CodecContext context) { + checkNotNull(entry, "Port Statistics cannot be null"); + + final ObjectNode result = context.mapper().createObjectNode() + .put("port", entry.port()) + .put("packetsReceived", entry.packetsReceived()) + .put("packetsSent", entry.packetsSent()) + .put("bytesReceived", entry.bytesReceived()) + .put("bytesSent", entry.bytesSent()) + .put("packetsRxDropped", entry.packetsRxDropped()) + .put("packetsTxDropped", entry.packetsTxDropped()) + .put("packetsRxErrors", entry.packetsRxErrors()) + .put("packetsTxErrors", entry.packetsTxErrors()) + .put("durationSec", entry.durationSec()); + + return result; + } + +} + diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/ConstraintCodecTest.java b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/ConstraintCodecTest.java index 2a47d115..a84dab48 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/ConstraintCodecTest.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/ConstraintCodecTest.java @@ -134,7 +134,7 @@ public class ConstraintCodecTest { assertThat(constraint, instanceOf(BandwidthConstraint.class)); BandwidthConstraint bandwidthConstraint = (BandwidthConstraint) constraint; - assertThat(bandwidthConstraint.bandwidth().toDouble(), is(345.678D)); + assertThat(bandwidthConstraint.bandwidth().bps(), is(345.678D)); } /** @@ -146,7 +146,7 @@ public class ConstraintCodecTest { assertThat(constraint, instanceOf(LambdaConstraint.class)); LambdaConstraint lambdaConstraint = (LambdaConstraint) constraint; - assertThat(lambdaConstraint.lambda().toInt(), is(444)); + assertThat(lambdaConstraint.lambda().index(), is(444L)); } /** diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java index b00632c3..7d8580a6 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java @@ -138,8 +138,8 @@ public final class CriterionJsonMatcher extends * @return true if the JSON matches the criterion, false otherwise. */ private boolean matchCriterion(EthTypeCriterion criterion) { - final int ethType = criterion.ethType().toShort(); - final int jsonEthType = jsonCriterion.get("ethType").intValue(); + final int ethType = criterion.ethType().toShort() & 0xffff; + final int jsonEthType = Integer.decode(jsonCriterion.get("ethType").textValue()) & 0xffff; if (ethType != jsonEthType) { description.appendText("ethType was " + Integer.toString(jsonEthType)); diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java index 2f933966..596c7ef9 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java @@ -63,8 +63,6 @@ import org.onosproject.net.intent.constraint.LambdaConstraint; import org.onosproject.net.intent.constraint.LatencyConstraint; import org.onosproject.net.intent.constraint.ObstacleConstraint; import org.onosproject.net.intent.constraint.WaypointConstraint; -import org.onosproject.net.resource.link.BandwidthResource; -import org.onosproject.net.resource.link.LambdaResource; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -181,8 +179,8 @@ public class IntentCodecTest extends AbstractIntentTest { final List constraints = ImmutableList.of( - new BandwidthConstraint(new BandwidthResource(Bandwidth.bps(1.0))), - new LambdaConstraint(LambdaResource.valueOf(3)), + new BandwidthConstraint(Bandwidth.bps(1.0)), + new LambdaConstraint(new IndexedLambda(3)), new AnnotationConstraint("key", 33.0), new AsymmetricPathConstraint(), new LatencyConstraint(Duration.ofSeconds(2)), diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentJsonMatcher.java b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentJsonMatcher.java index e485a5fa..acc1f0e8 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentJsonMatcher.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentJsonMatcher.java @@ -141,7 +141,7 @@ public final class IntentJsonMatcher extends TypeSafeDiagnosingMatcher final JsonNode bandwidthJson = constraintJson.get("bandwidth"); return bandwidthJson != null && constraintJson.get("bandwidth").asDouble() - == bandwidthConstraint.bandwidth().toDouble(); + == bandwidthConstraint.bandwidth().bps(); } /** @@ -157,7 +157,7 @@ public final class IntentJsonMatcher extends TypeSafeDiagnosingMatcher final JsonNode lambdaJson = constraintJson.get("lambda"); return lambdaJson != null && constraintJson.get("lambda").asInt() - == lambdaConstraint.lambda().toInt(); + == lambdaConstraint.lambda().index(); } /** diff --git a/framework/src/onos/core/common/src/test/resources/org/onosproject/codec/impl/criteria-flow.json b/framework/src/onos/core/common/src/test/resources/org/onosproject/codec/impl/criteria-flow.json index ccb2e161..82c0f59d 100644 --- a/framework/src/onos/core/common/src/test/resources/org/onosproject/codec/impl/criteria-flow.json +++ b/framework/src/onos/core/common/src/test/resources/org/onosproject/codec/impl/criteria-flow.json @@ -9,7 +9,7 @@ {"type":"IN_PORT", "port":23}, {"type":"IN_PHY_PORT", "port":44}, {"type":"METADATA", "metadata":123456}, - {"type":"ETH_TYPE","ethType":2054}, + {"type":"ETH_TYPE","ethType":"0x806"}, {"type":"ETH_SRC","mac":"00:11:22:33:44:55"}, {"type":"ETH_DST","mac":"00:11:22:33:44:55"}, {"type":"VLAN_VID","vlanId":777}, diff --git a/framework/src/onos/core/common/src/test/resources/org/onosproject/codec/impl/instructions-flow.json b/framework/src/onos/core/common/src/test/resources/org/onosproject/codec/impl/instructions-flow.json index 74b9546a..2a184b34 100644 --- a/framework/src/onos/core/common/src/test/resources/org/onosproject/codec/impl/instructions-flow.json +++ b/framework/src/onos/core/common/src/test/resources/org/onosproject/codec/impl/instructions-flow.json @@ -35,5 +35,5 @@ ], "deferred":[] }, - "selector": {"criteria":[{"type":"ETH_TYPE","ethType":2054}]} + "selector": {"criteria":[{"type":"ETH_TYPE","ethType":"0x806"}]} } diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java index d09eb1f1..80a5ca77 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java @@ -237,12 +237,22 @@ public class ApplicationManager boolean changed = false; for (String name : app.features()) { Feature feature = featuresService.getFeature(name); + + // If we see an attempt at activation of a non-existent feature + // attempt to install the app artifacts first and then retry. + // This can be triggered by a race condition between different ONOS + // instances "installing" the apps from disk at their own pace. + // Perhaps there is a more elegant solution to be explored in the + // future. + if (feature == null) { + installAppArtifacts(app); + feature = featuresService.getFeature(name); + } + if (feature != null && !featuresService.isInstalled(feature)) { featuresService.installFeature(name); changed = true; - } else if (feature == null && !initializing) { - // Suppress feature-not-found reporting during startup since these - // can arise naturally from the staggered cluster install. + } else if (feature == null) { log.warn("Feature {} not found", name); } } diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java index a76a298f..5ecdc7a2 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java @@ -54,6 +54,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -226,10 +227,11 @@ public class FlowObjectiveManager implements FlowObjectiveService { if (fwd.nextId() != null && flowObjectiveStore.getNextGroup(fwd.nextId()) == null) { log.trace("Queuing forwarding objective for nextId {}", fwd.nextId()); - if (pendingForwards.putIfAbsent(fwd.nextId(), - Sets.newHashSet(new PendingNext(deviceId, fwd))) != null) { - Set pending = pendingForwards.get(fwd.nextId()); - pending.add(new PendingNext(deviceId, fwd)); + // TODO: change to computeIfAbsent + Set pnext = pendingForwards.putIfAbsent(fwd.nextId(), + Sets.newHashSet(new PendingNext(deviceId, fwd))); + if (pnext != null) { + pnext.add(new PendingNext(deviceId, fwd)); } return true; } @@ -412,5 +414,26 @@ public class FlowObjectiveManager implements FlowObjectiveService { public ForwardingObjective forwardingObjective() { return fwd; } + + @Override + public int hashCode() { + return Objects.hash(deviceId, fwd); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PendingNext)) { + return false; + } + final PendingNext other = (PendingNext) obj; + if (this.deviceId.equals(other.deviceId) && + this.fwd.equals(other.fwd)) { + return true; + } + return false; + } } } diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java index 4dc93a51..5fb1dcf1 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java @@ -168,7 +168,9 @@ public class HostMonitor implements TimerTask { } } - this.timeout = Timer.getTimer().newTimeout(this, probeRate, TimeUnit.MILLISECONDS); + synchronized (this) { + this.timeout = Timer.getTimer().newTimeout(this, probeRate, TimeUnit.MILLISECONDS); + } } /** diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java index a4ed551a..2941ddba 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java @@ -189,6 +189,7 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler allocations = resourceService.allocate(intent.id(), lambdaResources); if (allocations.isEmpty()) { log.info("Resource allocation for {} failed (resource request: {})", intent, lambdaResources); + return null; } return minLambda; diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java index 066dd33e..4fb0d7ba 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java @@ -15,14 +15,23 @@ */ package org.onosproject.net.newresource.impl; +import com.google.common.collect.Lists; import org.onosproject.net.Device; import org.onosproject.net.Port; +import org.onosproject.net.OchPort; +import org.onosproject.net.TributarySlot; +import org.onosproject.net.OduSignalType; import org.onosproject.net.device.DeviceEvent; import org.onosproject.net.device.DeviceListener; import org.onosproject.net.newresource.ResourceAdminService; import org.onosproject.net.newresource.ResourcePath; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.List; import java.util.concurrent.ExecutorService; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import static com.google.common.base.Preconditions.checkNotNull; @@ -31,6 +40,13 @@ import static com.google.common.base.Preconditions.checkNotNull; */ final class ResourceDeviceListener implements DeviceListener { + private static final Logger log = LoggerFactory.getLogger(ResourceDeviceListener.class); + + private static final int TOTAL_ODU2_TRIBUTARY_SLOTS = 8; + private static final int TOTAL_ODU4_TRIBUTARY_SLOTS = 80; + private static final List ENTIRE_ODU2_TRIBUTARY_SLOTS = getEntireOdu2TributarySlots(); + private static final List ENTIRE_ODU4_TRIBUTARY_SLOTS = getEntireOdu4TributarySlots(); + private final ResourceAdminService adminService; private final ExecutorService executor; @@ -67,20 +83,56 @@ final class ResourceDeviceListener implements DeviceListener { } private void registerDeviceResource(Device device) { - executor.submit(() -> adminService.registerResources(ResourcePath.ROOT, device.id())); + executor.submit(() -> adminService.registerResources(ResourcePath.discrete(device.id()))); } private void unregisterDeviceResource(Device device) { - executor.submit(() -> adminService.unregisterResources(ResourcePath.ROOT, device.id())); + executor.submit(() -> adminService.unregisterResources(ResourcePath.discrete(device.id()))); } private void registerPortResource(Device device, Port port) { - ResourcePath parent = ResourcePath.discrete(device.id()); - executor.submit(() -> adminService.registerResources(parent, port.number())); + ResourcePath portPath = ResourcePath.discrete(device.id(), port.number()); + executor.submit(() -> { + adminService.registerResources(portPath); + + switch (port.type()) { + case OCH: + // register ODU TributarySlots against the OCH port + registerTributarySlotsResources(((OchPort) port).signalType(), portPath); + break; + default: + break; + } + }); + } + + private void registerTributarySlotsResources(OduSignalType oduSignalType, ResourcePath portPath) { + switch (oduSignalType) { + case ODU2: + adminService.registerResources(Lists.transform(ENTIRE_ODU2_TRIBUTARY_SLOTS, portPath::child)); + break; + case ODU4: + adminService.registerResources(Lists.transform(ENTIRE_ODU4_TRIBUTARY_SLOTS, portPath::child)); + break; + default: + break; + } } private void unregisterPortResource(Device device, Port port) { - ResourcePath parent = ResourcePath.discrete(device.id()); - executor.submit(() -> adminService.unregisterResources(parent, port.number())); + ResourcePath resource = ResourcePath.discrete(device.id(), port.number()); + executor.submit(() -> adminService.unregisterResources(resource)); } + + private static List getEntireOdu2TributarySlots() { + return IntStream.rangeClosed(1, TOTAL_ODU2_TRIBUTARY_SLOTS) + .mapToObj(x -> TributarySlot.of(x)) + .collect(Collectors.toList()); + } + private static List getEntireOdu4TributarySlots() { + return IntStream.rangeClosed(1, TOTAL_ODU4_TRIBUTARY_SLOTS) + .mapToObj(x -> TributarySlot.of(x)) + .collect(Collectors.toList()); + } + } diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java index 68fd6612..9d2e06f5 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java @@ -15,6 +15,7 @@ */ package org.onosproject.net.newresource.impl; +import com.google.common.collect.Lists; import org.onlab.packet.MplsLabel; import org.onlab.packet.VlanId; import org.onlab.util.ItemNotFoundException; @@ -85,24 +86,24 @@ final class ResourceLinkListener implements LinkListener { executor.submit(() -> { // register the link LinkKey linkKey = LinkKey.linkKey(link); - adminService.registerResources(ResourcePath.ROOT, linkKey); + adminService.registerResources(ResourcePath.discrete(linkKey)); ResourcePath linkPath = ResourcePath.discrete(linkKey); // register VLAN IDs against the link if (isEnabled(link, this::isVlanEnabled)) { - adminService.registerResources(linkPath, ENTIRE_VLAN_IDS); + adminService.registerResources(Lists.transform(ENTIRE_VLAN_IDS, linkPath::child)); } // register MPLS labels against the link if (isEnabled(link, this::isMplsEnabled)) { - adminService.registerResources(linkPath, ENTIRE_MPLS_LABELS); + adminService.registerResources(Lists.transform(ENTIRE_MPLS_LABELS, linkPath::child)); } }); } private void unregisterLinkResource(Link link) { LinkKey linkKey = LinkKey.linkKey(link); - executor.submit(() -> adminService.unregisterResources(ResourcePath.ROOT, linkKey)); + executor.submit(() -> adminService.unregisterResources(ResourcePath.discrete(linkKey))); } private boolean isEnabled(Link link, Predicate predicate) { diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java index 1c6930bb..3014951a 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java @@ -17,7 +17,6 @@ package org.onosproject.net.newresource.impl; import com.google.common.annotations.Beta; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; @@ -41,7 +40,6 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; /** @@ -164,23 +162,17 @@ public final class ResourceManager extends AbstractListenerManager boolean registerResources(ResourcePath parent, List children) { - checkNotNull(parent); - checkNotNull(children); - checkArgument(!children.isEmpty()); + public boolean registerResources(List resources) { + checkNotNull(resources); - List resources = Lists.transform(children, parent::child); return store.register(resources); } @Override - public boolean unregisterResources(ResourcePath parent, List children) { - checkNotNull(parent); - checkNotNull(children); - checkArgument(!children.isEmpty()); + public boolean unregisterResources(List resources) { + checkNotNull(resources); - List resources = Lists.transform(children, parent::child); - return store.unregister(resources); + return store.register(resources); } private class InternalStoreDelegate implements ResourceStoreDelegate { diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompilerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompilerTest.java index e57d9dbe..5d7b5c8d 100644 --- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompilerTest.java +++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompilerTest.java @@ -21,6 +21,7 @@ import org.onlab.util.Bandwidth; import org.onosproject.TestApplicationId; import org.onosproject.core.ApplicationId; import org.onosproject.net.ConnectPoint; +import org.onosproject.net.IndexedLambda; import org.onosproject.net.Link; import org.onosproject.net.Path; import org.onosproject.net.flow.TrafficSelector; @@ -34,8 +35,6 @@ import org.onosproject.net.intent.PointToPointIntent; import org.onosproject.net.intent.constraint.BandwidthConstraint; import org.onosproject.net.intent.constraint.LambdaConstraint; import org.onosproject.net.intent.impl.PathNotFoundException; -import org.onosproject.net.resource.link.BandwidthResource; -import org.onosproject.net.resource.link.LambdaResource; import org.onosproject.net.resource.link.LinkResourceService; import java.util.Collections; @@ -229,7 +228,7 @@ public class PointToPointIntentCompilerTest extends AbstractIntentTest { final LinkResourceService resourceService = IntentTestsMocks.MockResourceService.makeBandwidthResourceService(1000.0); final List constraints = - Collections.singletonList(new BandwidthConstraint(new BandwidthResource(Bandwidth.bps(100.0)))); + Collections.singletonList(new BandwidthConstraint(Bandwidth.bps(100.0))); final PointToPointIntent intent = makeIntent("s1", "s3", constraints); @@ -251,7 +250,7 @@ public class PointToPointIntentCompilerTest extends AbstractIntentTest { final LinkResourceService resourceService = IntentTestsMocks.MockResourceService.makeBandwidthResourceService(10.0); final List constraints = - Collections.singletonList(new BandwidthConstraint(new BandwidthResource(Bandwidth.bps(100.0)))); + Collections.singletonList(new BandwidthConstraint(Bandwidth.bps(100.0))); try { final PointToPointIntent intent = makeIntent("s1", "s3", constraints); @@ -275,7 +274,7 @@ public class PointToPointIntentCompilerTest extends AbstractIntentTest { public void testLambdaConstrainedIntentSuccess() { final List constraints = - Collections.singletonList(new LambdaConstraint(LambdaResource.valueOf(1))); + Collections.singletonList(new LambdaConstraint(new IndexedLambda(1))); final LinkResourceService resourceService = IntentTestsMocks.MockResourceService.makeLambdaResourceService(1); @@ -299,7 +298,7 @@ public class PointToPointIntentCompilerTest extends AbstractIntentTest { public void testLambdaConstrainedIntentFailure() { final List constraints = - Collections.singletonList(new LambdaConstraint(LambdaResource.valueOf(1))); + Collections.singletonList(new LambdaConstraint(new IndexedLambda(1))); final LinkResourceService resourceService = IntentTestsMocks.MockResourceService.makeBandwidthResourceService(10.0); try { diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java index d61d7dcf..ca6f9c1c 100644 --- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java +++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java @@ -48,7 +48,8 @@ public class NettyMessagingManager extends NettyMessaging { public void activate() throws Exception { ControllerNode localNode = clusterMetadataService.getLocalNode(); getTlsParameters(); - super.start(new Endpoint(localNode.ip(), localNode.tcpPort())); + super.start(clusterMetadataService.getClusterMetadata().getName().hashCode(), + new Endpoint(localNode.ip(), localNode.tcpPort())); log.info("Started"); } diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java index ca8eea37..27c79122 100644 --- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java +++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java @@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.node.DoubleNode; import com.fasterxml.jackson.databind.node.IntNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.LongNode; +import com.fasterxml.jackson.databind.node.NullNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ShortNode; import com.fasterxml.jackson.databind.node.TextNode; @@ -95,7 +96,8 @@ public class DistributedNetworkConfigStore .register(ConfigKey.class, ObjectNode.class, ArrayNode.class, JsonNodeFactory.class, LinkedHashMap.class, TextNode.class, BooleanNode.class, - LongNode.class, DoubleNode.class, ShortNode.class, IntNode.class); + LongNode.class, DoubleNode.class, ShortNode.class, IntNode.class, + NullNode.class); configs = storageService.consistentMapBuilder() .withSerializer(Serializer.using(kryoBuilder.build())) diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java index a999ee7f..83319c3e 100644 --- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java +++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java @@ -348,9 +348,11 @@ public class DistributedGroupStore public void storeGroupDescription(GroupDescription groupDesc) { log.debug("In storeGroupDescription"); // Check if a group is existing with the same key - if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) { - log.warn("Group already exists with the same key {}", - groupDesc.appCookie()); + Group existingGroup = getGroup(groupDesc.deviceId(), groupDesc.appCookie()); + if (existingGroup != null) { + log.warn("Group already exists with the same key {} in dev:{} with id:{}", + groupDesc.appCookie(), groupDesc.deviceId(), + Integer.toHexString(existingGroup.id().id())); return; } diff --git a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/mastership/impl/DistributedMastershipStoreTest.java b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/mastership/impl/DistributedMastershipStoreTest.java deleted file mode 100644 index 0b704011..00000000 --- a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/mastership/impl/DistributedMastershipStoreTest.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright 2014-2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.store.mastership.impl; - -/** - * Test of the Hazelcast-based distributed MastershipStore implementation. - */ -public class DistributedMastershipStoreTest { -/* - private static final DeviceId DID1 = DeviceId.deviceId("of:01"); - private static final DeviceId DID2 = DeviceId.deviceId("of:02"); - private static final DeviceId DID3 = DeviceId.deviceId("of:03"); - - private static final IpAddress IP = IpAddress.valueOf("127.0.0.1"); - - private static final NodeId N1 = new NodeId("node1"); - private static final NodeId N2 = new NodeId("node2"); - - private static final ControllerNode CN1 = new DefaultControllerNode(N1, IP); - private static final ControllerNode CN2 = new DefaultControllerNode(N2, IP); - - private DistributedMastershipStore dms; - private TestDistributedMastershipStore testStore; - private KryoSerializer serializationMgr; - private StoreManager storeMgr; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Before - public void setUp() throws Exception { - // TODO should find a way to clean Hazelcast instance without shutdown. - TestStoreManager testStoreMgr = new TestStoreManager(); - testStoreMgr.setHazelcastInstance(testStoreMgr.initSingleInstance()); - storeMgr = testStoreMgr; - storeMgr.activate(); - - serializationMgr = new KryoSerializer(); - - dms = new TestDistributedMastershipStore(storeMgr, serializationMgr); - dms.clusterService = new TestClusterService(); - dms.activate(); - - testStore = (TestDistributedMastershipStore) dms; - } - - @After - public void tearDown() throws Exception { - dms.deactivate(); - - storeMgr.deactivate(); - } - - @Test - @Ignore("Disabled this test due to intermittent failures seen on Jenkins runs") - public void getRole() { - assertEquals("wrong role:", NONE, dms.getRole(N1, DID1)); - testStore.put(DID1, N1, true, false, true); - assertEquals("wrong role:", MASTER, dms.getRole(N1, DID1)); - testStore.put(DID1, N2, false, true, false); - assertEquals("wrong role:", STANDBY, dms.getRole(N2, DID1)); - } - - @Test - public void getMaster() { - assertTrue("wrong store state:", dms.roleMap.isEmpty()); - - testStore.put(DID1, N1, true, false, false); - TestTools.assertAfter(100, () -> //wait for up to 100ms - assertEquals("wrong master:", N1, dms.getMaster(DID1))); - assertNull("wrong master:", dms.getMaster(DID2)); - } - - @Test - public void getDevices() { - assertTrue("wrong store state:", dms.roleMap.isEmpty()); - - testStore.put(DID1, N1, true, false, false); - testStore.put(DID2, N1, true, false, false); - testStore.put(DID3, N2, true, false, false); - assertEquals("wrong devices", - Sets.newHashSet(DID1, DID2), dms.getDevices(N1)); - } - - @Test - public void requestRoleAndTerm() { - //CN1 is "local" - testStore.setCurrent(CN1); - - //if already MASTER, nothing should happen - testStore.put(DID2, N1, true, false, true); - assertEquals("wrong role for MASTER:", MASTER, Futures.getUnchecked(dms.requestRole(DID2))); - - //populate maps with DID1, N1 thru NONE case - assertEquals("wrong role for NONE:", MASTER, Futures.getUnchecked(dms.requestRole(DID1))); - assertTrue("wrong state for store:", !dms.terms.isEmpty()); - assertEquals("wrong term", - MastershipTerm.of(N1, 1), dms.getTermFor(DID1)); - - //CN2 now local. DID2 has N1 as MASTER so N2 is STANDBY - testStore.setCurrent(CN2); - assertEquals("wrong role for STANDBY:", STANDBY, Futures.getUnchecked(dms.requestRole(DID2))); - assertEquals("wrong number of entries:", 2, dms.terms.size()); - - //change term and requestRole() again; should persist - testStore.increment(DID2); - assertEquals("wrong role for STANDBY:", STANDBY, Futures.getUnchecked(dms.requestRole(DID2))); - assertEquals("wrong term", MastershipTerm.of(N1, 1), dms.getTermFor(DID2)); - } - - @Test - public void setMaster() { - //populate maps with DID1, N1 as MASTER thru NONE case - testStore.setCurrent(CN1); - assertEquals("wrong role for NONE:", MASTER, Futures.getUnchecked(dms.requestRole(DID1))); - assertNull("wrong event:", Futures.getUnchecked(dms.setMaster(N1, DID1))); - - //switch over to N2 - assertEquals("wrong event:", Type.MASTER_CHANGED, Futures.getUnchecked(dms.setMaster(N2, DID1)).type()); - System.out.println(dms.getTermFor(DID1).master() + ":" + dms.getTermFor(DID1).termNumber()); - assertEquals("wrong term", MastershipTerm.of(N2, 2), dms.getTermFor(DID1)); - - //orphan switch - should be rare case - assertEquals("wrong event:", Type.MASTER_CHANGED, Futures.getUnchecked(dms.setMaster(N2, DID2)).type()); - assertEquals("wrong term", MastershipTerm.of(N2, 1), dms.getTermFor(DID2)); - //disconnect and reconnect - sign of failing re-election or single-instance channel - dms.roleMap.clear(); - dms.setMaster(N2, DID2); - assertEquals("wrong term", MastershipTerm.of(N2, 2), dms.getTermFor(DID2)); - } - - @Test - public void relinquishRole() { - //populate maps with DID1, N1 as MASTER thru NONE case - testStore.setCurrent(CN1); - assertEquals("wrong role for NONE:", MASTER, Futures.getUnchecked(dms.requestRole(DID1))); - //no backup, no new MASTER/event - assertNull("wrong event:", Futures.getUnchecked(dms.relinquishRole(N1, DID1))); - - dms.requestRole(DID1); - - //add backup CN2, get it elected MASTER by relinquishing - testStore.setCurrent(CN2); - assertEquals("wrong role for NONE:", STANDBY, Futures.getUnchecked(dms.requestRole(DID1))); - assertEquals("wrong event:", Type.MASTER_CHANGED, Futures.getUnchecked(dms.relinquishRole(N1, DID1)).type()); - assertEquals("wrong master", N2, dms.getMaster(DID1)); - - //all nodes "give up" on device, which goes back to NONE. - assertNull("wrong event:", Futures.getUnchecked(dms.relinquishRole(N2, DID1))); - assertEquals("wrong role for node:", NONE, dms.getRole(N2, DID1)); - - assertEquals("wrong number of retired nodes", 2, - dms.roleMap.get(DID1).nodesOfRole(NONE).size()); - - //bring nodes back - assertEquals("wrong role for NONE:", MASTER, Futures.getUnchecked(dms.requestRole(DID1))); - testStore.setCurrent(CN1); - assertEquals("wrong role for NONE:", STANDBY, Futures.getUnchecked(dms.requestRole(DID1))); - assertEquals("wrong number of backup nodes", 1, - dms.roleMap.get(DID1).nodesOfRole(STANDBY).size()); - - //If STANDBY, should drop to NONE - assertEquals("wrong event:", Type.BACKUPS_CHANGED, Futures.getUnchecked(dms.relinquishRole(N1, DID1)).type()); - assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1)); - - //NONE - nothing happens - assertEquals("wrong event:", Type.BACKUPS_CHANGED, Futures.getUnchecked(dms.relinquishRole(N1, DID2)).type()); - assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2)); - - } - - @Ignore("Ignore until Delegate spec. is clear.") - @Test - public void testEvents() throws InterruptedException { - //shamelessly copy other distributed store tests - final CountDownLatch addLatch = new CountDownLatch(1); - - MastershipStoreDelegate checkAdd = new MastershipStoreDelegate() { - @Override - public void notify(MastershipEvent event) { - assertEquals("wrong event:", Type.MASTER_CHANGED, event.type()); - assertEquals("wrong subject", DID1, event.subject()); - assertEquals("wrong subject", N1, event.roleInfo().master()); - addLatch.countDown(); - } - }; - - dms.setDelegate(checkAdd); - dms.setMaster(N1, DID1); - //this will fail until we do something about single-instance-ness - assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS)); - } - - private class TestDistributedMastershipStore extends - DistributedMastershipStore { - public TestDistributedMastershipStore(StoreService storeService, - KryoSerializer kryoSerialization) { - this.storeService = storeService; - this.serializer = kryoSerialization; - } - - //helper to populate master/backup structures - public void put(DeviceId dev, NodeId node, - boolean master, boolean backup, boolean term) { - RoleValue rv = dms.roleMap.get(dev); - if (rv == null) { - rv = new RoleValue(); - } - - if (master) { - rv.add(MASTER, node); - rv.reassign(node, STANDBY, NONE); - } - if (backup) { - rv.add(STANDBY, node); - rv.remove(MASTER, node); - rv.remove(NONE, node); - } - if (term) { - dms.terms.put(dev, 0); - } - dms.roleMap.put(dev, rv); - } - - //a dumb utility function. - public void dump() { - for (Map.Entry el : dms.roleMap.entrySet()) { - System.out.println("DID: " + el.getKey()); - for (MastershipRole role : MastershipRole.values()) { - System.out.println("\t" + role.toString() + ":"); - for (NodeId n : el.getValue().nodesOfRole(role)) { - System.out.println("\t\t" + n); - } - } - } - } - - //increment term for a device - public void increment(DeviceId dev) { - Integer t = dms.terms.get(dev); - if (t != null) { - dms.terms.put(dev, ++t); - } - } - - //sets the "local" node - public void setCurrent(ControllerNode node) { - ((TestClusterService) clusterService).current = node; - } - } - - private class TestClusterService extends ClusterServiceAdapter { - - protected ControllerNode current; - - @Override - public ControllerNode getLocalNode() { - return current; - } - - @Override - public Set getNodes() { - return Sets.newHashSet(CN1, CN2); - } - - } -*/ -} diff --git a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/resource/impl/HazelcastLinkResourceStoreTest.java b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/resource/impl/HazelcastLinkResourceStoreTest.java deleted file mode 100644 index a5f2facb..00000000 --- a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/resource/impl/HazelcastLinkResourceStoreTest.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright 2014-2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.store.resource.impl; - -/** - * Test of the simple LinkResourceStore implementation. - */ -public class HazelcastLinkResourceStoreTest { -/* - private LinkResourceStore store; - private HazelcastLinkResourceStore storeImpl; - private Link link1; - private Link link2; - private Link link3; - private TestStoreManager storeMgr; - - /** - * Returns {@link Link} object. - * - * @param dev1 source device - * @param port1 source port - * @param dev2 destination device - * @param port2 destination port - * @return created {@link Link} object - * / - private Link newLink(String dev1, int port1, String dev2, int port2) { - Annotations annotations = DefaultAnnotations.builder() - .set(AnnotationKeys.OPTICAL_WAVES, "80") - .set(AnnotationKeys.BANDWIDTH, "1000") - .build(); - return new DefaultLink( - new ProviderId("of", "foo"), - new ConnectPoint(deviceId(dev1), portNumber(port1)), - new ConnectPoint(deviceId(dev2), portNumber(port2)), - DIRECT, annotations); - } - - @Before - public void setUp() throws Exception { - - TestStoreManager testStoreMgr = new TestStoreManager(); - testStoreMgr.setHazelcastInstance(testStoreMgr.initSingleInstance()); - storeMgr = testStoreMgr; - storeMgr.activate(); - - - storeImpl = new TestHazelcastLinkResourceStore(storeMgr); - storeImpl.activate(); - store = storeImpl; - - link1 = newLink("of:1", 1, "of:2", 2); - link2 = newLink("of:2", 1, "of:3", 2); - link3 = newLink("of:3", 1, "of:4", 2); - } - - @After - public void tearDown() throws Exception { - storeImpl.deactivate(); - - storeMgr.deactivate(); - } - - @Test - public void testConstructorAndActivate() { - final Iterable allAllocations = store.getAllocations(); - assertNotNull(allAllocations); - assertFalse(allAllocations.iterator().hasNext()); - - final Iterable linkAllocations = - store.getAllocations(link1); - assertNotNull(linkAllocations); - assertFalse(linkAllocations.iterator().hasNext()); - - final Set res = store.getFreeResources(link2); - assertNotNull(res); - } - - private BandwidthResourceAllocation getBandwidthObj(Set resources) { - for (ResourceAllocation res : resources) { - if (res.type() == ResourceType.BANDWIDTH) { - return ((BandwidthResourceAllocation) res); - } - } - return null; - } - - private Set getLambdaObjs(Set resources) { - Set lambdaResources = new HashSet<>(); - for (ResourceAllocation res : resources) { - if (res.type() == ResourceType.LAMBDA) { - lambdaResources.add((LambdaResourceAllocation) res); - } - } - return lambdaResources; - } - - @Test - public void testInitialBandwidth() { - final Set freeRes = store.getFreeResources(link1); - assertNotNull(freeRes); - - final BandwidthResourceAllocation alloc = getBandwidthObj(freeRes); - assertNotNull(alloc); - - assertEquals(new BandwidthResource(Bandwidth.mbps(1000.0)), alloc.bandwidth()); - } - - @Test - public void testInitialLambdas() { - final Set freeRes = store.getFreeResources(link3); - assertNotNull(freeRes); - - final Set res = getLambdaObjs(freeRes); - assertNotNull(res); - assertEquals(80, res.size()); - } - - public static final class TestHazelcastLinkResourceStore - extends HazelcastLinkResourceStore { - - public TestHazelcastLinkResourceStore(StoreService storeMgr) { - super.storeService = storeMgr; - } - - } - - @Test - public void testSuccessfulBandwidthAllocation() { - final Link link = newLink("of:1", 1, "of:2", 2); - - final LinkResourceRequest request = - DefaultLinkResourceRequest.builder(IntentId.valueOf(1), - ImmutableSet.of(link)) - .build(); - final ResourceAllocation allocation = - new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.mbps(900.0))); - final Set allocationSet = ImmutableSet.of(allocation); - - final LinkResourceAllocations allocations = - new DefaultLinkResourceAllocations(request, ImmutableMap.of(link, allocationSet)); - - store.allocateResources(allocations); - } - - @Test - public void testUnsuccessfulBandwidthAllocation() { - final Link link = newLink("of:1", 1, "of:2", 2); - - final LinkResourceRequest request = - DefaultLinkResourceRequest.builder(IntentId.valueOf(1), - ImmutableSet.of(link)) - .build(); - final ResourceAllocation allocation = - new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.mbps(9000.0))); - final Set allocationSet = ImmutableSet.of(allocation); - - final LinkResourceAllocations allocations = - new DefaultLinkResourceAllocations(request, ImmutableMap.of(link, allocationSet)); - - boolean gotException = false; - try { - store.allocateResources(allocations); - } catch (ResourceAllocationException rae) { - assertEquals(true, rae.getMessage().contains("Unable to allocate bandwidth for link")); - gotException = true; - } - assertEquals(true, gotException); - } - - @Test - public void testSuccessfulLambdaAllocation() { - final Link link = newLink("of:1", 1, "of:2", 2); - - final LinkResourceRequest request = - DefaultLinkResourceRequest.builder(IntentId.valueOf(1), - ImmutableSet.of(link)) - .build(); - final ResourceAllocation allocation = - new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.mbps(900.0))); - final Set allocationSet = ImmutableSet.of(allocation); - - final LinkResourceAllocations allocations = - new DefaultLinkResourceAllocations(request, ImmutableMap.of(link, allocationSet)); - - store.allocateResources(allocations); - } - - @Test - public void testUnsuccessfulLambdaAllocation() { - final Link link = newLink("of:1", 1, "of:2", 2); - - final LinkResourceRequest request = - DefaultLinkResourceRequest.builder(IntentId.valueOf(1), - ImmutableSet.of(link)) - .build(); - final ResourceAllocation allocation = - new LambdaResourceAllocation(LambdaResource.valueOf(33)); - final Set allocationSet = ImmutableSet.of(allocation); - - final LinkResourceAllocations allocations = - new DefaultLinkResourceAllocations(request, ImmutableMap.of(link, allocationSet)); - store.allocateResources(allocations); - - boolean gotException = false; - try { - store.allocateResources(allocations); - } catch (ResourceAllocationException rae) { - assertEquals(true, rae.getMessage().contains("Unable to allocate lambda for link")); - gotException = true; - } - assertEquals(true, gotException); - } - */ -} diff --git a/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceManager.java b/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceManager.java index 64a8683a..3428bce1 100644 --- a/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceManager.java +++ b/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceManager.java @@ -60,12 +60,13 @@ public class PersistenceManager implements PersistenceService { private static final int FLUSH_FREQUENCY_MILLIS = 3000; - private final Timer timer = new Timer(); + private Timer timer; private final CommitTask commitTask = new CommitTask(); @Activate public void activate() { + timer = new Timer(); Path dbPath = Paths.get(DATABASE_PATH); Path dbFolderPath = Paths.get(ENCLOSING_FOLDER); //Make sure the directory exists, if it does not, make it. @@ -96,6 +97,7 @@ public class PersistenceManager implements PersistenceService { @Deactivate public void deactivate() { + timer.cancel(); for (Map.Entry entry : localDB.getAll().entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); diff --git a/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/ExtensionInstructionSerializer.java b/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/ExtensionInstructionSerializer.java index 6b12df96..e688a80c 100644 --- a/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/ExtensionInstructionSerializer.java +++ b/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/ExtensionInstructionSerializer.java @@ -22,13 +22,13 @@ import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import org.onlab.osgi.DefaultServiceDirectory; import org.onosproject.net.DeviceId; -import org.onosproject.net.behaviour.ExtensionResolver; +import org.onosproject.net.behaviour.ExtensionTreatmentResolver; import org.onosproject.net.driver.DefaultDriverData; import org.onosproject.net.driver.DefaultDriverHandler; import org.onosproject.net.driver.DriverHandler; import org.onosproject.net.driver.DriverService; -import org.onosproject.net.flow.instructions.ExtensionInstruction; -import org.onosproject.net.flow.instructions.ExtensionType; +import org.onosproject.net.flow.instructions.ExtensionTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; import org.onosproject.net.flow.instructions.Instructions; /** @@ -53,16 +53,16 @@ public class ExtensionInstructionSerializer extends @Override public Instructions.ExtensionInstructionWrapper read(Kryo kryo, Input input, Class type) { - ExtensionType exType = (ExtensionType) kryo.readClassAndObject(input); + ExtensionTreatmentType exType = (ExtensionTreatmentType) kryo.readClassAndObject(input); DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input); DriverService driverService = DefaultServiceDirectory.getService(DriverService.class); DriverHandler handler = new DefaultDriverHandler( new DefaultDriverData(driverService.getDriver(deviceId), deviceId)); - ExtensionResolver resolver = handler.behaviour(ExtensionResolver.class); + ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class); - ExtensionInstruction instruction = resolver.getExtensionInstruction(exType); + ExtensionTreatment instruction = resolver.getExtensionInstruction(exType); byte[] bytes = (byte[]) kryo.readClassAndObject(input); diff --git a/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java index 6f96498f..1b883a30 100644 --- a/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java +++ b/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java @@ -75,6 +75,7 @@ import org.onosproject.net.OduSignalType; import org.onosproject.net.OmsPort; import org.onosproject.net.Port; import org.onosproject.net.PortNumber; +import org.onosproject.net.TributarySlot; import org.onosproject.net.device.DefaultDeviceDescription; import org.onosproject.net.device.DefaultPortDescription; import org.onosproject.net.device.DefaultPortStatistics; @@ -128,7 +129,7 @@ import org.onosproject.net.flow.criteria.TunnelIdCriterion; import org.onosproject.net.flow.criteria.UdpPortCriterion; import org.onosproject.net.flow.criteria.VlanIdCriterion; import org.onosproject.net.flow.criteria.VlanPcpCriterion; -import org.onosproject.net.flow.instructions.ExtensionType; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; import org.onosproject.net.flow.instructions.Instructions; import org.onosproject.net.flow.instructions.L0ModificationInstruction; import org.onosproject.net.flow.instructions.L1ModificationInstruction; @@ -367,6 +368,7 @@ public final class KryoNamespaces { L2ModificationInstruction.ModVlanPcpInstruction.class, L2ModificationInstruction.PopVlanInstruction.class, L2ModificationInstruction.ModMplsLabelInstruction.class, + L2ModificationInstruction.ModMplsBosInstruction.class, L2ModificationInstruction.ModMplsTtlInstruction.class, L2ModificationInstruction.ModTunnelIdInstruction.class, L3ModificationInstruction.class, @@ -454,7 +456,7 @@ public final class KryoNamespaces { .register(new DefaultOutboundPacketSerializer(), DefaultOutboundPacket.class) .register(new AnnotationsSerializer(), DefaultAnnotations.class) .register(new ExtensionInstructionSerializer(), Instructions.ExtensionInstructionWrapper.class) - .register(ExtensionType.class) + .register(ExtensionTreatmentType.class) .register(Versioned.class) .register(MapEvent.class) .register(MapEvent.Type.class) @@ -476,6 +478,7 @@ public final class KryoNamespaces { .register(OduCltPortDescription.class) .register(OchPortDescription.class) .register(OmsPortDescription.class) + .register(TributarySlot.class) .register( MplsIntent.class, MplsPathIntent.class, diff --git a/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java b/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java index 11a62d4e..45b4da1a 100644 --- a/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java +++ b/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java @@ -43,6 +43,7 @@ import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.GridType; import org.onosproject.net.HostLocation; +import org.onosproject.net.IndexedLambda; import org.onosproject.net.Link; import org.onosproject.net.Link.Type; import org.onosproject.net.LinkKey; @@ -395,12 +396,12 @@ public class KryoSerializerTest { @Test public void testLambdaConstraint() { - testSerializable(new LambdaConstraint(LambdaResource.valueOf(1))); + testSerializable(new LambdaConstraint(new IndexedLambda(1))); } @Test public void testBandwidthConstraint() { - testSerializable(new BandwidthConstraint(new BandwidthResource(Bandwidth.bps(1000.0)))); + testSerializable(new BandwidthConstraint(Bandwidth.bps(1000.0))); } @Test diff --git a/framework/src/onos/docs/external.xml b/framework/src/onos/docs/external.xml index f2c568a6..37463c34 100644 --- a/framework/src/onos/docs/external.xml +++ b/framework/src/onos/docs/external.xml @@ -46,11 +46,13 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.1 + 2.10.3 package - @external-excludes - + @external-excludes + + **/generated-sources/** + true ONOS Java API (1.4.0-SNAPSHOT) diff --git a/framework/src/onos/docs/internal.xml b/framework/src/onos/docs/internal.xml index e0ba3607..d1525aaa 100644 --- a/framework/src/onos/docs/internal.xml +++ b/framework/src/onos/docs/internal.xml @@ -51,8 +51,11 @@ package true ONOS Java API (1.4.0-SNAPSHOT) - @internal-excludes - + @internal-excludes + + **/generated-sources/** + + Network Model & Services diff --git a/framework/src/onos/drivers/features.xml b/framework/src/onos/drivers/features.xml index e83f93fa..cb2ca0b4 100644 --- a/framework/src/onos/drivers/features.xml +++ b/framework/src/onos/drivers/features.xml @@ -15,7 +15,6 @@ ~ limitations under the License. --> - mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features onos-api diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionInterpreter.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java similarity index 56% rename from framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionInterpreter.java rename to framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java index b8f1fd91..a7f70f98 100644 --- a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionInterpreter.java +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java @@ -17,11 +17,11 @@ package org.onosproject.driver.extensions; import org.onlab.packet.Ip4Address; -import org.onosproject.net.behaviour.ExtensionResolver; +import org.onosproject.net.behaviour.ExtensionTreatmentResolver; import org.onosproject.net.driver.AbstractHandlerBehaviour; -import org.onosproject.net.flow.instructions.ExtensionInstruction; -import org.onosproject.net.flow.instructions.ExtensionType; -import org.onosproject.openflow.controller.ExtensionInterpreter; +import org.onosproject.net.flow.instructions.ExtensionTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; +import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter; import org.projectfloodlight.openflow.protocol.OFActionType; import org.projectfloodlight.openflow.protocol.OFFactory; import org.projectfloodlight.openflow.protocol.action.OFAction; @@ -33,36 +33,45 @@ import org.projectfloodlight.openflow.types.IPv4Address; /** * Interpreter for Nicira OpenFlow extensions. */ -public class NiciraExtensionInterpreter extends AbstractHandlerBehaviour - implements ExtensionInterpreter, ExtensionResolver { +public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviour + implements ExtensionTreatmentInterpreter, ExtensionTreatmentResolver { @Override - public boolean supported(ExtensionType extensionType) { - if (extensionType.equals(ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type())) { + public boolean supported(ExtensionTreatmentType extensionTreatmentType) { + if (extensionTreatmentType.equals( + ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type())) { return true; } - if (extensionType.equals(ExtensionType.ExtensionTypes.NICIRA_RESUBMIT.type())) { + if (extensionTreatmentType.equals( + ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT.type())) { + return true; + } + if (extensionTreatmentType.equals( + ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type())) { return true; } return false; } @Override - public OFAction mapInstruction(OFFactory factory, ExtensionInstruction extensionInstruction) { - ExtensionType type = extensionInstruction.type(); - if (type.equals(ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type())) { - NiciraSetTunnelDst tunnelDst = (NiciraSetTunnelDst) extensionInstruction; + public OFAction mapInstruction(OFFactory factory, ExtensionTreatment extensionTreatment) { + ExtensionTreatmentType type = extensionTreatment.type(); + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type())) { + NiciraSetTunnelDst tunnelDst = (NiciraSetTunnelDst) extensionTreatment; return factory.actions().setField(factory.oxms().tunnelIpv4Dst( IPv4Address.of(tunnelDst.tunnelDst().toInt()))); } - if (type.equals(ExtensionType.ExtensionTypes.NICIRA_RESUBMIT.type())) { + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT.type())) { // TODO this will be implemented later } + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type())) { + // TODO this will be implemented later + } return null; } @Override - public ExtensionInstruction mapAction(OFAction action) { + public ExtensionTreatment mapAction(OFAction action) { if (action.getType().equals(OFActionType.SET_FIELD)) { OFActionSetField setFieldAction = (OFActionSetField) action; OFOxm oxm = setFieldAction.getField(); @@ -79,13 +88,16 @@ public class NiciraExtensionInterpreter extends AbstractHandlerBehaviour } @Override - public ExtensionInstruction getExtensionInstruction(ExtensionType type) { - if (type.equals(ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type())) { + public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) { + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type())) { return new NiciraSetTunnelDst(); } - if (type.equals(ExtensionType.ExtensionTypes.NICIRA_RESUBMIT.type())) { + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT.type())) { return new NiciraResubmit(); } + if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type())) { + return new NiciraSetNshSpi(); + } throw new UnsupportedOperationException( "Driver does not support extension type " + type.toString()); } diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmit.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmit.java new file mode 100644 index 00000000..481b6f9c --- /dev/null +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmit.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.driver.extensions; + +import com.google.common.base.MoreObjects; +import org.onlab.util.KryoNamespace; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.instructions.AbstractExtensionTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; +import org.onosproject.store.serializers.PortNumberSerializer; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Nicira resubmit extension instruction. + */ +public class NiciraResubmit extends AbstractExtensionTreatment { + + private PortNumber inPort; + + private final KryoNamespace appKryo = new KryoNamespace.Builder() + .register(new PortNumberSerializer(), PortNumber.class) + .register(byte[].class) + .build(); + + /** + * Creates a new resubmit instruction. + */ + NiciraResubmit() { + inPort = null; + } + + /** + * Creates a new resubmit instruction with a particular inPort. + * + * @param inPort in port number + */ + public NiciraResubmit(PortNumber inPort) { + checkNotNull(inPort); + this.inPort = inPort; + } + + /** + * Gets the inPort. + * + * @return inPort + */ + public PortNumber inPort() { + return inPort; + } + + @Override + public ExtensionTreatmentType type() { + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT.type(); + } + + @Override + public void deserialize(byte[] data) { + inPort = appKryo.deserialize(data); + } + + @Override + public byte[] serialize() { + return appKryo.serialize(inPort); + } + + @Override + public int hashCode() { + return Objects.hash(inPort); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof NiciraResubmit) { + NiciraResubmit that = (NiciraResubmit) obj; + return Objects.equals(inPort, that.inPort); + + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("inPort", inPort) + .toString(); + } +} diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSpi.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSpi.java new file mode 100644 index 00000000..25358702 --- /dev/null +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSpi.java @@ -0,0 +1,104 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.driver.extensions; + +import java.util.Objects; + +import org.onlab.util.KryoNamespace; +import org.onosproject.net.flow.instructions.AbstractExtensionTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; +import org.onosproject.store.serializers.Ip4AddressSerializer; + +import com.google.common.base.MoreObjects; + +/** + * Nicira set NSH SPI extension instruction. + */ +public class NiciraSetNshSpi extends AbstractExtensionTreatment { + + private int nshSpi; + + private final KryoNamespace appKryo = new KryoNamespace.Builder() + .register(new Ip4AddressSerializer(), Integer.class) + .register(byte[].class) + .build(); + + /** + * Creates a new set nsh spi instruction. + */ + NiciraSetNshSpi() { + nshSpi = 0; + } + + /** + * Creates a new set nsh spi instruction with given spi. + * + * @param nshSpi nsh service path index + */ + NiciraSetNshSpi(int nshSpi) { + this.nshSpi = nshSpi; + } + + /** + * Gets the nsh service path index. + * + * @return nsh service path index + */ + public int nshSpi() { + return nshSpi; + } + + @Override + public ExtensionTreatmentType type() { + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type(); + } + + @Override + public void deserialize(byte[] data) { + nshSpi = appKryo.deserialize(data); + } + + @Override + public byte[] serialize() { + return appKryo.serialize(nshSpi); + } + + @Override + public int hashCode() { + return Objects.hash(nshSpi); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof NiciraSetNshSpi) { + NiciraSetNshSpi that = (NiciraSetNshSpi) obj; + return Objects.equals(nshSpi, that.nshSpi); + + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("nshSpi", nshSpi) + .toString(); + } +} diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java index a20b2479..ec23a9e0 100644 --- a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java @@ -19,8 +19,8 @@ package org.onosproject.driver.extensions; import com.google.common.base.MoreObjects; import org.onlab.packet.Ip4Address; import org.onlab.util.KryoNamespace; -import org.onosproject.net.flow.instructions.AbstractExtensionInstruction; -import org.onosproject.net.flow.instructions.ExtensionType; +import org.onosproject.net.flow.instructions.AbstractExtensionTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; import org.onosproject.store.serializers.Ip4AddressSerializer; import java.util.Objects; @@ -30,7 +30,7 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Nicira set tunnel destination extension instruction. */ -public class NiciraSetTunnelDst extends AbstractExtensionInstruction { +public class NiciraSetTunnelDst extends AbstractExtensionTreatment { private Ip4Address tunnelDst; @@ -67,8 +67,8 @@ public class NiciraSetTunnelDst extends AbstractExtensionInstruction { } @Override - public ExtensionType type() { - return ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type(); + public ExtensionTreatmentType type() { + return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST.type(); } @Override diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitch13.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitch13.java index a62b93c8..5c6ce360 100644 --- a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitch13.java +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OFOpticalSwitch13.java @@ -144,7 +144,16 @@ public class OFOpticalSwitch13 extends AbstractOpenFlowSwitch implements OpenFlo @Override public Device.Type deviceType() { - return Device.Type.ROADM; + String hwDesc = hardwareDescription(); + switch (hwDesc) { + case "Optical-ROADM": + return Device.Type.ROADM; + case "Optical-OTN": + return Device.Type.OTN; + default: + log.error("Unsupported hardwareDescription {}", hwDesc); + return Device.Type.OTHER; + } } /* diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OfOpticalSwitchImplLinc13.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OfOpticalSwitchImplLinc13.java index ff65e0c6..f91e2a7e 100644 --- a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OfOpticalSwitchImplLinc13.java +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/handshaker/OfOpticalSwitchImplLinc13.java @@ -15,8 +15,8 @@ */ package org.onosproject.driver.handshaker; -import org.onosproject.net.Device; import com.google.common.collect.ImmutableSet; +import org.onosproject.net.Device; import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; import org.onosproject.openflow.controller.PortDescPropertyType; import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; @@ -26,6 +26,8 @@ import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotSta import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus; import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply; import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest; +import org.projectfloodlight.openflow.protocol.OFFlowMod; +import org.projectfloodlight.openflow.protocol.OFFlowStatsRequest; import org.projectfloodlight.openflow.protocol.OFMessage; import org.projectfloodlight.openflow.protocol.OFObject; import org.projectfloodlight.openflow.protocol.OFPortDesc; @@ -34,11 +36,19 @@ import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply; import org.projectfloodlight.openflow.protocol.OFPortOptical; import org.projectfloodlight.openflow.protocol.OFStatsReply; import org.projectfloodlight.openflow.protocol.OFStatsType; +import org.projectfloodlight.openflow.protocol.action.OFAction; +import org.projectfloodlight.openflow.protocol.action.OFActionSetField; +import org.projectfloodlight.openflow.protocol.match.Match; +import org.projectfloodlight.openflow.protocol.match.MatchField; +import org.projectfloodlight.openflow.protocol.oxm.OFOxmExpOchSigId; +import org.projectfloodlight.openflow.types.CircuitSignalID; import org.projectfloodlight.openflow.types.OFPort; +import org.projectfloodlight.openflow.types.U8; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @@ -52,6 +62,9 @@ import java.util.concurrent.atomic.AtomicBoolean; * LINC sends the tap ports (OCh for our purposes) in the regular port desc stats reply, * while it sends *all* ports (both tap and WDM ports, i.e., OCh and OMS) in the experimenter port desc stats reply. * + * As LINC implements custom OF optical extensions (in contrast to the final standard as specified in + * ONF TS-022 (March 15, 2015), we need to rewrite flow stat requests and flow mods in {@link #sendMsg(OFMessage)}. + * */ public class OfOpticalSwitchImplLinc13 extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch { @@ -160,6 +173,86 @@ public class OfOpticalSwitchImplLinc13 return Collections.EMPTY_LIST; } + /** + * Rewrite match object to use LINC OF optical extensions. + * + * @param match original match + * @return rewritten match + */ + private Match rewriteMatch(Match match) { + Match.Builder mBuilder = factory().buildMatch(); + for (MatchField mf : match.getMatchFields()) { + if (mf == MatchField.EXP_OCH_SIG_ID) { + mBuilder.setExact(MatchField.OCH_SIGID, (CircuitSignalID) match.get(mf)); + continue; + } + if (mf == MatchField.EXP_OCH_SIGTYPE) { + mBuilder.setExact(MatchField.OCH_SIGTYPE, (U8) match.get(mf)); + continue; + } + mBuilder.setExact(mf, match.get(mf)); + } + + return mBuilder.build(); + } + + /** + * Rewrite actions to use LINC OF optical extensions. + * + * @param actions original actions + * @return rewritten actions + */ + private List rewriteActions(List actions) { + List newActions = new LinkedList<>(); + + for (OFAction action : actions) { + if (!(action instanceof OFActionSetField)) { + newActions.add(action); + continue; + } + + OFActionSetField sf = (OFActionSetField) action; + if (!(sf instanceof OFOxmExpOchSigId)) { + newActions.add(action); + } + + OFOxmExpOchSigId oxm = (OFOxmExpOchSigId) sf.getField(); + CircuitSignalID signalId = oxm.getValue(); + + newActions.add( + factory().actions().circuit(factory().oxms().ochSigid(signalId))); + } + + return newActions; + } + + @Override + public void sendMsg(OFMessage msg) { + // Ignore everything but flow mods and stat requests + if (!(msg instanceof OFFlowMod || msg instanceof OFFlowStatsRequest)) { + super.sendMsg(msg); + return; + } + + Match newMatch; + OFMessage newMsg = null; + + if (msg instanceof OFFlowStatsRequest) { + // Rewrite match only + OFFlowStatsRequest fsr = (OFFlowStatsRequest) msg; + newMatch = rewriteMatch(fsr.getMatch()); + newMsg = fsr.createBuilder().setMatch(newMatch).build(); + } else if (msg instanceof OFFlowMod) { + // Rewrite match and actions + OFFlowMod fm = (OFFlowMod) msg; + newMatch = rewriteMatch(fm.getMatch()); + List actions = rewriteActions(fm.getActions()); + + newMsg = fm.createBuilder().setMatch(newMatch).setActions(actions).build(); + } + + super.sendMsg(newMsg); + } @Override public Boolean supportNxRole() { diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/NetconfControllerConfig.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/NetconfControllerConfig.java new file mode 100644 index 00000000..84043b5b --- /dev/null +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/NetconfControllerConfig.java @@ -0,0 +1,89 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.driver.netconf; + +import com.google.common.base.Preconditions; +import org.onosproject.net.DeviceId; +import org.onosproject.net.behaviour.ControllerConfig; +import org.onosproject.net.behaviour.ControllerInfo; +import org.onosproject.net.driver.AbstractHandlerBehaviour; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.netconf.NetconfController; +import org.onosproject.netconf.NetconfDevice; +import org.slf4j.Logger; + +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Implementation of controller config which allows to get and set controllers + * through the Netconf protocol. + */ +public class NetconfControllerConfig extends AbstractHandlerBehaviour + implements ControllerConfig { + + private final Logger log = getLogger(NetconfControllerConfig.class); + + @Override + public List getControllers() { + DriverHandler handler = handler(); + NetconfController controller = handler.get(NetconfController.class); + DeviceId ofDeviceId = handler.data().deviceId(); + Preconditions.checkNotNull(controller, "Netconf controller is null"); + List controllers = new ArrayList<>(); + controllers.addAll(XmlConfigParser.parseStreamControllers(XmlConfigParser. + loadXml(new ByteArrayInputStream(controller. + getDevicesMap().get(ofDeviceId).getSession(). + getConfig("running").getBytes(StandardCharsets.UTF_8))))); + return controllers; + } + + @Override + public void setControllers(List controllers) { + DriverHandler handler = handler(); + NetconfController controller = handler.get(NetconfController.class); + DeviceId deviceId = handler.data().deviceId(); + Preconditions.checkNotNull(controller, "Netconf controller is null"); + try { + NetconfDevice device = controller.getNetconfDevice(deviceId); + log.warn("provider map {}", controller.getDevicesMap()); + String config = XmlConfigParser.createControllersConfig( + XmlConfigParser.loadXml(getClass().getResourceAsStream("controllers.xml")), + XmlConfigParser.loadXml( + new ByteArrayInputStream(device.getSession() + .getConfig("running") + .getBytes( + StandardCharsets.UTF_8))), + "running", "merge", "create", controllers + ); + device.getSession().editConfig(config.substring(config.indexOf("-->") + 3)); + } catch (NullPointerException e) { + log.warn("No NETCONF device with requested parameters " + e); + throw new NullPointerException("No NETCONF device with requested parameters " + e); + } + + } + + //TODO maybe put method getNetconfClientService like in ovsdb if we need it + +} + + diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/XmlConfigParser.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/XmlConfigParser.java new file mode 100644 index 00000000..55826a25 --- /dev/null +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/XmlConfigParser.java @@ -0,0 +1,126 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.driver.netconf; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.HierarchicalConfiguration; +import org.apache.commons.configuration.XMLConfiguration; +import org.apache.commons.configuration.tree.ConfigurationNode; +import org.onlab.packet.IpAddress; +import org.onosproject.net.behaviour.ControllerInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.InputStream; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +/** + * Parser for Netconf XML configurations and replys. + */ +final class XmlConfigParser { + public static final Logger log = LoggerFactory + .getLogger(XmlConfigParser.class); + + private XmlConfigParser() { + //not called, preventing any allocation + } + + + protected static HierarchicalConfiguration loadXml(InputStream xmlStream) { + XMLConfiguration cfg = new XMLConfiguration(); + try { + cfg.load(xmlStream); + return cfg; + } catch (ConfigurationException e) { + throw new IllegalArgumentException("Cannot load xml from Stream", e); + } + } + + protected static List parseStreamControllers(HierarchicalConfiguration cfg) { + List controllers = new ArrayList<>(); + List fields = + cfg.configurationsAt("data.capable-switch." + + "logical-switches." + + "switch.controllers.controller"); + for (HierarchicalConfiguration sub : fields) { + controllers.add(new ControllerInfo( + IpAddress.valueOf(sub.getString("ip-address")), + Integer.parseInt(sub.getString("port")), + sub.getString("protocol"))); + } + return controllers; + } + + protected static String parseSwitchId(HierarchicalConfiguration cfg) { + HierarchicalConfiguration field = + cfg.configurationAt("data.capable-switch." + + "logical-switches." + + "switch"); + return field.getProperty("id").toString(); + } + + protected static String parseCapableSwitchId(HierarchicalConfiguration cfg) { + HierarchicalConfiguration field = + cfg.configurationAt("data.capable-switch"); + return field.getProperty("id").toString(); + } + + protected static String createControllersConfig(HierarchicalConfiguration cfg, + HierarchicalConfiguration actualCfg, + String target, String netconfOperation, + String controllerOperation, + List controllers) { + //cfg.getKeys().forEachRemaining(key -> System.out.println(key)); + cfg.setProperty("edit-config.target", target); + cfg.setProperty("edit-config.default-operation", netconfOperation); + cfg.setProperty("edit-config.config.capable-switch.id", + parseCapableSwitchId(actualCfg)); + cfg.setProperty("edit-config.config.capable-switch." + + "logical-switches.switch.id", parseSwitchId(actualCfg)); + List newControllers = new ArrayList<>(); + for (ControllerInfo ci : controllers) { + XMLConfiguration controller = new XMLConfiguration(); + controller.setRoot(new HierarchicalConfiguration.Node("controller")); + String id = ci.type() + ":" + ci.ip() + ":" + ci.port(); + controller.setProperty("id", id); + controller.setProperty("ip-address", ci.ip()); + controller.setProperty("port", ci.port()); + controller.setProperty("protocol", ci.type()); + newControllers.add(controller.getRootNode()); + } + cfg.addNodes("edit-config.config.capable-switch.logical-switches." + + "switch.controllers", newControllers); + XMLConfiguration editcfg = (XMLConfiguration) cfg; + StringWriter stringWriter = new StringWriter(); + try { + editcfg.save(stringWriter); + } catch (ConfigurationException e) { + e.printStackTrace(); + } + String s = stringWriter.toString() + .replaceAll("", + ""); + s = s.replace("" + target + "", + "<" + target + "/>"); + return s; + + } + + //TODO implement mor methods for parsing configuration when you need them +} diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/package-info.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/package-info.java new file mode 100644 index 00000000..200312b4 --- /dev/null +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/netconf/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Implementations of the Netconf driver behaviours. + */ +package org.onosproject.driver.netconf; \ No newline at end of file diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbControllerConfig.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbControllerConfig.java index a00d3dbc..f116ab84 100644 --- a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbControllerConfig.java +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbControllerConfig.java @@ -16,6 +16,7 @@ package org.onosproject.driver.ovsdb; +import com.google.common.collect.ImmutableSet; import org.onlab.packet.IpAddress; import org.onlab.packet.TpPort; import org.onosproject.net.AnnotationKeys; @@ -56,7 +57,7 @@ public class OvsdbControllerConfig extends AbstractHandlerBehaviour implements C DriverHandler handler = handler(); OvsdbClientService clientService = getOvsdbClientService(handler); if (!clientService.getControllers(handler().data().deviceId()) - .equals(controllers)) { + .equals(ImmutableSet.copyOf(controllers))) { clientService.setControllersWithDeviceId(handler(). data().deviceId(), controllers); } diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbTunnelConfig.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbTunnelConfig.java index a32553ad..ad90ca44 100644 --- a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbTunnelConfig.java +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbTunnelConfig.java @@ -68,10 +68,10 @@ public class OvsdbTunnelConfig extends AbstractHandlerBehaviour public boolean createTunnelInterface(BridgeName bridgeName, TunnelDescription tunnel) { Map options = ((DefaultAnnotations) tunnel.annotations()).asMap(); if (tunnel.src() != null) { - options.put(OPTION_LOCAL_IP, tunnel.src().toString()); + options.put(OPTION_LOCAL_IP, ((IpTunnelEndPoint) tunnel.src()).ip().toString()); } if (tunnel.dst() != null) { - options.put(OPTION_REMOTE_IP, tunnel.dst().toString()); + options.put(OPTION_REMOTE_IP, ((IpTunnelEndPoint) tunnel.dst()).ip().toString()); } DriverHandler handler = handler(); diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/CpqdOFDPA2Pipeline.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/CpqdOFDPA2Pipeline.java index 0cb30d28..937c9ac8 100644 --- a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/CpqdOFDPA2Pipeline.java +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/CpqdOFDPA2Pipeline.java @@ -18,15 +18,19 @@ package org.onosproject.driver.pipeline; import static org.slf4j.LoggerFactory.getLogger; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; +import java.util.Deque; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import org.onlab.packet.Ethernet; import org.onlab.packet.VlanId; import org.onosproject.core.ApplicationId; import org.onosproject.net.Port; import org.onosproject.net.PortNumber; +import org.onosproject.net.behaviour.NextGroup; import org.onosproject.net.flow.DefaultFlowRule; import org.onosproject.net.flow.DefaultTrafficSelector; import org.onosproject.net.flow.DefaultTrafficTreatment; @@ -35,8 +39,18 @@ import org.onosproject.net.flow.FlowRuleOperations; import org.onosproject.net.flow.FlowRuleOperationsContext; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.criteria.Criterion; +import org.onosproject.net.flow.criteria.EthTypeCriterion; +import org.onosproject.net.flow.criteria.IPCriterion; +import org.onosproject.net.flow.criteria.MplsBosCriterion; +import org.onosproject.net.flow.criteria.MplsCriterion; import org.onosproject.net.flow.criteria.PortCriterion; import org.onosproject.net.flow.criteria.VlanIdCriterion; +import org.onosproject.net.flow.instructions.Instruction; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.ObjectiveError; +import org.onosproject.net.group.Group; +import org.onosproject.net.group.GroupKey; import org.slf4j.Logger; @@ -108,6 +122,81 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { return rules; } + @Override + protected Collection processSpecific(ForwardingObjective fwd) { + TrafficSelector selector = fwd.selector(); + EthTypeCriterion ethType = + (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE); + if ((ethType == null) || + (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) && + (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST)) { + log.warn("processSpecific: Unsupported " + + "forwarding objective criteraia"); + fail(fwd, ObjectiveError.UNSUPPORTED); + return Collections.emptySet(); + } + + int forTableId = -1; + TrafficSelector.Builder filteredSelector = DefaultTrafficSelector.builder(); + if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) { + filteredSelector.matchEthType(Ethernet.TYPE_IPV4) + .matchIPDst(((IPCriterion) + selector.getCriterion(Criterion.Type.IPV4_DST)).ip()); + forTableId = UNICAST_ROUTING_TABLE; + log.debug("processing IPv4 specific forwarding objective {} hash{} in dev:{}", + fwd.id(), fwd.hashCode(), deviceId); + } else { + filteredSelector + .matchEthType(Ethernet.MPLS_UNICAST) + .matchMplsLabel(((MplsCriterion) + selector.getCriterion(Criterion.Type.MPLS_LABEL)).label()); + MplsBosCriterion bos = (MplsBosCriterion) selector + .getCriterion(Criterion.Type.MPLS_BOS); + if (bos != null) { + filteredSelector.matchMplsBos(bos.mplsBos()); + } + forTableId = MPLS_TABLE_1; + log.debug("processing MPLS specific forwarding objective {} hash:{} in dev {}", + fwd.id(), fwd.hashCode(), deviceId); + } + + TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); + if (fwd.treatment() != null) { + for (Instruction i : fwd.treatment().allInstructions()) { + tb.add(i); + } + } + + if (fwd.nextId() != null) { + NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId()); + List> gkeys = appKryo.deserialize(next.data()); + // we only need the top level group's key to point the flow to it + Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst()); + if (group == null) { + log.warn("The group left!"); + fail(fwd, ObjectiveError.GROUPMISSING); + return Collections.emptySet(); + } + tb.deferred().group(group.id()); + } + tb.transition(ACL_TABLE); + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder() + .fromApp(fwd.appId()) + .withPriority(fwd.priority()) + .forDevice(deviceId) + .withSelector(filteredSelector.build()) + .withTreatment(tb.build()) + .forTable(forTableId); + + if (fwd.permanent()) { + ruleBuilder.makePermanent(); + } else { + ruleBuilder.makeTemporary(fwd.timeout()); + } + + return Collections.singletonList(ruleBuilder.build()); + } + @Override protected void initializePipeline() { diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/OFDPA2Pipeline.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/OFDPA2Pipeline.java index cf3c7e89..863caebb 100644 --- a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/OFDPA2Pipeline.java +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/OFDPA2Pipeline.java @@ -19,9 +19,11 @@ import static org.onlab.util.Tools.groupedThreads; import static org.slf4j.LoggerFactory.getLogger; import java.nio.ByteBuffer; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Deque; import java.util.List; import java.util.Map; import java.util.Set; @@ -65,15 +67,20 @@ import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flow.criteria.Criteria; import org.onosproject.net.flow.criteria.Criterion; +import org.onosproject.net.flow.criteria.Criterion.Type; import org.onosproject.net.flow.criteria.EthCriterion; import org.onosproject.net.flow.criteria.EthTypeCriterion; import org.onosproject.net.flow.criteria.IPCriterion; +import org.onosproject.net.flow.criteria.MplsBosCriterion; +import org.onosproject.net.flow.criteria.MplsCriterion; import org.onosproject.net.flow.criteria.PortCriterion; import org.onosproject.net.flow.criteria.VlanIdCriterion; import org.onosproject.net.flow.instructions.Instruction; import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; import org.onosproject.net.flow.instructions.L2ModificationInstruction; +import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType; import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction; import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction; import org.onosproject.net.flowobjective.FilteringObjective; import org.onosproject.net.flowobjective.FlowObjectiveStore; @@ -127,51 +134,44 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline protected static final int DEFAULT_PRIORITY = 0x8000; protected static final int LOWEST_PRIORITY = 0x0; - /* - * Group keys are normally generated by using the next Objective id. In the - * case of a next objective resulting in a group chain, each group derives a - * group key from the next objective id in the following way: - * The upper 4 bits of the group-key are used to denote the position of the - * group in the group chain. For example, in the chain - * group0 --> group1 --> group2 --> port - * group0's group key would have the upper 4 bits as 0, group1's upper four - * bits would be 1, and so on - */ - private static final int GROUP0MASK = 0x0; - private static final int GROUP1MASK = 0x10000000; - /* * OFDPA requires group-id's to have a certain form. * L2 Interface Groups have <4bits-0><12bits-vlanid><16bits-portid> * L3 Unicast Groups have <4bits-2><28bits-index> + * MPLS Interface Groups have <4bits-9><4bits:0><24bits-index> + * L3 ECMP Groups have <4bits-7><28bits-index> + * L2 Flood Groups have <4bits-4><12bits-vlanid><16bits-index> + * L3 VPN Groups have <4bits-9><4bits-2><24bits-index> */ private static final int L2INTERFACEMASK = 0x0; private static final int L3UNICASTMASK = 0x20000000; - //private static final int MPLSINTERFACEMASK = 0x90000000; + private static final int MPLSINTERFACEMASK = 0x90000000; private static final int L3ECMPMASK = 0x70000000; private static final int L2FLOODMASK = 0x40000000; + private static final int L3VPNMASK = 0x92000000; private final Logger log = getLogger(getClass()); private ServiceDirectory serviceDirectory; protected FlowRuleService flowRuleService; private CoreService coreService; - private GroupService groupService; - private FlowObjectiveStore flowObjectiveStore; + protected GroupService groupService; + protected FlowObjectiveStore flowObjectiveStore; protected DeviceId deviceId; protected ApplicationId driverId; protected PacketService packetService; protected DeviceService deviceService; private InternalPacketProcessor processor = new InternalPacketProcessor(); - private KryoNamespace appKryo = new KryoNamespace.Builder() + protected KryoNamespace appKryo = new KryoNamespace.Builder() .register(KryoNamespaces.API) .register(GroupKey.class) .register(DefaultGroupKey.class) - .register(OfdpaGroupChain.class) + .register(OfdpaNextGroup.class) .register(byte[].class) + .register(ArrayDeque.class) .build(); - private Cache pendingNextObjectives; - private ConcurrentHashMap pendingGroups; + private Cache pendingNextObjectives; + private ConcurrentHashMap> pendingGroups; private ScheduledExecutorService groupChecker = Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner", @@ -184,6 +184,8 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline Map> vlan2Port = new ConcurrentHashMap>(); + // index number for group creation + AtomicInteger l3vpnindex = new AtomicInteger(0); @Override @@ -193,15 +195,16 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline pendingNextObjectives = CacheBuilder.newBuilder() .expireAfterWrite(20, TimeUnit.SECONDS) - .removalListener((RemovalNotification notification) -> { - if (notification.getCause() == RemovalCause.EXPIRED) { - fail(notification.getValue().nextObjective(), - ObjectiveError.GROUPINSTALLATIONFAILED); - } + .removalListener(( + RemovalNotification notification) -> { + if (notification.getCause() == RemovalCause.EXPIRED) { + fail(notification.getValue().nextObjective(), + ObjectiveError.GROUPINSTALLATIONFAILED); + } }).build(); groupChecker.scheduleAtFixedRate(new GroupChecker(), 0, 500, TimeUnit.MILLISECONDS); - pendingGroups = new ConcurrentHashMap(); + pendingGroups = new ConcurrentHashMap>(); coreService = serviceDirectory.get(CoreService.class); flowRuleService = serviceDirectory.get(FlowRuleService.class); @@ -285,22 +288,49 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline @Override public void next(NextObjective nextObjective) { - log.debug("Processing NextObjective id{} op{}", nextObjective.id(), - nextObjective.op()); - if (nextObjective.op() == Objective.Operation.REMOVE) { - if (nextObjective.next().isEmpty()) { - removeGroup(nextObjective); - } else { - removeBucketFromGroup(nextObjective); + NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id()); + switch (nextObjective.op()) { + case ADD: + if (nextGroup != null) { + log.warn("Cannot add next {} that already exists in device {}", + nextObjective.id(), deviceId); + return; } - } else if (nextObjective.op() == Objective.Operation.ADD) { - NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id()); + log.debug("Processing NextObjective id{} in dev{} - add group", + nextObjective.id(), deviceId); + addGroup(nextObjective); + break; + case ADD_TO_EXISTING: if (nextGroup != null) { + log.debug("Processing NextObjective id{} in dev{} - add bucket", + nextObjective.id(), deviceId); addBucketToGroup(nextObjective); } else { - addGroup(nextObjective); + // it is possible that group-chain has not been fully created yet + waitToAddBucketToGroup(nextObjective); } - } else { + break; + case REMOVE: + if (nextGroup == null) { + log.warn("Cannot remove next {} that does not exist in device {}", + nextObjective.id(), deviceId); + return; + } + log.debug("Processing NextObjective id{} in dev{} - remove group", + nextObjective.id(), deviceId); + removeGroup(nextObjective); + break; + case REMOVE_FROM_EXISTING: + if (nextGroup == null) { + log.warn("Cannot remove from next {} that does not exist in device {}", + nextObjective.id(), deviceId); + return; + } + log.debug("Processing NextObjective id{} in dev{} - remove bucket", + nextObjective.id(), deviceId); + removeBucketFromGroup(nextObjective); + break; + default: log.warn("Unsupported operation {}", nextObjective.op()); } } @@ -309,7 +339,6 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline // Flow handling ////////////////////////////////////// - /** * As per OFDPA 2.0 TTP, filtering of VLAN ids, MAC addresses (for routing) * and IP addresses configured on switch ports happen in different tables. @@ -520,7 +549,6 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline /** * Allows routed packets with correct destination MAC to be directed * to unicast-IP routing table or MPLS forwarding table. - * XXX need to add rule for multicast routing. * * @param portCriterion port on device for which this filter is programmed * @param ethCriterion dstMac of device for which is filter is programmed @@ -661,38 +689,78 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline /** * In the OF-DPA 2.0 pipeline, specific forwarding refers to the IP table - * (unicast or multicast) or the L2 table (mac + vlan). + * (unicast or multicast) or the L2 table (mac + vlan) or the MPLS table. * * @param fwd the forwarding objective of type 'specific' * @return a collection of flow rules. Typically there will be only one * for this type of forwarding objective. An empty set may be * returned if there is an issue in processing the objective. */ - private Collection processSpecific(ForwardingObjective fwd) { - log.debug("Processing specific forwarding objective"); + protected Collection processSpecific(ForwardingObjective fwd) { TrafficSelector selector = fwd.selector(); EthTypeCriterion ethType = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE); - // XXX currently supporting only the L3 unicast table - if (ethType == null || ethType.ethType().toShort() != Ethernet.TYPE_IPV4) { + if ((ethType == null) || + (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) && + (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST)) { + log.warn("processSpecific: Unsupported " + + "forwarding objective criteraia"); fail(fwd, ObjectiveError.UNSUPPORTED); return Collections.emptySet(); } - TrafficSelector filteredSelector = - DefaultTrafficSelector.builder() - .matchEthType(Ethernet.TYPE_IPV4) - .matchIPDst( - ((IPCriterion) - selector.getCriterion(Criterion.Type.IPV4_DST)).ip()) - .build(); + int forTableId = -1; + TrafficSelector.Builder filteredSelector = DefaultTrafficSelector.builder(); + if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) { + filteredSelector.matchEthType(Ethernet.TYPE_IPV4) + .matchIPDst(((IPCriterion) + selector.getCriterion(Criterion.Type.IPV4_DST)).ip()); + forTableId = UNICAST_ROUTING_TABLE; + log.debug("processing IPv4 specific forwarding objective {} in dev:{}", + fwd.id(), deviceId); + } else { + filteredSelector + .matchEthType(Ethernet.MPLS_UNICAST) + .matchMplsLabel(((MplsCriterion) + selector.getCriterion(Criterion.Type.MPLS_LABEL)).label()); + MplsBosCriterion bos = (MplsBosCriterion) selector + .getCriterion(Criterion.Type.MPLS_BOS); + if (bos != null) { + filteredSelector.matchMplsBos(bos.mplsBos()); + } + forTableId = MPLS_TABLE_1; + log.debug("processing MPLS specific forwarding objective {} in dev {}", + fwd.id(), deviceId); + } TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); + boolean popMpls = false; + if (fwd.treatment() != null) { + for (Instruction i : fwd.treatment().allInstructions()) { + tb.add(i); + if (i instanceof L2ModificationInstruction && + ((L2ModificationInstruction) i).subtype() == L2SubType.MPLS_POP) { + popMpls = true; + } + } + } if (fwd.nextId() != null) { + if (forTableId == MPLS_TABLE_1 && !popMpls) { + log.warn("SR CONTINUE case cannot be handled as MPLS ECMP " + + "is not implemented in OF-DPA yet. Aborting this flow " + + "in this device {}", deviceId); + // XXX We could convert to forwarding to a single-port, via a + // MPLS interface, or a MPLS SWAP (with-same) but that would + // have to be handled in the next-objective. Also the pop-mpls + // logic used here won't work in non-BoS case. + return Collections.emptySet(); + } + NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId()); - List gkeys = appKryo.deserialize(next.data()); - Group group = groupService.getGroup(deviceId, gkeys.get(0)); + List> gkeys = appKryo.deserialize(next.data()); + // we only need the top level group's key to point the flow to it + Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst()); if (group == null) { log.warn("The group left!"); fail(fwd, ObjectiveError.GROUPMISSING); @@ -705,8 +773,9 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline .fromApp(fwd.appId()) .withPriority(fwd.priority()) .forDevice(deviceId) - .withSelector(filteredSelector) - .withTreatment(tb.build()); + .withSelector(filteredSelector.build()) + .withTreatment(tb.build()) + .forTable(forTableId); if (fwd.permanent()) { ruleBuilder.makePermanent(); @@ -714,7 +783,6 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline ruleBuilder.makeTemporary(fwd.timeout()); } - ruleBuilder.forTable(UNICAST_ROUTING_TABLE); return Collections.singletonList(ruleBuilder.build()); } @@ -724,7 +792,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline } } - private void fail(Objective obj, ObjectiveError error) { + protected void fail(Objective obj, ObjectiveError error) { if (obj.context().isPresent()) { obj.context().get().onError(obj, error); } @@ -765,20 +833,66 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline /** * As per the OFDPA 2.0 TTP, packets are sent out of ports by using - * a chain of groups, namely an L3 Unicast Group that points to an L2 Interface - * Group which in-turn points to an output port. The Next Objective passed + * a chain of groups. The simple Next Objective passed * in by the application has to be broken up into a group chain - * to satisfy this TTP. + * comprising of an L3 Unicast Group that points to an L2 Interface + * Group which in-turn points to an output port. In some cases, the simple + * next Objective can just be an L2 interface without the need for chaining. * * @param nextObj the nextObjective of type SIMPLE */ private void processSimpleNextObjective(NextObjective nextObj) { // break up simple next objective to GroupChain objects TrafficTreatment treatment = nextObj.next().iterator().next(); + + GroupInfo groupInfo = createL2L3Chain(treatment, nextObj.id(), + nextObj.appId(), false, + nextObj.meta()); + if (groupInfo == null) { + log.error("Could not process nextObj={} in dev:{}", nextObj.id(), deviceId); + return; + } + // create object for local and distributed storage + Deque gkeyChain = new ArrayDeque<>(); + gkeyChain.addFirst(groupInfo.innerGrpDesc.appCookie()); + gkeyChain.addFirst(groupInfo.outerGrpDesc.appCookie()); + OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup( + Collections.singletonList(gkeyChain), + nextObj); + + // store l3groupkey with the ofdpaGroupChain for the nextObjective that depends on it + pendingNextObjectives.put(groupInfo.outerGrpDesc.appCookie(), ofdpaGrp); + + // now we are ready to send the l2 groupDescription (inner), as all the stores + // that will get async replies have been updated. By waiting to update + // the stores, we prevent nasty race conditions. + groupService.addGroup(groupInfo.innerGrpDesc); + } + + /** + * Creates one of two possible group-chains from the treatment + * passed in. Depending on the MPLS boolean, this method either creates + * an L3Unicast Group --> L2Interface Group, if mpls is false; + * or MPLSInterface Group --> L2Interface Group, if mpls is true; + * The returned 'inner' group description is always the L2 Interface group. + * + * @param treatment that needs to be broken up to create the group chain + * @param nextId of the next objective that needs this group chain + * @param appId of the application that sent this next objective + * @param mpls determines if L3Unicast or MPLSInterface group is created + * @param meta metadata passed in by the application as part of the nextObjective + * @return GroupInfo containing the GroupDescription of the + * L2Interface group(inner) and the GroupDescription of the (outer) + * L3Unicast/MPLSInterface group. May return null if there is an + * error in processing the chain + */ + private GroupInfo createL2L3Chain(TrafficTreatment treatment, int nextId, + ApplicationId appId, boolean mpls, + TrafficSelector meta) { // for the l2interface group, get vlan and port info - // for the l3unicast group, get the src/dst mac and vlan info - TrafficTreatment.Builder l3utt = DefaultTrafficTreatment.builder(); - TrafficTreatment.Builder l2itt = DefaultTrafficTreatment.builder(); + // for the outer group, get the src/dst mac, and vlan info + TrafficTreatment.Builder outerTtb = DefaultTrafficTreatment.builder(); + TrafficTreatment.Builder innerTtb = DefaultTrafficTreatment.builder(); VlanId vlanid = null; long portNum = 0; for (Instruction ins : treatment.allInstructions()) { @@ -786,76 +900,144 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline L2ModificationInstruction l2ins = (L2ModificationInstruction) ins; switch (l2ins.subtype()) { case ETH_DST: - l3utt.setEthDst(((ModEtherInstruction) l2ins).mac()); + outerTtb.setEthDst(((ModEtherInstruction) l2ins).mac()); break; case ETH_SRC: - l3utt.setEthSrc(((ModEtherInstruction) l2ins).mac()); + outerTtb.setEthSrc(((ModEtherInstruction) l2ins).mac()); break; case VLAN_ID: vlanid = ((ModVlanIdInstruction) l2ins).vlanId(); - l3utt.setVlanId(vlanid); + outerTtb.setVlanId(vlanid); + break; + case VLAN_POP: + innerTtb.popVlan(); break; case DEC_MPLS_TTL: case MPLS_LABEL: case MPLS_POP: case MPLS_PUSH: case VLAN_PCP: - case VLAN_POP: case VLAN_PUSH: default: break; } } else if (ins.type() == Instruction.Type.OUTPUT) { portNum = ((OutputInstruction) ins).port().toLong(); - l2itt.add(ins); + innerTtb.add(ins); } else { log.warn("Driver does not handle this type of TrafficTreatment" + " instruction in nextObjectives: {}", ins.type()); } } + if (vlanid == null) { + //use the vlanid associated with the port + vlanid = port2Vlan.get(PortNumber.portNumber(portNum)); + } + + if (vlanid == null) { + // use metadata + for (Criterion metaCriterion : meta.criteria()) { + if (metaCriterion.type() == Type.VLAN_VID) { + vlanid = ((VlanIdCriterion) metaCriterion).vlanId(); + } + } + } + + if (vlanid == null) { + log.error("Driver cannot process an L2/L3 group chain without " + + "egress vlan information for dev: {} port:{}", + deviceId, portNum); + return null; + } + // assemble information for ofdpa l2interface group - int l2gk = nextObj.id() | GROUP1MASK; - final GroupKey l2groupkey = new DefaultGroupKey(appKryo.serialize(l2gk)); Integer l2groupId = L2INTERFACEMASK | (vlanid.toShort() << 16) | (int) portNum; + // a globally unique groupkey that is different for ports in the same devices + // but different for the same portnumber on different devices. Also different + // for the various group-types created out of the same next objective. + int l2gk = 0x0ffffff & (deviceId.hashCode() << 8 | (int) portNum); + final GroupKey l2groupkey = new DefaultGroupKey(appKryo.serialize(l2gk)); - // assemble information for ofdpa l3unicast group - int l3gk = nextObj.id() | GROUP0MASK; - final GroupKey l3groupkey = new DefaultGroupKey(appKryo.serialize(l3gk)); - Integer l3groupId = L3UNICASTMASK | (int) portNum; - l3utt.group(new DefaultGroupId(l2groupId)); - GroupChainElem gce = new GroupChainElem(l3groupkey, l3groupId, - GroupDescription.Type.INDIRECT, - Collections.singletonList(l3utt.build()), - nextObj.appId(), 1); - - // create object for local and distributed storage - List gkeys = new ArrayList(); - gkeys.add(l3groupkey); // group0 in chain - gkeys.add(l2groupkey); // group1 in chain - OfdpaGroupChain ofdpaGrp = new OfdpaGroupChain(gkeys, nextObj); + // assemble information for outer group + GroupDescription outerGrpDesc = null; + if (mpls) { + // outer group is MPLSInteface + Integer mplsgroupId = MPLSINTERFACEMASK | (int) portNum; + // using mplsinterfacemask in groupkey to differentiate from l2interface + int mplsgk = MPLSINTERFACEMASK | (0x0ffffff & (deviceId.hashCode() << 8 | (int) portNum)); + final GroupKey mplsgroupkey = new DefaultGroupKey(appKryo.serialize(mplsgk)); + outerTtb.group(new DefaultGroupId(l2groupId)); + // create the mpls-interface group description to wait for the + // l2 interface group to be processed + GroupBucket mplsinterfaceGroupBucket = + DefaultGroupBucket.createIndirectGroupBucket(outerTtb.build()); + outerGrpDesc = new DefaultGroupDescription( + deviceId, + GroupDescription.Type.INDIRECT, + new GroupBuckets(Collections.singletonList( + mplsinterfaceGroupBucket)), + mplsgroupkey, + mplsgroupId, + appId); + log.debug("Trying MPLS-Interface: device:{} gid:{} gkey:{} nextid:{}", + deviceId, Integer.toHexString(mplsgroupId), + mplsgroupkey, nextId); + } else { + // outer group is L3Unicast + Integer l3groupId = L3UNICASTMASK | (int) portNum; + int l3gk = L3UNICASTMASK | (0x0ffffff & (deviceId.hashCode() << 8 | (int) portNum)); + final GroupKey l3groupkey = new DefaultGroupKey(appKryo.serialize(l3gk)); + outerTtb.group(new DefaultGroupId(l2groupId)); + // create the l3unicast group description to wait for the + // l2 interface group to be processed + GroupBucket l3unicastGroupBucket = + DefaultGroupBucket.createIndirectGroupBucket(outerTtb.build()); + outerGrpDesc = new DefaultGroupDescription( + deviceId, + GroupDescription.Type.INDIRECT, + new GroupBuckets(Collections.singletonList( + l3unicastGroupBucket)), + l3groupkey, + l3groupId, + appId); + log.debug("Trying L3Unicast: device:{} gid:{} gkey:{} nextid:{}", + deviceId, Integer.toHexString(l3groupId), + l3groupkey, nextId); + } - // store l2groupkey with the groupChainElem for the l3group that depends on it - pendingGroups.put(l2groupkey, gce); + // store l2groupkey with the groupChainElem for the outer-group that depends on it + GroupChainElem gce = new GroupChainElem(outerGrpDesc, 1); + Set gceSet = Collections.newSetFromMap( + new ConcurrentHashMap()); + gceSet.add(gce); + Set retval = pendingGroups.putIfAbsent(l2groupkey, gceSet); + if (retval != null) { + retval.add(gce); + } - // store l3groupkey with the ofdpaGroupChain for the nextObjective that depends on it - pendingNextObjectives.put(l3groupkey, ofdpaGrp); + // create group description for the inner l2interfacegroup + GroupBucket l2interfaceGroupBucket = + DefaultGroupBucket.createIndirectGroupBucket(innerTtb.build()); + GroupDescription l2groupDescription = + new DefaultGroupDescription( + deviceId, + GroupDescription.Type.INDIRECT, + new GroupBuckets(Collections.singletonList( + l2interfaceGroupBucket)), + l2groupkey, + l2groupId, + appId); + log.debug("Trying L2Interface: device:{} gid:{} gkey:{} nextId:{}", + deviceId, Integer.toHexString(l2groupId), + l2groupkey, nextId); + return new GroupInfo(l2groupDescription, outerGrpDesc); - // create group description for the ofdpa l2interfacegroup and send to groupservice - GroupBucket bucket = - DefaultGroupBucket.createIndirectGroupBucket(l2itt.build()); - GroupDescription groupDescription = new DefaultGroupDescription(deviceId, - GroupDescription.Type.INDIRECT, - new GroupBuckets(Collections.singletonList(bucket)), - l2groupkey, - l2groupId, - nextObj.appId()); - groupService.addGroup(groupDescription); } /** * As per the OFDPA 2.0 TTP, packets are sent out of ports by using - * a chain of groups. The Next Objective passed in by the application + * a chain of groups. The broadcast Next Objective passed in by the application * has to be broken up into a group chain comprising of an * L2 Flood group whose buckets point to L2 Interface groups. * @@ -866,9 +1048,9 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline Collection buckets = nextObj.next(); // each treatment is converted to an L2 interface group - int indicator = 0; VlanId vlanid = null; - List groupInfoCollection = new ArrayList<>(); + List l2interfaceGroupDescs = new ArrayList<>(); + List> allGroupKeys = new ArrayList<>(); for (TrafficTreatment treatment : buckets) { TrafficTreatment.Builder newTreatment = DefaultTrafficTreatment.builder(); PortNumber portNum = null; @@ -907,83 +1089,284 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline } } - // assemble info for all l2 interface groups - indicator += GROUP1MASK; - int l2gk = nextObj.id() | indicator; + // assemble info for l2 interface group + int l2gk = 0x0ffffff & (deviceId.hashCode() << 8 | (int) portNum.toLong()); final GroupKey l2groupkey = new DefaultGroupKey(appKryo.serialize(l2gk)); Integer l2groupId = L2INTERFACEMASK | (vlanid.toShort() << 16) | (int) portNum.toLong(); - GroupBucket newbucket = + GroupBucket l2interfaceGroupBucket = DefaultGroupBucket.createIndirectGroupBucket(newTreatment.build()); + GroupDescription l2interfaceGroupDescription = + new DefaultGroupDescription( + deviceId, + GroupDescription.Type.INDIRECT, + new GroupBuckets(Collections.singletonList( + l2interfaceGroupBucket)), + l2groupkey, + l2groupId, + nextObj.appId()); + log.debug("Trying L2-Interface: device:{} gid:{} gkey:{} nextid:{}", + deviceId, Integer.toHexString(l2groupId), + l2groupkey, nextObj.id()); + + Deque gkeyChain = new ArrayDeque<>(); + gkeyChain.addFirst(l2groupkey); // store the info needed to create this group - groupInfoCollection.add(new GroupInfo(l2groupId, l2groupkey, newbucket)); + l2interfaceGroupDescs.add(l2interfaceGroupDescription); + allGroupKeys.add(gkeyChain); } // assemble info for l2 flood group - int l2floodgk = nextObj.id() | GROUP0MASK; - final GroupKey l2floodgroupkey = new DefaultGroupKey(appKryo.serialize(l2floodgk)); Integer l2floodgroupId = L2FLOODMASK | (vlanid.toShort() << 16) | nextObj.id(); - // collection of treatment with groupids of l2 interface groups - List floodtt = new ArrayList<>(); - for (GroupInfo gi : groupInfoCollection) { + int l2floodgk = L2FLOODMASK | nextObj.id() << 12; + final GroupKey l2floodgroupkey = new DefaultGroupKey(appKryo.serialize(l2floodgk)); + // collection of group buckets pointing to all the l2 interface groups + List l2floodBuckets = new ArrayList<>(); + for (GroupDescription l2intGrpDesc : l2interfaceGroupDescs) { TrafficTreatment.Builder ttb = DefaultTrafficTreatment.builder(); - ttb.group(new DefaultGroupId(gi.groupId)); - floodtt.add(ttb.build()); + ttb.group(new DefaultGroupId(l2intGrpDesc.givenGroupId())); + GroupBucket abucket = DefaultGroupBucket.createAllGroupBucket(ttb.build()); + l2floodBuckets.add(abucket); } - GroupChainElem gce = new GroupChainElem(l2floodgroupkey, l2floodgroupId, - GroupDescription.Type.ALL, - floodtt, - nextObj.appId(), - groupInfoCollection.size()); + // create the l2flood group-description to wait for all the + // l2interface groups to be processed + GroupDescription l2floodGroupDescription = + new DefaultGroupDescription( + deviceId, + GroupDescription.Type.ALL, + new GroupBuckets(l2floodBuckets), + l2floodgroupkey, + l2floodgroupId, + nextObj.appId()); + GroupChainElem gce = new GroupChainElem(l2floodGroupDescription, + l2interfaceGroupDescs.size()); + log.debug("Trying L2-Flood: device:{} gid:{} gkey:{} nextid:{}", + deviceId, Integer.toHexString(l2floodgroupId), + l2floodgroupkey, nextObj.id()); // create objects for local and distributed storage - List gkeys = new ArrayList(); - gkeys.add(l2floodgroupkey); // group0 in chain - OfdpaGroupChain ofdpaGrp = new OfdpaGroupChain(gkeys, nextObj); + allGroupKeys.forEach(gkeyChain -> gkeyChain.addFirst(l2floodgroupkey)); + OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(allGroupKeys, nextObj); // store l2floodgroupkey with the ofdpaGroupChain for the nextObjective // that depends on it pendingNextObjectives.put(l2floodgroupkey, ofdpaGrp); - for (GroupInfo gi : groupInfoCollection) { + for (GroupDescription l2intGrpDesc : l2interfaceGroupDescs) { // store all l2groupkeys with the groupChainElem for the l2floodgroup // that depends on it - pendingGroups.put(gi.groupKey, gce); + Set gceSet = Collections.newSetFromMap( + new ConcurrentHashMap()); + gceSet.add(gce); + Set retval = pendingGroups.putIfAbsent( + l2intGrpDesc.appCookie(), gceSet); + if (retval != null) { + retval.add(gce); + } // create and send groups for all l2 interface groups - GroupDescription groupDescription = - new DefaultGroupDescription( - deviceId, - GroupDescription.Type.INDIRECT, - new GroupBuckets(Collections.singletonList(gi.groupBucket)), - gi.groupKey, - gi.groupId, - nextObj.appId()); - groupService.addGroup(groupDescription); + groupService.addGroup(l2intGrpDesc); } } + /** + * Utility class for moving group information around. + * + */ private class GroupInfo { - private Integer groupId; - private GroupKey groupKey; - private GroupBucket groupBucket; - - GroupInfo(Integer groupId, GroupKey groupKey, GroupBucket groupBucket) { - this.groupBucket = groupBucket; - this.groupId = groupId; - this.groupKey = groupKey; + private GroupDescription innerGrpDesc; + private GroupDescription outerGrpDesc; + + GroupInfo(GroupDescription innerGrpDesc, GroupDescription outerGrpDesc) { + this.innerGrpDesc = innerGrpDesc; + this.outerGrpDesc = outerGrpDesc; } } + /** + * As per the OFDPA 2.0 TTP, packets are sent out of ports by using + * a chain of groups. The hashed Next Objective passed in by the application + * has to be broken up into a group chain comprising of an + * L3 ECMP group as the top level group. Buckets of this group can point + * to a variety of groups in a group chain, depending on the whether + * MPLS labels are being pushed or not. + *

+ * NOTE: We do not create MPLS ECMP groups as they are unimplemented in + * OF-DPA 2.0 (even though it is in the spec). Therefore we do not + * check the nextObjective meta. + * + * @param nextObj the nextObjective of type HASHED + */ private void processHashedNextObjective(NextObjective nextObj) { - // TODO Auto-generated method stub + // break up hashed next objective to multiple groups + Collection buckets = nextObj.next(); + + // storage for all group keys in the chain of groups created + List> allGroupKeys = new ArrayList<>(); + List unsentGroups = new ArrayList<>(); + for (TrafficTreatment bucket : buckets) { + //figure out how many labels are pushed in each bucket + int labelsPushed = 0; + MplsLabel innermostLabel = null; + for (Instruction ins : bucket.allInstructions()) { + if (ins.type() == Instruction.Type.L2MODIFICATION) { + L2ModificationInstruction l2ins = (L2ModificationInstruction) ins; + if (l2ins.subtype() == L2SubType.MPLS_PUSH) { + labelsPushed++; + } + if (l2ins.subtype() == L2SubType.MPLS_LABEL) { + if (innermostLabel == null) { + innermostLabel = ((ModMplsLabelInstruction) l2ins).mplsLabel(); + } + } + } + } + + Deque gkeyChain = new ArrayDeque<>(); + // XXX we only deal with 0 and 1 label push right now + if (labelsPushed == 0) { + GroupInfo nolabelGroupInfo = createL2L3Chain(bucket, nextObj.id(), + nextObj.appId(), false, + nextObj.meta()); + if (nolabelGroupInfo == null) { + log.error("Could not process nextObj={} in dev:{}", + nextObj.id(), deviceId); + return; + } + gkeyChain.addFirst(nolabelGroupInfo.innerGrpDesc.appCookie()); + gkeyChain.addFirst(nolabelGroupInfo.outerGrpDesc.appCookie()); + + // we can't send the inner group description yet, as we have to + // create the dependent ECMP group first. So we store.. + unsentGroups.add(nolabelGroupInfo); + + } else if (labelsPushed == 1) { + GroupInfo onelabelGroupInfo = createL2L3Chain(bucket, nextObj.id(), + nextObj.appId(), true, + nextObj.meta()); + if (onelabelGroupInfo == null) { + log.error("Could not process nextObj={} in dev:{}", + nextObj.id(), deviceId); + return; + } + // we need to add another group to this chain - the L3VPN group + TrafficTreatment.Builder l3vpnTtb = DefaultTrafficTreatment.builder(); + l3vpnTtb.pushMpls() + .setMpls(innermostLabel) + .setMplsBos(true) + .copyTtlOut() + .group(new DefaultGroupId( + onelabelGroupInfo.outerGrpDesc.givenGroupId())); + GroupBucket l3vpnGrpBkt = + DefaultGroupBucket.createIndirectGroupBucket(l3vpnTtb.build()); + int l3vpngroupId = L3VPNMASK | l3vpnindex.incrementAndGet(); + int l3vpngk = L3VPNMASK | nextObj.id() << 12 | l3vpnindex.get(); + GroupKey l3vpngroupkey = new DefaultGroupKey(appKryo.serialize(l3vpngk)); + GroupDescription l3vpnGroupDesc = + new DefaultGroupDescription( + deviceId, + GroupDescription.Type.INDIRECT, + new GroupBuckets(Collections.singletonList( + l3vpnGrpBkt)), + l3vpngroupkey, + l3vpngroupId, + nextObj.appId()); + GroupChainElem l3vpnGce = new GroupChainElem(l3vpnGroupDesc, 1); + Set gceSet = Collections.newSetFromMap( + new ConcurrentHashMap()); + gceSet.add(l3vpnGce); + Set retval = pendingGroups + .putIfAbsent(onelabelGroupInfo.outerGrpDesc.appCookie(), gceSet); + if (retval != null) { + retval.add(l3vpnGce); + } + + gkeyChain.addFirst(onelabelGroupInfo.innerGrpDesc.appCookie()); + gkeyChain.addFirst(onelabelGroupInfo.outerGrpDesc.appCookie()); + gkeyChain.addFirst(l3vpngroupkey); + + //now we can replace the outerGrpDesc with the one we just created + onelabelGroupInfo.outerGrpDesc = l3vpnGroupDesc; + + // we can't send the innermost group yet, as we have to create + // the dependent ECMP group first. So we store ... + unsentGroups.add(onelabelGroupInfo); + + log.debug("Trying L3VPN: device:{} gid:{} gkey:{} nextId:{}", + deviceId, Integer.toHexString(l3vpngroupId), + l3vpngroupkey, nextObj.id()); + + } else { + log.warn("Driver currently does not handle more than 1 MPLS " + + "labels. Not processing nextObjective {}", nextObj); + return; + } + + // all groups in this chain + allGroupKeys.add(gkeyChain); + } + + // now we can create the outermost L3 ECMP group + List l3ecmpGroupBuckets = new ArrayList<>(); + for (GroupInfo gi : unsentGroups) { + // create ECMP bucket to point to the outer group + TrafficTreatment.Builder ttb = DefaultTrafficTreatment.builder(); + ttb.group(new DefaultGroupId(gi.outerGrpDesc.givenGroupId())); + GroupBucket sbucket = DefaultGroupBucket + .createSelectGroupBucket(ttb.build()); + l3ecmpGroupBuckets.add(sbucket); + } + int l3ecmpGroupId = L3ECMPMASK | nextObj.id() << 12; + GroupKey l3ecmpGroupKey = new DefaultGroupKey(appKryo.serialize(l3ecmpGroupId)); + GroupDescription l3ecmpGroupDesc = + new DefaultGroupDescription( + deviceId, + GroupDescription.Type.SELECT, + new GroupBuckets(l3ecmpGroupBuckets), + l3ecmpGroupKey, + l3ecmpGroupId, + nextObj.appId()); + GroupChainElem l3ecmpGce = new GroupChainElem(l3ecmpGroupDesc, + l3ecmpGroupBuckets.size()); + + // create objects for local and distributed storage + allGroupKeys.forEach(gkeyChain -> gkeyChain.addFirst(l3ecmpGroupKey)); + OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(allGroupKeys, nextObj); + + // store l3ecmpGroupKey with the ofdpaGroupChain for the nextObjective + // that depends on it + pendingNextObjectives.put(l3ecmpGroupKey, ofdpaGrp); + + log.debug("Trying L3ECMP: device:{} gid:{} gkey:{} nextId:{}", + deviceId, Integer.toHexString(l3ecmpGroupId), + l3ecmpGroupKey, nextObj.id()); + // finally we are ready to send the innermost groups + for (GroupInfo gi : unsentGroups) { + log.debug("Sending innermost group {} in group chain on device {} ", + Integer.toHexString(gi.innerGrpDesc.givenGroupId()), deviceId); + Set gceSet = Collections.newSetFromMap( + new ConcurrentHashMap()); + gceSet.add(l3ecmpGce); + Set retval = pendingGroups + .putIfAbsent(gi.outerGrpDesc.appCookie(), gceSet); + if (retval != null) { + retval.add(l3ecmpGce); + } + + groupService.addGroup(gi.innerGrpDesc); + } + } private void addBucketToGroup(NextObjective nextObjective) { // TODO Auto-generated method stub } + private void waitToAddBucketToGroup(NextObjective nextObjective) { + // TODO Auto-generated method stub + } + private void removeBucketFromGroup(NextObjective nextObjective) { // TODO Auto-generated method stub } @@ -1009,45 +1392,11 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline private void processGroupChain(GroupChainElem gce) { int waitOnGroups = gce.decrementAndGetGroupsWaitedOn(); if (waitOnGroups != 0) { - log.debug("GCE: {} waiting on {} groups. Not processing yet", - gce, waitOnGroups); + log.debug("GCE: {} not ready to be processed", gce); return; } - List buckets = new ArrayList<>(); - switch (gce.groupType) { - case INDIRECT: - GroupBucket ibucket = DefaultGroupBucket - .createIndirectGroupBucket(gce.bucketActions.iterator().next()); - buckets.add(ibucket); - break; - case ALL: - for (TrafficTreatment tt : gce.bucketActions) { - GroupBucket abucket = DefaultGroupBucket - .createAllGroupBucket(tt); - buckets.add(abucket); - } - break; - case SELECT: - for (TrafficTreatment tt : gce.bucketActions) { - GroupBucket sbucket = DefaultGroupBucket - .createSelectGroupBucket(tt); - buckets.add(sbucket); - } - break; - case FAILOVER: - default: - log.error("Unknown or unimplemented GroupChainElem {}", gce); - } - - if (buckets.size() > 0) { - GroupDescription groupDesc = new DefaultGroupDescription( - deviceId, gce.groupType, - new GroupBuckets(buckets), - gce.gkey, - gce.givenGroupId, - gce.appId); - groupService.addGroup(groupDesc); - } + log.debug("GCE: {} ready to be processed", gce); + groupService.addGroup(gce.groupDescription); } private class GroupChecker implements Runnable { @@ -1063,19 +1412,23 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline keys.stream().forEach(key -> { //first check for group chain - GroupChainElem gce = pendingGroups.remove(key); - if (gce != null) { - log.info("Group service processed group key {}. Processing next " - + "group in group chain with group key {}", - appKryo.deserialize(key.key()), - appKryo.deserialize(gce.gkey.key())); - processGroupChain(gce); + Set gceSet = pendingGroups.remove(key); + if (gceSet != null) { + for (GroupChainElem gce : gceSet) { + log.info("Group service processed group key {} in device {}. " + + "Processing next group in group chain with group id {}", + key, deviceId, + Integer.toHexString(gce.groupDescription.givenGroupId())); + processGroupChain(gce); + } } else { - OfdpaGroupChain obj = pendingNextObjectives.getIfPresent(key); - log.info("Group service processed group key {}. Done implementing " - + "next objective: {}", appKryo.deserialize(key.key()), - obj.nextObjective().id()); + OfdpaNextGroup obj = pendingNextObjectives.getIfPresent(key); if (obj != null) { + log.info("Group service processed group key {} in device:{}. " + + "Done implementing next objective: {} <<-->> gid:{}", + key, deviceId, obj.nextObjective().id(), + Integer.toHexString(groupService.getGroup(deviceId, key) + .givenGroupId())); pass(obj.nextObjective()); pendingNextObjectives.invalidate(key); flowObjectiveStore.putNextGroup(obj.nextObjective().id(), obj); @@ -1088,23 +1441,27 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline private class InnerGroupListener implements GroupListener { @Override public void event(GroupEvent event) { - log.debug("received group event of type {}", event.type()); + log.trace("received group event of type {}", event.type()); if (event.type() == GroupEvent.Type.GROUP_ADDED) { GroupKey key = event.subject().appCookie(); // first check for group chain - GroupChainElem gce = pendingGroups.remove(key); - if (gce != null) { - log.info("group ADDED with group key {} .. " - + "Processing next group in group chain with group key {}", - appKryo.deserialize(key.key()), - appKryo.deserialize(gce.gkey.key())); - processGroupChain(gce); + Set gceSet = pendingGroups.remove(key); + if (gceSet != null) { + for (GroupChainElem gce : gceSet) { + log.info("group ADDED with group key {} .. " + + "Processing next group in group chain with group key {}", + key, + gce.groupDescription.appCookie()); + processGroupChain(gce); + } } else { - OfdpaGroupChain obj = pendingNextObjectives.getIfPresent(key); + OfdpaNextGroup obj = pendingNextObjectives.getIfPresent(key); if (obj != null) { - log.info("group ADDED with key {}.. Done implementing next " - + "objective: {}", - appKryo.deserialize(key.key()), obj.nextObjective().id()); + log.info("group ADDED with key {} in dev {}.. Done implementing next " + + "objective: {} <<-->> gid:{}", + key, deviceId, obj.nextObjective().id(), + Integer.toHexString(groupService.getGroup(deviceId, key) + .givenGroupId())); pass(obj.nextObjective()); pendingNextObjectives.invalidate(key); flowObjectiveStore.putNextGroup(obj.nextObjective().id(), obj); @@ -1115,30 +1472,35 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline } /** - * Represents a group-chain that implements a Next-Objective from - * the application. Includes information about the next objective Id, and the - * group keys for the groups in the group chain. The chain is expected to - * look like group0 --> group 1 --> outPort. Information about the groups - * themselves can be fetched from the Group Service using the group keys from - * objects instantiating this class. + * Represents an entire group-chain that implements a Next-Objective from + * the application. The objective is represented as a list of deques, where + * each deque can is a separate chain of groups. + *

+ * For example, an ECMP group with 3 buckets, where each bucket points to + * a group chain of L3 Unicast and L2 interface groups will look like this: + *

    + *
  • List[0] is a Deque of GroupKeyECMP(first)-GroupKeyL3(middle)-GroupKeyL2(last) + *
  • List[1] is a Deque of GroupKeyECMP(first)-GroupKeyL3(middle)-GroupKeyL2(last) + *
  • List[2] is a Deque of GroupKeyECMP(first)-GroupKeyL3(middle)-GroupKeyL2(last) + *
+ * where the first element of each deque is the same, representing the + * top level ECMP group, while every other element represents a unique groupKey. + *

+ * Also includes information about the next objective that + * resulted in this group-chain. * - * XXX Revisit this - since the forwarding objective only ever needs the - * groupkey of the top-level group in the group chain, why store a series - * of groupkeys. Also the group-chain list only works for 1-to-1 chaining, - * not for 1-to-many chaining. */ - private class OfdpaGroupChain implements NextGroup { + private class OfdpaNextGroup implements NextGroup { private final NextObjective nextObj; - private final List gkeys; + private final List> gkeys; - /** expected group chain: group0 --> group1 --> port. */ - public OfdpaGroupChain(List gkeys, NextObjective nextObj) { + public OfdpaNextGroup(List> gkeys, NextObjective nextObj) { this.gkeys = gkeys; this.nextObj = nextObj; } @SuppressWarnings("unused") - public List groupKeys() { + public List> groupKey() { return gkeys; } @@ -1161,22 +1523,11 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline * preceding groups in the group chain to be created. */ private class GroupChainElem { - private Collection bucketActions; - private Integer givenGroupId; - private GroupDescription.Type groupType; - private GroupKey gkey; - private ApplicationId appId; + private GroupDescription groupDescription; private AtomicInteger waitOnGroups; - GroupChainElem(GroupKey gkey, Integer givenGroupId, - GroupDescription.Type groupType, - Collection tr, ApplicationId appId, - int waitOnGroups) { - this.bucketActions = tr; - this.givenGroupId = givenGroupId; - this.groupType = groupType; - this.gkey = gkey; - this.appId = appId; + GroupChainElem(GroupDescription groupDescription, int waitOnGroups) { + this.groupDescription = groupDescription; this.waitOnGroups = new AtomicInteger(waitOnGroups); } @@ -1194,7 +1545,10 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline @Override public String toString() { - return Integer.toHexString(givenGroupId); + return (Integer.toHexString(groupDescription.givenGroupId()) + + " groupKey: " + groupDescription.appCookie() + + " waiting-on-groups: " + waitOnGroups.get() + + " device: " + deviceId); } } diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java new file mode 100644 index 00000000..8a7b22b8 --- /dev/null +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java @@ -0,0 +1,238 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.driver.pipeline; + +import org.onlab.osgi.ServiceDirectory; +import org.onlab.packet.EthType; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.DefaultAnnotations; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.MastershipRole; +import org.onosproject.net.PortNumber; +import org.onosproject.net.behaviour.Pipeliner; +import org.onosproject.net.behaviour.PipelinerContext; +import org.onosproject.net.device.DefaultDeviceDescription; +import org.onosproject.net.device.DeviceDescription; +import org.onosproject.net.device.DeviceProvider; +import org.onosproject.net.device.DeviceProviderRegistry; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.driver.AbstractHandlerBehaviour; +import org.onosproject.net.flow.DefaultFlowRule; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.FlowRule; +import org.onosproject.net.flow.FlowRuleOperations; +import org.onosproject.net.flow.FlowRuleOperationsContext; +import org.onosproject.net.flow.FlowRuleService; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.instructions.Instructions; +import org.onosproject.net.flowobjective.FilteringObjective; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.NextObjective; +import org.onosproject.net.flowobjective.ObjectiveError; +import org.onosproject.net.packet.PacketPriority; +import org.onosproject.net.provider.AbstractProvider; +import org.onosproject.net.provider.ProviderId; +import org.slf4j.Logger; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Pipeliner for OLT device. + */ +public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { + + private final Logger log = getLogger(getClass()); + + static final ProviderId PID = new ProviderId("olt", "org.onosproject.olt", true); + + static final String DEVICE = "isAccess"; + static final String OLT = "true"; + + private ServiceDirectory serviceDirectory; + private FlowRuleService flowRuleService; + private DeviceId deviceId; + private CoreService coreService; + + private ApplicationId appId; + + private DeviceProvider provider = new AnnotationProvider(); + + + @Override + public void init(DeviceId deviceId, PipelinerContext context) { + this.serviceDirectory = context.directory(); + this.deviceId = deviceId; + DeviceProviderRegistry registry = + serviceDirectory.get(DeviceProviderRegistry.class); + flowRuleService = serviceDirectory.get(FlowRuleService.class); + coreService = serviceDirectory.get(CoreService.class); + + /*try { + DeviceProviderService providerService = registry.register(provider); + providerService.deviceConnected(deviceId, + description(deviceId, DEVICE, OLT)); + } finally { + registry.unregister(provider); + }*/ + + appId = coreService.registerApplication( + "org.onosproject.driver.OLTPipeline"); + + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchEthType(EthType.EtherType.EAPOL.ethType().toShort()) + .build(); + + TrafficTreatment treatment = DefaultTrafficTreatment.builder() + .punt() + .build(); + + FlowRule flowRule = new DefaultFlowRule(deviceId, selector, treatment, + PacketPriority.CONTROL.priorityValue(), + appId, 0, true, null); + + //flowRuleService.applyFlowRules(flowRule); + } + + @Override + public void filter(FilteringObjective filter) { + throw new UnsupportedOperationException("OLT does not filter."); + } + + @Override + public void forward(ForwardingObjective fwd) { + FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder(); + + if (fwd.flag() != ForwardingObjective.Flag.VERSATILE) { + throw new UnsupportedOperationException( + "Only VERSATILE is supported."); + } + + boolean isPunt = fwd.treatment().immediate().stream().anyMatch(i -> { + if (i instanceof Instructions.OutputInstruction) { + Instructions.OutputInstruction out = (Instructions.OutputInstruction) i; + return out.port().equals(PortNumber.CONTROLLER); + } + return false; + }); + + if (isPunt) { + return; + } + + TrafficSelector selector = fwd.selector(); + TrafficTreatment treatment = fwd.treatment(); + + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder() + .forDevice(deviceId) + .withSelector(selector) + .withTreatment(treatment) + .fromApp(fwd.appId()) + .withPriority(fwd.priority()); + + if (fwd.permanent()) { + ruleBuilder.makePermanent(); + } else { + ruleBuilder.makeTemporary(fwd.timeout()); + } + + switch (fwd.op()) { + case ADD: + flowBuilder.add(ruleBuilder.build()); + break; + case REMOVE: + flowBuilder.remove(ruleBuilder.build()); + break; + default: + log.warn("Unknown operation {}", fwd.op()); + } + + flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() { + @Override + public void onSuccess(FlowRuleOperations ops) { + if (fwd.context().isPresent()) { + fwd.context().get().onSuccess(fwd); + } + } + + @Override + public void onError(FlowRuleOperations ops) { + if (fwd.context().isPresent()) { + fwd.context().get().onError(fwd, ObjectiveError.FLOWINSTALLATIONFAILED); + } + } + })); + } + + @Override + public void next(NextObjective nextObjective) { + throw new UnsupportedOperationException("OLT does not next hop."); + } + + /** + * Build a device description. + * + * @param deviceId a deviceId + * @param key the key of the annotation + * @param value the value for the annotation + * @return a device description + */ + private DeviceDescription description(DeviceId deviceId, String key, String value) { + DeviceService deviceService = serviceDirectory.get(DeviceService.class); + Device device = deviceService.getDevice(deviceId); + + checkNotNull(device, "Device not found in device service."); + + DefaultAnnotations.Builder builder = DefaultAnnotations.builder(); + if (value != null) { + builder.set(key, value); + } else { + builder.remove(key); + } + return new DefaultDeviceDescription(device.id().uri(), device.type(), + device.manufacturer(), device.hwVersion(), + device.swVersion(), device.serialNumber(), + device.chassisId(), builder.build()); + } + + /** + * Simple ancillary provider used to annotate device. + */ + private static final class AnnotationProvider + extends AbstractProvider implements DeviceProvider { + private AnnotationProvider() { + super(PID); + } + + @Override + public void triggerProbe(DeviceId deviceId) { + } + + @Override + public void roleChanged(DeviceId deviceId, MastershipRole newRole) { + } + + @Override + public boolean isReachable(DeviceId deviceId) { + return false; + } + } + +} diff --git a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java index b5541065..8ac5eec8 100644 --- a/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java +++ b/framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java @@ -47,6 +47,7 @@ import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flow.criteria.Criteria; import org.onosproject.net.flow.criteria.Criterion; +import org.onosproject.net.flow.criteria.Criterion.Type; import org.onosproject.net.flow.criteria.EthCriterion; import org.onosproject.net.flow.criteria.EthTypeCriterion; import org.onosproject.net.flow.criteria.IPCriterion; @@ -73,6 +74,7 @@ import org.onosproject.net.group.GroupEvent; import org.onosproject.net.group.GroupKey; import org.onosproject.net.group.GroupListener; import org.onosproject.net.group.GroupService; +import org.onosproject.store.serializers.KryoNamespaces; import org.slf4j.Logger; import java.util.ArrayList; @@ -129,8 +131,13 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour groupedThreads("onos/pipeliner", "spring-open-%d")); protected KryoNamespace appKryo = new KryoNamespace.Builder() - .register(GroupKey.class).register(DefaultGroupKey.class) - .register(SegmentRoutingGroup.class).register(byte[].class).build(); + .register(KryoNamespaces.API) + .register(GroupKey.class) + .register(DefaultGroupKey.class) + .register(TrafficTreatment.class) + .register(SpringOpenGroup.class) + .register(byte[].class) + .build(); @Override public void init(DeviceId deviceId, PipelinerContext context) { @@ -202,17 +209,15 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour @Override public void onSuccess(FlowRuleOperations ops) { pass(fwd); - log.debug("Provisioned tables in {} with " - + "forwarding rules for segment " - + "router", deviceId); + log.debug("Provisioned tables in {} successfully with " + + "forwarding rules", deviceId); } @Override public void onError(FlowRuleOperations ops) { fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED); log.warn("Failed to provision tables in {} with " - + "forwarding rules for segment router", - deviceId); + + "forwarding rules", deviceId); } })); @@ -220,26 +225,50 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour @Override public void next(NextObjective nextObjective) { - - log.debug("Processing NextObjective id{} op{}", nextObjective.id(), - nextObjective.op()); - if (nextObjective.op() == Objective.Operation.REMOVE) { - if (nextObjective.next().isEmpty()) { - removeGroup(nextObjective); - } else { - removeBucketFromGroup(nextObjective); + NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id()); + switch (nextObjective.op()) { + case ADD: + if (nextGroup != null) { + log.warn("Cannot add next {} that already exists in device {}", + nextObjective.id(), deviceId); + return; } - } else if (nextObjective.op() == Objective.Operation.ADD) { - NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id()); + log.debug("Processing NextObjective id{} in dev{} - add group", + nextObjective.id(), deviceId); + addGroup(nextObjective); + break; + case ADD_TO_EXISTING: if (nextGroup != null) { + log.debug("Processing NextObjective id{} in dev{} - add bucket", + nextObjective.id(), deviceId); addBucketToGroup(nextObjective); } else { - addGroup(nextObjective); + log.warn("Cannot add to group that does not exist"); } - } else { + break; + case REMOVE: + if (nextGroup == null) { + log.warn("Cannot remove next {} that does not exist in device {}", + nextObjective.id(), deviceId); + return; + } + log.debug("Processing NextObjective id{} in dev{} - remove group", + nextObjective.id(), deviceId); + removeGroup(nextObjective); + break; + case REMOVE_FROM_EXISTING: + if (nextGroup == null) { + log.warn("Cannot remove from next {} that does not exist in device {}", + nextObjective.id(), deviceId); + return; + } + log.debug("Processing NextObjective id{} in dev{} - remove bucket", + nextObjective.id(), deviceId); + removeBucketFromGroup(nextObjective); + break; + default: log.warn("Unsupported operation {}", nextObjective.op()); } - } private void removeGroup(NextObjective nextObjective) { @@ -256,7 +285,6 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour List buckets; switch (nextObjective.type()) { case SIMPLE: - log.debug("processing SIMPLE next objective"); Collection treatments = nextObjective.next(); if (treatments.size() == 1) { TrafficTreatment treatment = treatments.iterator().next(); @@ -273,39 +301,57 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour key, null, nextObjective.appId()); - log.debug("Creating SIMPLE group for next objective id {}", - nextObjective.id()); - groupService.addGroup(groupDescription); + log.debug("Creating SIMPLE group for next objective id {} " + + "in dev:{}", nextObjective.id(), deviceId); pendingGroups.put(key, nextObjective); + groupService.addGroup(groupDescription); } break; case HASHED: - log.debug("processing HASHED next objective"); - buckets = nextObjective - .next() - .stream() - .map((treatment) -> DefaultGroupBucket - .createSelectGroupBucket(treatment)) - .collect(Collectors.toList()); - if (!buckets.isEmpty()) { - final GroupKey key = new DefaultGroupKey( - appKryo.serialize(nextObjective - .id())); - GroupDescription groupDescription = new DefaultGroupDescription( - deviceId, - GroupDescription.Type.SELECT, - new GroupBuckets(buckets), - key, - null, - nextObjective.appId()); - log.debug("Creating HASHED group for next objective id {}", - nextObjective.id()); - groupService.addGroup(groupDescription); - pendingGroups.put(key, nextObjective); + // we convert MPLS ECMP groups to flow-actions for a single + // bucket(output port). + boolean mplsEcmp = false; + if (nextObjective.meta() != null) { + for (Criterion c : nextObjective.meta().criteria()) { + if (c.type() == Type.MPLS_LABEL) { + mplsEcmp = true; + } + } + } + if (mplsEcmp) { + // covert to flow-actions in a dummy group by choosing the first bucket + log.debug("Converting HASHED group for next objective id {} " + + "to flow-actions in device:{}", nextObjective.id(), + deviceId); + TrafficTreatment treatment = nextObjective.next().iterator().next(); + flowObjectiveStore.putNextGroup(nextObjective.id(), + new SpringOpenGroup(null, treatment)); + } else { + // process as ECMP group + buckets = nextObjective + .next() + .stream() + .map((treatment) -> DefaultGroupBucket + .createSelectGroupBucket(treatment)) + .collect(Collectors.toList()); + if (!buckets.isEmpty()) { + final GroupKey key = new DefaultGroupKey( + appKryo.serialize(nextObjective.id())); + GroupDescription groupDescription = new DefaultGroupDescription( + deviceId, + GroupDescription.Type.SELECT, + new GroupBuckets(buckets), + key, + null, + nextObjective.appId()); + log.debug("Creating HASHED group for next objective id {}" + + " in dev:{}", nextObjective.id(), deviceId); + pendingGroups.put(key, nextObjective); + groupService.addGroup(groupDescription); + } } break; case BROADCAST: - log.debug("processing BROADCAST next objective"); buckets = nextObjective .next() .stream() @@ -323,10 +369,10 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour key, null, nextObjective.appId()); - log.debug("Creating BROADCAST group for next objective id {}", - nextObjective.id()); - groupService.addGroup(groupDescription); + log.debug("Creating BROADCAST group for next objective id {} " + + "in device {}", nextObjective.id(), deviceId); pendingGroups.put(key, nextObjective); + groupService.addGroup(groupDescription); } break; case FAILOVER: @@ -417,9 +463,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour } private Collection processVersatile(ForwardingObjective fwd) { - log.debug("Processing versatile forwarding objective"); + log.debug("Processing versatile forwarding objective in dev:{}", deviceId); TrafficSelector selector = fwd.selector(); - TrafficTreatment treatment = null; EthTypeCriterion ethType = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE); if (ethType == null) { @@ -428,50 +473,60 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour return Collections.emptySet(); } + if (fwd.treatment() == null && fwd.nextId() == null) { + log.error("VERSATILE forwarding objective needs next objective ID " + + "or treatment."); + return Collections.emptySet(); + } + // emulation of ACL table (for versatile fwd objective) requires + // overriding any previous instructions TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment .builder(); treatmentBuilder.wipeDeferred(); if (fwd.nextId() != null) { NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId()); - if (next != null) { - GroupKey key = appKryo.deserialize(next.data()); - - Group group = groupService.getGroup(deviceId, key); - - if (group == null) { - log.warn("The group left!"); - fail(fwd, ObjectiveError.GROUPMISSING); - return Collections.emptySet(); + SpringOpenGroup soGroup = appKryo.deserialize(next.data()); + if (soGroup.dummy) { + // need to convert to flow-actions + for (Instruction ins : soGroup.treatment.allInstructions()) { + treatmentBuilder.add(ins); + } + } else { + GroupKey key = soGroup.key; + Group group = groupService.getGroup(deviceId, key); + if (group == null) { + log.warn("The group left!"); + fail(fwd, ObjectiveError.GROUPMISSING); + return Collections.emptySet(); + } + treatmentBuilder.deferred().group(group.id()); + log.debug("Adding OUTGROUP action"); } - treatmentBuilder.deferred().group(group.id()); - treatment = treatmentBuilder.build(); - log.debug("Adding OUTGROUP action"); } - } else if (fwd.treatment() != null) { + } + + if (fwd.treatment() != null) { if (fwd.treatment().allInstructions().size() == 1 && fwd.treatment().allInstructions().get(0).type() == Instruction.Type.OUTPUT) { OutputInstruction o = (OutputInstruction) fwd.treatment().allInstructions().get(0); if (o.port() == PortNumber.CONTROLLER) { treatmentBuilder.punt(); - treatment = treatmentBuilder.build(); } else { - treatment = fwd.treatment(); + treatmentBuilder.add(o); } } else { - treatment = fwd.treatment(); + for (Instruction ins : fwd.treatment().allInstructions()) { + treatmentBuilder.add(ins); + } } - } else { - log.warn("VERSATILE forwarding objective needs next objective ID " - + "or treatment."); - return Collections.emptySet(); } FlowRule.Builder ruleBuilder = DefaultFlowRule.builder() .fromApp(fwd.appId()).withPriority(fwd.priority()) .forDevice(deviceId).withSelector(fwd.selector()) - .withTreatment(treatment); + .withTreatment(treatmentBuilder.build()); if (fwd.permanent()) { ruleBuilder.makePermanent(); @@ -508,7 +563,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour } protected Collection processSpecific(ForwardingObjective fwd) { - log.debug("Processing specific"); + log.debug("Processing specific fwd objective:{} in dev:{} with next:{}", + fwd.id(), deviceId, fwd.nextId()); boolean isEthTypeObj = isSupportedEthTypeObjective(fwd); boolean isEthDstObj = isSupportedEthDstObjective(fwd); @@ -518,7 +574,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour return processEthDstSpecificObjective(fwd); } else { log.warn("processSpecific: Unsupported " - + "forwarding objective criteraia"); + + "forwarding objective criteria"); fail(fwd, ObjectiveError.UNSUPPORTED); return Collections.emptySet(); } @@ -540,7 +596,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour .getCriterion(Criterion.Type.IPV4_DST)) .ip()); forTableId = ipv4UnicastTableId; - log.debug("processing IPv4 specific forwarding objective"); + log.debug("processing IPv4 specific forwarding objective:{} in dev:{}", + fwd.id(), deviceId); } else { filteredSelectorBuilder = filteredSelectorBuilder .matchEthType(Ethernet.MPLS_UNICAST) @@ -550,7 +607,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour //if (selector.getCriterion(Criterion.Type.MPLS_BOS) != null) { //} forTableId = mplsTableId; - log.debug("processing MPLS specific forwarding objective"); + log.debug("processing MPLS specific forwarding objective:{} in dev:{}", + fwd.id(), deviceId); } TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment @@ -561,24 +619,28 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour } } - //TODO: Analyze the forwarding objective here to make - //device specific decision such as no ECMP groups in Dell - //switches. if (fwd.nextId() != null) { NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId()); - if (next != null) { - GroupKey key = appKryo.deserialize(next.data()); - - Group group = groupService.getGroup(deviceId, key); - - if (group == null) { - log.warn("The group left!"); - fail(fwd, ObjectiveError.GROUPMISSING); - return Collections.emptySet(); + SpringOpenGroup soGroup = appKryo.deserialize(next.data()); + if (soGroup.dummy) { + log.debug("Adding flow-actions for fwd. obj. {} " + + "in dev: {}", fwd.id(), deviceId); + for (Instruction ins : soGroup.treatment.allInstructions()) { + treatmentBuilder.add(ins); + } + } else { + GroupKey key = soGroup.key; + Group group = groupService.getGroup(deviceId, key); + if (group == null) { + log.warn("The group left!"); + fail(fwd, ObjectiveError.GROUPMISSING); + return Collections.emptySet(); + } + treatmentBuilder.deferred().group(group.id()); + log.debug("Adding OUTGROUP action to group:{} for fwd. obj. {} " + + "in dev: {}", group.id(), fwd.id(), deviceId); } - treatmentBuilder.deferred().group(group.id()); - log.debug("Adding OUTGROUP action"); } else { log.warn("processSpecific: No associated next objective object"); fail(fwd, ObjectiveError.GROUPMISSING); @@ -621,6 +683,12 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour // Do not match MacAddress for subnet broadcast entry if (!ethCriterion.mac().equals(MacAddress.NONE)) { filteredSelectorBuilder.matchEthDst(ethCriterion.mac()); + log.debug("processing L2 forwarding objective:{} in dev:{}", + fwd.id(), deviceId); + } else { + log.debug("processing L2 Broadcast forwarding objective:{} " + + "in dev:{} for vlan:{}", + fwd.id(), deviceId, vlanIdCriterion.vlanId()); } filteredSelectorBuilder.matchVlanId(vlanIdCriterion.vlanId()); TrafficSelector filteredSelector = filteredSelectorBuilder.build(); @@ -635,14 +703,24 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour if (fwd.nextId() != null) { NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId()); if (next != null) { - GroupKey key = appKryo.deserialize(next.data()); - Group group = groupService.getGroup(deviceId, key); - if (group != null) { - treatmentBuilder.deferred().group(group.id()); + SpringOpenGroup soGrp = appKryo.deserialize(next.data()); + if (soGrp.dummy) { + log.debug("Adding flow-actions for fwd. obj. {} " + + "in dev: {}", fwd.id(), deviceId); + for (Instruction ins : soGrp.treatment.allInstructions()) { + treatmentBuilder.add(ins); + } } else { - log.warn("Group Missing"); - fail(fwd, ObjectiveError.GROUPMISSING); - return Collections.emptySet(); + GroupKey key = soGrp.key; + Group group = groupService.getGroup(deviceId, key); + if (group == null) { + log.warn("The group left!"); + fail(fwd, ObjectiveError.GROUPMISSING); + return Collections.emptySet(); + } + treatmentBuilder.deferred().group(group.id()); + log.debug("Adding OUTGROUP action to group:{} for fwd. obj. {} " + + "in dev: {}", group.id(), fwd.id(), deviceId); } } } @@ -869,14 +947,14 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour public void onSuccess(FlowRuleOperations ops) { pass(filt); log.debug("Provisioned tables in {} with fitering " - + "rules for segment router", deviceId); + + "rules", deviceId); } @Override public void onError(FlowRuleOperations ops) { fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED); log.warn("Failed to provision tables in {} with " - + "fitering rules for segment router", deviceId); + + "fitering rules", deviceId); } })); } @@ -934,15 +1012,17 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour @Override public void event(GroupEvent event) { if (event.type() == GroupEvent.Type.GROUP_ADDED) { - log.debug("InnerGroupListener: Group ADDED " + log.trace("InnerGroupListener: Group ADDED " + "event received in device {}", deviceId); GroupKey key = event.subject().appCookie(); NextObjective obj = pendingGroups.getIfPresent(key); if (obj != null) { + log.debug("Group verified: dev:{} gid:{} <<->> nextId:{}", + deviceId, event.subject().id(), obj.id()); flowObjectiveStore .putNextGroup(obj.id(), - new SegmentRoutingGroup(key)); + new SpringOpenGroup(key, null)); pass(obj); pendingGroups.invalidate(key); } @@ -971,21 +1051,47 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour if (obj == null) { return; } + log.debug("Group verified: dev:{} gid:{} <<->> nextId:{}", + deviceId, + groupService.getGroup(deviceId, key).id(), + obj.id()); pass(obj); pendingGroups.invalidate(key); - flowObjectiveStore.putNextGroup(obj.id(), - new SegmentRoutingGroup( - key)); - }); + flowObjectiveStore.putNextGroup( + obj.id(), + new SpringOpenGroup(key, null)); + }); } } - private class SegmentRoutingGroup implements NextGroup { - + /** + * SpringOpenGroup can either serve as storage for a GroupKey which can be + * used to fetch the group from the Group Service, or it can be serve as storage + * for Traffic Treatments which can be used as flow actions. In the latter + * case, we refer to this as a dummy group. + * + */ + private class SpringOpenGroup implements NextGroup { + private final boolean dummy; private final GroupKey key; + private final TrafficTreatment treatment; - public SegmentRoutingGroup(GroupKey key) { - this.key = key; + /** + * Storage for a GroupKey or a TrafficTreatment. One of the params + * to this constructor must be null. + * @param key represents a GroupKey + * @param treatment represents flow actions in a dummy group + */ + public SpringOpenGroup(GroupKey key, TrafficTreatment treatment) { + if (key == null) { + this.key = new DefaultGroupKey(new byte[]{0}); + this.treatment = treatment; + this.dummy = true; + } else { + this.key = key; + this.treatment = DefaultTrafficTreatment.builder().build(); + this.dummy = false; + } } @SuppressWarnings("unused") @@ -995,7 +1101,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour @Override public byte[] data() { - return appKryo.serialize(key); + return appKryo.serialize(this); } } diff --git a/framework/src/onos/drivers/src/main/resources/onos-drivers.xml b/framework/src/onos/drivers/src/main/resources/onos-drivers.xml index 0349e1c2..a172c18b 100644 --- a/framework/src/onos/drivers/src/main/resources/onos-drivers.xml +++ b/framework/src/onos/drivers/src/main/resources/onos-drivers.xml @@ -32,13 +32,14 @@ impl="org.onosproject.driver.handshaker.NiciraSwitchHandshaker"/> - - + + + + manufacturer="" hwVersion="" swVersion=""> + manufacturer="ECI Telecom" hwVersion="Optical.*" swVersion="V_1_0"> diff --git a/framework/src/onos/drivers/src/main/resources/org/onosproject/driver/netconf/controllers.xml b/framework/src/onos/drivers/src/main/resources/org/onosproject/driver/netconf/controllers.xml new file mode 100644 index 00000000..21e4dd14 --- /dev/null +++ b/framework/src/onos/drivers/src/main/resources/org/onosproject/driver/netconf/controllers.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/framework/src/onos/drivers/src/test/java/org/onosproject/driver/netconf/XmlConfigParserTest.java b/framework/src/onos/drivers/src/test/java/org/onosproject/driver/netconf/XmlConfigParserTest.java new file mode 100644 index 00000000..d8b695c3 --- /dev/null +++ b/framework/src/onos/drivers/src/test/java/org/onosproject/driver/netconf/XmlConfigParserTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.driver.netconf; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onosproject.net.behaviour.ControllerInfo; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertTrue; +import static org.onosproject.driver.netconf.XmlConfigParser.*; + +//import static org.junit.Assert.*; + +/** + * Test the XML document Parsing for netconf configuration. + */ +public class XmlConfigParserTest { + + + @Test + public void basics() throws IOException { + InputStream stream = getClass().getResourceAsStream("testConfig.xml"); + List controllers = parseStreamControllers(loadXml(stream)); + assertTrue(controllers.get(0).equals(new ControllerInfo( + IpAddress.valueOf("10.128.12.1"), 6653, "tcp"))); + assertTrue(controllers.get(1).equals(new ControllerInfo( + IpAddress.valueOf("10.128.12.2"), 6654, "tcp"))); + + } + + @Test + public void switchId() { + InputStream stream = getClass().getResourceAsStream("testConfig.xml"); + String switchId = parseSwitchId(loadXml(stream)); + assertTrue(switchId.equals("ofc-bridge")); + } + + @Test + public void capableSwitchId() { + InputStream stream = getClass().getResourceAsStream("testConfig.xml"); + String capableSwitchId = parseCapableSwitchId(loadXml(stream)); + assertTrue(capableSwitchId.equals("openvswitch")); + } + + @Test + public void controllersConfig() { + InputStream streamOrig = getClass().getResourceAsStream("testConfig.xml"); + InputStream streamCFG = XmlConfigParser.class + .getResourceAsStream("controllers.xml"); + String config = createControllersConfig(loadXml(streamCFG), + loadXml(streamOrig), "running", "merge", + "create", new ArrayList<>(Arrays.asList( + new ControllerInfo(IpAddress.valueOf("192.168.1.1"), + 5000, "tcp")))); + assertTrue(config.contains("192.168.1.1")); + assertTrue(config.contains("tcp")); + assertTrue(config.contains("5000")); + + } +} \ No newline at end of file diff --git a/framework/src/onos/drivers/src/test/resources/org/onosproject/driver/netconf/testConfig.xml b/framework/src/onos/drivers/src/test/resources/org/onosproject/driver/netconf/testConfig.xml new file mode 100644 index 00000000..88d1a3a3 --- /dev/null +++ b/framework/src/onos/drivers/src/test/resources/org/onosproject/driver/netconf/testConfig.xml @@ -0,0 +1,60 @@ + + + + + + + openvswitch + + + ofc-bridge + 666 + + down + false + false + false + + + + + + ofc-bridge + 00:01:02:03:04:05:06:07 + failSecureMode + + + (null) + 10.128.12.1 + 6653 + tcp + + + (null) + 10.128.12.2 + 6654 + tcp + + + + ofc-bridge + + + + + + \ No newline at end of file diff --git a/framework/src/onos/features/features.xml b/framework/src/onos/features/features.xml index 7d12d7b8..0d9c2c30 100644 --- a/framework/src/onos/features/features.xml +++ b/framework/src/onos/features/features.xml @@ -16,8 +16,7 @@ --> - mvn:org.onosproject/onos-features/@ONOS-VERSION/xml/features - + mvn:org.apache.karaf.features/standard/3.0.3/xml/features diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContext.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContext.java new file mode 100644 index 00000000..09c507dd --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContext.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.incubator.rpc; + +import com.google.common.annotations.Beta; + +// Implementation is expected to be a handler for RPC channel +// and shim-layer to convert Java Service interface calls to/from RPC call +/** + * Context for Remote service. + */ +@Beta +public interface RemoteServiceContext { + + // we may need a method to check connection state? + + /** + * Returns implementation of the specified service class. + * + * @param serviceClass service class + * @param type of service + * @return implementation class + * @throws UnsupportedOperationException if this context does not support it. + */ + T get(Class serviceClass); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContextProvider.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContextProvider.java new file mode 100644 index 00000000..47bbfbc9 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContextProvider.java @@ -0,0 +1,38 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc; + +import java.net.URI; + +import org.onosproject.net.provider.Provider; + +import com.google.common.annotations.Beta; + +//Factory to create RemoteServiceContext +/** + * Abstraction of a remote service implementation provider. + */ +@Beta +public interface RemoteServiceContextProvider extends Provider { + + /** + * Returns {@link RemoteServiceContext} for given URI. + * + * @param uri URI for remote end point. + * @return {@link RemoteServiceContext} + */ + RemoteServiceContext get(URI uri); +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContextProviderService.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContextProviderService.java new file mode 100644 index 00000000..42b976c5 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceContextProviderService.java @@ -0,0 +1,28 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc; + +import org.onosproject.net.provider.ProviderService; + +import com.google.common.annotations.Beta; + +// Not completely sure if we will make use of this at the moment +// added to follow existing {@link ProviderRegistry} pattern +@Beta +public interface RemoteServiceContextProviderService + extends ProviderService { + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceDirectory.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceDirectory.java new file mode 100644 index 00000000..0d2bbc70 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceDirectory.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc; + +import java.net.URI; + +import com.google.common.annotations.Beta; + +// This is actually the RPC Service, where consumers get +// RemoteSericeContext (~= RPC Session) for given URI +// expected to be implemented by some Manager class on Lower-side ONOS +/** + * Service for retrieving RPC session handler ({@link RemoteServiceContext}). + */ +@Beta +public interface RemoteServiceDirectory { + + /** + * Returns remote service context. + * + * @param uri URI representing remote end point. e.g., (grpc://hostname:port) + * @return remote service context + * @throws UnsupportedOperationException if URI scheme was not supported. + */ + RemoteServiceContext get(URI uri); + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceProviderRegistry.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceProviderRegistry.java new file mode 100644 index 00000000..3b3c3891 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/RemoteServiceProviderRegistry.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc; + +import org.onosproject.net.provider.ProviderRegistry; + +import com.google.common.annotations.Beta; + +/** + * Abstraction of a remote service provider registry. + */ +@Beta +public interface RemoteServiceProviderRegistry + extends ProviderRegistry { + +} diff --git a/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/package-info.java b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/package-info.java new file mode 100644 index 00000000..4ec56ae1 --- /dev/null +++ b/framework/src/onos/incubator/api/src/main/java/org/onosproject/incubator/rpc/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Incubating inter-cluster RPC APIs. + */ +package org.onosproject.incubator.rpc; diff --git a/framework/src/onos/incubator/pom.xml b/framework/src/onos/incubator/pom.xml index 5222fe98..8122a680 100644 --- a/framework/src/onos/incubator/pom.xml +++ b/framework/src/onos/incubator/pom.xml @@ -36,6 +36,7 @@ net store rpc + rpc-grpc diff --git a/framework/src/onos/incubator/rpc-grpc/features.xml b/framework/src/onos/incubator/rpc-grpc/features.xml new file mode 100644 index 00000000..df768fbb --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/features.xml @@ -0,0 +1,37 @@ + + + + + onos-api + mvn:com.google.protobuf/protobuf-java/3.0.0-beta-1 + mvn:io.netty/netty-common/4.1.0.Beta6 + mvn:io.netty/netty-buffer/4.1.0.Beta6 + mvn:io.netty/netty-transport/4.1.0.Beta6 + mvn:io.netty/netty-handler/4.1.0.Beta6 + mvn:io.netty/netty-codec/4.1.0.Beta6 + mvn:io.netty/netty-codec-http/4.1.0.Beta6 + mvn:io.netty/netty-codec-http2/4.1.0.Beta6 + mvn:io.netty/netty-resolver/4.1.0.Beta6 + mvn:com.twitter/hpack/0.11.0 + + wrap:mvn:com.google.auth/google-auth-library-credentials/0.3.0$Bundle-SymbolicName=com.google.auth.google-auth-library-credentials&Bundle-Version=0.3.0 + wrap:mvn:com.google.auth/google-auth-library-oauth2-http/0.3.0$Bundle-SymbolicName=com.google.auth.google-auth-library-oauth2-http&Bundle-Version=0.3.0 + wrap:mvn:io.grpc/grpc-all/0.9.0$Bundle-SymbolicName=io.grpc.grpc-all&Bundle-Version=0.9.0&Import-Package=io.netty.*;version=4.1.0.Beta6,javax.net.ssl,com.google.protobuf.nano;resolution:=optional,okio;resolution:=optional,* + mvn:${project.groupId}/${project.artifactId}/${project.version} + + diff --git a/framework/src/onos/incubator/rpc-grpc/pom.xml b/framework/src/onos/incubator/rpc-grpc/pom.xml new file mode 100644 index 00000000..f528ca53 --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/pom.xml @@ -0,0 +1,269 @@ + + + + 4.0.0 + + onos-incubator + org.onosproject + 1.4.0-SNAPSHOT + + + onos-incubator-rpc-grpc + bundle + + ONOS inter-cluster RPC based on gRPC + http://onosproject.org + + + org.onosproject.incubator.rpc.grpc + org.onosproject.incubator.rpc + + 0.9.0 + 4.1.0.Beta6 + + + + + protoc-plugin + https://dl.bintray.com/sergei-ivanov/maven/ + + + + + + + org.onosproject + onos-api + + + + org.onosproject + onos-incubator-api + + + + org.onosproject + onlab-osgi + + + + io.grpc + grpc-core + ${grpc.version} + + + io.grpc + grpc-protobuf + ${grpc.version} + + + io.grpc + grpc-stub + ${grpc.version} + + + io.grpc + grpc-netty + ${grpc.version} + + + io.grpc + grpc-auth + ${grpc.version} + + + + junit + junit + test + + + + org.onosproject + onos-api + test + tests + + + + org.apache.felix + org.apache.felix.scr.annotations + provided + + + + + + + kr.motd.maven + os-maven-plugin + 1.4.0.Final + + + + + + org.apache.felix + maven-bundle-plugin + true + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.felix + maven-scr-plugin + + + generate-scr-srcdescriptor + + scr + + + + + + true + + bundle + war + + + + + org.onosproject + onos-maven-plugin + + + cfg + generate-resources + + cfg + + + + swagger + generate-sources + + swagger + + + + app + package + + app + + + + + + + com.google.protobuf.tools + maven-protoc-plugin + 0.4.2 + + + com.google.protobuf:protoc:3.0.0-beta-1:exe:${os.detected.classifier} + grpc-java + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + + + + + compile + compile-custom + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.9.1 + + + add-source + generate-sources + + add-source + + + + ${project.build.directory}/generated-sources/protobuf/java + ${project.build.directory}/generated-sources/protobuf/grpc-java + + + + + + + + + + + + + + io.netty + netty-codec + ${grpc.netty.version} + + + io.netty + netty-transport + ${grpc.netty.version} + + + io.netty + netty-handler + ${grpc.netty.version} + + + io.netty + netty-buffer + ${grpc.netty.version} + + + io.netty + netty-common + ${grpc.netty.version} + + + com.twitter + hpack + + 0.11.0 + + + + + diff --git a/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderRegistryClientProxy.java b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderRegistryClientProxy.java new file mode 100644 index 00000000..cad0fbb6 --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderRegistryClientProxy.java @@ -0,0 +1,77 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.grpc; + +import java.util.Map; + +import org.onosproject.net.device.DeviceProvider; +import org.onosproject.net.device.DeviceProviderRegistry; +import org.onosproject.net.device.DeviceProviderService; +import org.onosproject.net.provider.AbstractProviderRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Maps; + +import io.grpc.Channel; +import io.grpc.ManagedChannel; + +// gRPC Client side +/** + * Proxy object to handle DeviceProviderRegistry calls. + * + * RPC wise, this will start/stop bidirectional streaming service sessions. + */ +final class DeviceProviderRegistryClientProxy + extends AbstractProviderRegistry + implements DeviceProviderRegistry { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final Channel channel; + + private final Map pServices; + + DeviceProviderRegistryClientProxy(ManagedChannel channel) { + this.channel = channel; + pServices = Maps.newIdentityHashMap(); + } + + @Override + protected synchronized DeviceProviderService createProviderService(DeviceProvider provider) { + + // Create session + DeviceProviderServiceClientProxy pService = new DeviceProviderServiceClientProxy(provider, channel); + log.debug("Created DeviceProviderServiceClientProxy", pService); + + DeviceProviderServiceClientProxy old = pServices.put(provider, pService); + if (old != null) { + // sanity check, can go away + log.warn("Duplicate registration detected for {}", provider.id()); + } + return pService; + } + + @Override + public synchronized void unregister(DeviceProvider provider) { + DeviceProviderServiceClientProxy pService = pServices.remove(provider); + log.debug("Unregistering DeviceProviderServiceClientProxy", pService); + super.unregister(provider); + if (pService != null) { + pService.shutdown(); + } + } +} diff --git a/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderServiceClientProxy.java b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderServiceClientProxy.java new file mode 100644 index 00000000..498011f2 --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderServiceClientProxy.java @@ -0,0 +1,295 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.grpc; + +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.stream.Collectors.toList; +import static org.onosproject.incubator.rpc.grpc.GrpcDeviceUtils.translate; +import static org.onosproject.net.DeviceId.deviceId; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.onosproject.grpc.Device.DeviceProviderMsg; +import org.onosproject.grpc.Device.DeviceProviderServiceMsg; +import org.onosproject.grpc.Device.IsReachableRequest; +import org.onosproject.grpc.Device.RoleChanged; +import org.onosproject.grpc.Device.TriggerProbe; +import org.onosproject.grpc.DeviceProviderRegistryRpcGrpc; +import org.onosproject.grpc.DeviceProviderRegistryRpcGrpc.DeviceProviderRegistryRpcStub; +import org.onosproject.net.DeviceId; +import org.onosproject.net.MastershipRole; +import org.onosproject.net.device.DeviceDescription; +import org.onosproject.net.device.DeviceProvider; +import org.onosproject.net.device.DeviceProviderService; +import org.onosproject.net.device.PortDescription; +import org.onosproject.net.device.PortStatistics; +import org.onosproject.net.provider.AbstractProviderService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +import io.grpc.Channel; +import io.grpc.stub.StreamObserver; + +// gRPC Client side +// gRPC wise, this object represents bidirectional streaming service session +// and deals with outgoing message stream +/** + * DeviceProviderService instance associated with given DeviceProvider. + */ +final class DeviceProviderServiceClientProxy + extends AbstractProviderService + implements DeviceProviderService { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final StreamObserver devProvService; + private final AtomicBoolean hasShutdown = new AtomicBoolean(false); + + private final Channel channel; + + DeviceProviderServiceClientProxy(DeviceProvider provider, Channel channel) { + super(provider); + this.channel = channel; + + DeviceProviderRegistryRpcStub stub = DeviceProviderRegistryRpcGrpc.newStub(channel); + log.debug("Calling RPC register({}) against {}", provider.id(), channel.authority()); + devProvService = stub.register(new DeviceProviderClientProxy(provider)); + + // send initialize message + DeviceProviderServiceMsg.Builder builder = DeviceProviderServiceMsg.newBuilder(); + builder.setRegisterProvider(builder.getRegisterProviderBuilder() + .setProviderScheme(provider.id().scheme()) + .build()); + devProvService.onNext(builder.build()); + } + + @Override + public void deviceConnected(DeviceId deviceId, + DeviceDescription deviceDescription) { + checkValidity(); + + DeviceProviderServiceMsg.Builder builder = DeviceProviderServiceMsg.newBuilder(); + builder.setDeviceConnected(builder.getDeviceConnectedBuilder() + .setDeviceId(deviceId.toString()) + .setDeviceDescription(translate(deviceDescription)) + .build()); + + devProvService.onNext(builder.build()); + } + + @Override + public void deviceDisconnected(DeviceId deviceId) { + checkValidity(); + + DeviceProviderServiceMsg.Builder builder = DeviceProviderServiceMsg.newBuilder(); + builder.setDeviceDisconnected(builder.getDeviceDisconnectedBuilder() + .setDeviceId(deviceId.toString()) + .build()); + + devProvService.onNext(builder.build()); + } + + @Override + public void updatePorts(DeviceId deviceId, + List portDescriptions) { + checkValidity(); + + DeviceProviderServiceMsg.Builder builder = DeviceProviderServiceMsg.newBuilder(); + List portDescs = + portDescriptions.stream() + .map(GrpcDeviceUtils::translate) + .collect(toList()); + + builder.setUpdatePorts(builder.getUpdatePortsBuilder() + .setDeviceId(deviceId.toString()) + .addAllPortDescriptions(portDescs) + .build()); + + devProvService.onNext(builder.build()); + } + + @Override + public void portStatusChanged(DeviceId deviceId, + PortDescription portDescription) { + checkValidity(); + + DeviceProviderServiceMsg.Builder builder = DeviceProviderServiceMsg.newBuilder(); + builder.setPortStatusChanged(builder.getPortStatusChangedBuilder() + .setDeviceId(deviceId.toString()) + .setPortDescription(translate(portDescription)) + .build()); + + devProvService.onNext(builder.build()); + } + + @Override + public void receivedRoleReply(DeviceId deviceId, MastershipRole requested, + MastershipRole response) { + checkValidity(); + + DeviceProviderServiceMsg.Builder builder = DeviceProviderServiceMsg.newBuilder(); + builder.setReceivedRoleReply(builder.getReceivedRoleReplyBuilder() + .setDeviceId(deviceId.toString()) + .setRequested(translate(requested)) + .setResponse(translate(response)) + .build()); + + devProvService.onNext(builder.build()); + } + + @Override + public void updatePortStatistics(DeviceId deviceId, + Collection portStatistics) { + checkValidity(); + + DeviceProviderServiceMsg.Builder builder = DeviceProviderServiceMsg.newBuilder(); + List portStats = + portStatistics.stream() + .map(GrpcDeviceUtils::translate) + .collect(toList()); + builder.setUpdatePortStatistics(builder.getUpdatePortStatisticsBuilder() + .setDeviceId(deviceId.toString()) + .addAllPortStatistics(portStats) + .build()); + + devProvService.onNext(builder.build()); + } + + /** + * Shutdown this session. + */ + public void shutdown() { + if (hasShutdown.compareAndSet(false, true)) { + log.info("Shutting down session over {}", channel.authority()); + // initiate clean shutdown from client + devProvService.onCompleted(); + invalidate(); + } + } + + /** + * Abnormally terminate this session. + * @param t error details + */ + public void shutdown(Throwable t) { + if (hasShutdown.compareAndSet(false, true)) { + log.error("Shutting down session over {}", channel.authority()); + // initiate abnormal termination from client + devProvService.onError(t); + invalidate(); + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("channel", channel.authority()) + .add("hasShutdown", hasShutdown.get()) + .toString(); + } + + // gRPC wise, this object handles incoming message stream + /** + * Translates DeviceProvider instructions received from RPC to Java calls. + */ + private final class DeviceProviderClientProxy + implements StreamObserver { + + private final DeviceProvider provider; + + DeviceProviderClientProxy(DeviceProvider provider) { + this.provider = checkNotNull(provider); + } + + @Override + public void onNext(DeviceProviderMsg msg) { + try { + log.trace("DeviceProviderClientProxy received: {}", msg); + onMethod(msg); + } catch (Exception e) { + log.error("Exception caught handling {} at DeviceProviderClientProxy", msg, e); + // initiate shutdown from client + shutdown(e); + } + } + + /** + * Translates received RPC message to {@link DeviceProvider} method calls. + * @param msg DeviceProvider message + */ + private void onMethod(DeviceProviderMsg msg) { + switch (msg.getMethodCase()) { + case TRIGGER_PROBE: + TriggerProbe triggerProbe = msg.getTriggerProbe(); + provider.triggerProbe(deviceId(triggerProbe.getDeviceId())); + break; + case ROLE_CHANGED: + RoleChanged roleChanged = msg.getRoleChanged(); + provider.roleChanged(deviceId(roleChanged.getDeviceId()), + translate(roleChanged.getNewRole())); + break; + case IS_REACHABLE_REQUEST: + IsReachableRequest isReachableRequest = msg.getIsReachableRequest(); + // check if reachable + boolean reachable = provider.isReachable(deviceId(isReachableRequest.getDeviceId())); + + int xid = isReachableRequest.getXid(); + // send response back DeviceProviderService channel + DeviceProviderServiceMsg.Builder builder = DeviceProviderServiceMsg.newBuilder(); + builder.setIsReachableResponse(builder.getIsReachableResponseBuilder() + .setXid(xid) + .setIsReachable(reachable) + .build()); + devProvService.onNext(builder.build()); + break; + + case METHOD_NOT_SET: + default: + log.warn("Unexpected method, ignoring", msg); + break; + } + } + + @Override + public void onCompleted() { + log.info("DeviceProviderClientProxy completed"); + // session terminated from remote + // TODO unregister...? how? + + //devProvService.onCompleted(); + } + + @Override + public void onError(Throwable t) { + log.error("DeviceProviderClientProxy#onError", t); + // session terminated from remote + // TODO unregister...? how? + //devProvService.onError(t); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("channel", channel.authority()) + .toString(); + } + } +} + diff --git a/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcDeviceUtils.java b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcDeviceUtils.java new file mode 100644 index 00000000..7045b0c2 --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcDeviceUtils.java @@ -0,0 +1,381 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.grpc; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.onlab.packet.ChassisId; +import org.onosproject.grpc.Device.DeviceType; +import org.onosproject.grpc.Port.PortType; +import org.onosproject.net.Annotations; +import org.onosproject.net.DefaultAnnotations; +import org.onosproject.net.Device; +import org.onosproject.net.MastershipRole; +import org.onosproject.net.Port; +import org.onosproject.net.Port.Type; +import org.onosproject.net.PortNumber; +import org.onosproject.net.SparseAnnotations; +import org.onosproject.net.device.DefaultDeviceDescription; +import org.onosproject.net.device.DefaultPortDescription; +import org.onosproject.net.device.DefaultPortStatistics; +import org.onosproject.net.device.DeviceDescription; +import org.onosproject.net.device.PortDescription; +import org.onosproject.net.device.PortStatistics; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.api.client.repackaged.com.google.common.annotations.Beta; + +/** + * gRPC message conversion related utilities. + */ +@Beta +public final class GrpcDeviceUtils { + + private static final Logger log = LoggerFactory.getLogger(GrpcDeviceUtils.class); + + /** + * Translates gRPC enum MastershipRole to ONOS enum. + * + * @param role mastership role in gRPC enum + * @return equivalent in ONOS enum + */ + public static MastershipRole translate(org.onosproject.grpc.Device.MastershipRole role) { + switch (role) { + case NONE: + return MastershipRole.NONE; + case MASTER: + return MastershipRole.MASTER; + case STANDBY: + return MastershipRole.STANDBY; + case UNRECOGNIZED: + log.warn("Unrecognized MastershipRole gRPC message: {}", role); + default: + return MastershipRole.NONE; + } + } + + /** + * Translates ONOS enum MastershipRole to gRPC enum. + * + * @param newRole ONOS' mastership role + * @return equivalent in gRPC message enum + */ + public static org.onosproject.grpc.Device.MastershipRole translate(MastershipRole newRole) { + switch (newRole) { + case MASTER: + return org.onosproject.grpc.Device.MastershipRole.MASTER; + case STANDBY: + return org.onosproject.grpc.Device.MastershipRole.STANDBY; + case NONE: + default: + return org.onosproject.grpc.Device.MastershipRole.NONE; + } + } + + + /** + * Translates gRPC DeviceDescription to {@link DeviceDescription}. + * + * @param deviceDescription gRPC message + * @return {@link DeviceDescription} + */ + public static DeviceDescription translate(org.onosproject.grpc.Device.DeviceDescription deviceDescription) { + URI uri = URI.create(deviceDescription.getDeviceUri()); + Device.Type type = translate(deviceDescription.getType()); + String manufacturer = deviceDescription.getManufacturer(); + String hwVersion = deviceDescription.getHwVersion(); + String swVersion = deviceDescription.getSwVersion(); + String serialNumber = deviceDescription.getSerialNumber(); + ChassisId chassis = new ChassisId(deviceDescription.getChassisId()); + return new DefaultDeviceDescription(uri, type, manufacturer, + hwVersion, swVersion, serialNumber, + chassis, + asAnnotations(deviceDescription.getAnnotations())); + } + + /** + * Translates {@link DeviceDescription} to gRPC DeviceDescription message. + * + * @param deviceDescription {@link DeviceDescription} + * @return gRPC DeviceDescription message + */ + public static org.onosproject.grpc.Device.DeviceDescription translate(DeviceDescription deviceDescription) { + + return org.onosproject.grpc.Device.DeviceDescription.newBuilder() + .setDeviceUri(deviceDescription.deviceUri().toString()) + .setType(translate(deviceDescription.type())) + .setManufacturer(deviceDescription.manufacturer()) + .setHwVersion(deviceDescription.hwVersion()) + .setSwVersion(deviceDescription.swVersion()) + .setSerialNumber(deviceDescription.serialNumber()) + .setChassisId(deviceDescription.chassisId().toString()) + .putAllAnnotations(asMap(deviceDescription.annotations())) + .build(); + } + + + /** + * Translates gRPC DeviceType to {@link Device.Type}. + * + * @param type gRPC message + * @return {@link Device.Type} + */ + public static Device.Type translate(org.onosproject.grpc.Device.DeviceType type) { + switch (type) { + case BALANCER: + return Device.Type.BALANCER; + case CONTROLLER: + return Device.Type.CONTROLLER; + case FIBER_SWITCH: + return Device.Type.FIBER_SWITCH; + case FIREWALL: + return Device.Type.FIREWALL; + case IDS: + return Device.Type.IDS; + case IPS: + return Device.Type.IPS; + case MICROWAVE: + return Device.Type.MICROWAVE; + case OTHER: + return Device.Type.OTHER; + case OTN: + return Device.Type.OTN; + case ROADM: + return Device.Type.ROADM; + case ROADM_OTN: + return Device.Type.ROADM_OTN; + case ROUTER: + return Device.Type.ROUTER; + case SWITCH: + return Device.Type.SWITCH; + case VIRTUAL: + return Device.Type.VIRTUAL; + + case UNRECOGNIZED: + default: + log.warn("Unexpected DeviceType: {}", type); + return Device.Type.OTHER; + } + } + + /** + * Translates {@link Type} to gRPC DeviceType. + * + * @param type {@link Type} + * @return gRPC message + */ + public static DeviceType translate(Device.Type type) { + switch (type) { + case BALANCER: + return DeviceType.BALANCER; + case CONTROLLER: + return DeviceType.CONTROLLER; + case FIBER_SWITCH: + return DeviceType.FIBER_SWITCH; + case FIREWALL: + return DeviceType.FIREWALL; + case IDS: + return DeviceType.IDS; + case IPS: + return DeviceType.IPS; + case MICROWAVE: + return DeviceType.MICROWAVE; + case OTHER: + return DeviceType.OTHER; + case OTN: + return DeviceType.OTN; + case ROADM: + return DeviceType.ROADM; + case ROADM_OTN: + return DeviceType.ROADM_OTN; + case ROUTER: + return DeviceType.ROUTER; + case SWITCH: + return DeviceType.SWITCH; + case VIRTUAL: + return DeviceType.VIRTUAL; + + default: + log.warn("Unexpected Device.Type: {}", type); + return DeviceType.OTHER; + } + } + + /** + * Translates gRPC PortDescription message to {@link PortDescription}. + * + * @param portDescription gRPC message + * @return {@link PortDescription} + */ + public static PortDescription translate(org.onosproject.grpc.Port.PortDescription portDescription) { + PortNumber number = PortNumber.fromString(portDescription.getPortNumber()); + boolean isEnabled = portDescription.getIsEnabled(); + Port.Type type = translate(portDescription.getType()); + long portSpeed = portDescription.getPortSpeed(); + SparseAnnotations annotations = asAnnotations(portDescription.getAnnotations()); + // TODO How to deal with more specific Port... + return new DefaultPortDescription(number, isEnabled, type, portSpeed, annotations); + } + + /** + * Translates {@link PortDescription} to gRPC PortDescription message. + * + * @param portDescription {@link PortDescription} + * @return gRPC PortDescription message + */ + public static org.onosproject.grpc.Port.PortDescription translate(PortDescription portDescription) { + // TODO How to deal with more specific Port... + return org.onosproject.grpc.Port.PortDescription.newBuilder() + .setPortNumber(portDescription.portNumber().toString()) + .setIsEnabled(portDescription.isEnabled()) + .setType(translate(portDescription.type())) + .setPortSpeed(portDescription.portSpeed()) + .putAllAnnotations(asMap(portDescription.annotations())) + .build(); + } + + /** + * Translates gRPC PortType to {@link Port.Type}. + * + * @param type gRPC message + * @return {@link Port.Type} + */ + public static Port.Type translate(PortType type) { + switch (type) { + case COPPER: + return Type.COPPER; + case FIBER: + return Type.FIBER; + case OCH: + return Type.OCH; + case ODUCLT: + return Type.ODUCLT; + case OMS: + return Type.OMS; + case PACKET: + return Type.PACKET; + case VIRTUAL: + return Type.VIRTUAL; + + case UNRECOGNIZED: + default: + log.warn("Unexpected PortType: {}", type); + return Type.COPPER; + } + } + + /** + * Translates {@link Port.Type} to gRPC PortType. + * + * @param type {@link Port.Type} + * @return gRPC message + */ + public static PortType translate(Port.Type type) { + switch (type) { + case COPPER: + return PortType.COPPER; + case FIBER: + return PortType.FIBER; + case OCH: + return PortType.OCH; + case ODUCLT: + return PortType.ODUCLT; + case OMS: + return PortType.OMS; + case PACKET: + return PortType.PACKET; + case VIRTUAL: + return PortType.VIRTUAL; + + default: + log.warn("Unexpected Port.Type: {}", type); + return PortType.COPPER; + } + } + + /** + * Translates gRPC PortStatistics message to {@link PortStatistics}. + * + * @param portStatistics gRPC PortStatistics message + * @return {@link PortStatistics} + */ + public static PortStatistics translate(org.onosproject.grpc.Port.PortStatistics portStatistics) { + // TODO implement adding missing fields + return DefaultPortStatistics.builder() + .setPort(portStatistics.getPort()) + .setPacketsReceived(portStatistics.getPacketsReceived()) + .setPacketsSent(portStatistics.getPacketsSent()) + .build(); + } + + /** + * Translates {@link PortStatistics} to gRPC PortStatistics message. + * + * @param portStatistics {@link PortStatistics} + * @return gRPC PortStatistics message + */ + public static org.onosproject.grpc.Port.PortStatistics translate(PortStatistics portStatistics) { + // TODO implement adding missing fields + return org.onosproject.grpc.Port.PortStatistics.newBuilder() + .setPort(portStatistics.port()) + .setPacketsReceived(portStatistics.packetsReceived()) + .setPacketsSent(portStatistics.packetsSent()) + .build(); + } + + // may be this can be moved to Annotation itself or AnnotationsUtils + /** + * Converts Annotations to Map of Strings. + * + * @param annotations {@link Annotations} + * @return Map of annotation key and values + */ + public static Map asMap(Annotations annotations) { + if (annotations instanceof DefaultAnnotations) { + return ((DefaultAnnotations) annotations).asMap(); + } + Map map = new HashMap<>(); + annotations.keys() + .forEach(k -> map.put(k, annotations.value(k))); + + return map; + } + + // may be this can be moved to Annotation itself or AnnotationsUtils + /** + * Converts Map of Strings to {@link SparseAnnotations}. + * + * @param annotations Map of annotation key and values + * @return {@link SparseAnnotations} + */ + public static SparseAnnotations asAnnotations(Map annotations) { + DefaultAnnotations.Builder builder = DefaultAnnotations.builder(); + annotations.entrySet().forEach(e -> { + if (e.getValue() != null) { + builder.set(e.getKey(), e.getValue()); + } else { + builder.remove(e.getKey()); + } + }); + return builder.build(); + } + + // Utility class not intended for instantiation. + private GrpcDeviceUtils() {} +} diff --git a/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceContext.java b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceContext.java new file mode 100644 index 00000000..b419a346 --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceContext.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.grpc; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.concurrent.ConcurrentHashMap; + +import org.onosproject.incubator.rpc.RemoteServiceContext; +import org.onosproject.net.device.DeviceProviderRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +import io.grpc.ManagedChannel; + +// gRPC Client side +// Probably there should be plug-in mechanism in the future. +/** + * RemoteServiceContext based on gRPC. + * + *

+ * Currently it supports {@link DeviceProviderRegistry}. + */ +public class GrpcRemoteServiceContext implements RemoteServiceContext { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final Map, Object> services = new ConcurrentHashMap<>(); + + private final ManagedChannel channel; + + public GrpcRemoteServiceContext(ManagedChannel channel) { + this.channel = checkNotNull(channel); + services.put(DeviceProviderRegistry.class, new DeviceProviderRegistryClientProxy(channel)); + } + + + @Override + public T get(Class serviceClass) { + @SuppressWarnings("unchecked") + T service = (T) services.get(serviceClass); + if (service != null) { + return service; + } + log.error("{} not supported", serviceClass); + throw new NoSuchElementException(serviceClass.getTypeName() + " not supported"); + } + + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("services", services.keySet()) + .add("channel", channel.authority()) + .toString(); + } + +} diff --git a/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceProvider.java b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceProvider.java new file mode 100644 index 00000000..74962187 --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceProvider.java @@ -0,0 +1,119 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.grpc; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.net.URI; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onosproject.incubator.rpc.RemoteServiceContext; +import org.onosproject.incubator.rpc.RemoteServiceContextProvider; +import org.onosproject.incubator.rpc.RemoteServiceContextProviderService; +import org.onosproject.incubator.rpc.RemoteServiceProviderRegistry; +import org.onosproject.net.provider.ProviderId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.grpc.ManagedChannel; +import io.grpc.netty.NegotiationType; +import io.grpc.netty.NettyChannelBuilder; + + +// gRPC Client side +/** + * RemoteServiceContextProvider based on gRPC. + */ +@Component(immediate = true) +public class GrpcRemoteServiceProvider implements RemoteServiceContextProvider { + + public static final String GRPC_SCHEME = "grpc"; + + public static final String RPC_PROVIDER_NAME = "org.onosproject.rpc.provider.grpc"; + + private static final ProviderId PID = new ProviderId(GRPC_SCHEME, RPC_PROVIDER_NAME); + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RemoteServiceProviderRegistry rpcRegistry; + + private Map channels = new ConcurrentHashMap<>(); + + private RemoteServiceContextProviderService providerService; + + + @Activate + protected void activate() { + providerService = rpcRegistry.register(this); + + // FIXME remove me. test code to see if gRPC loads in karaf + //getChannel(URI.create("grpc://localhost:8080")); + + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + rpcRegistry.unregister(this); + + // shutdown all channels + channels.values().stream() + .forEach(ManagedChannel::shutdown); + // Should we wait for shutdown? How? + channels.clear(); + log.info("Stopped"); + } + + @Override + public ProviderId id() { + return PID; + } + + @Override + public RemoteServiceContext get(URI uri) { + // Create gRPC client + return new GrpcRemoteServiceContext(getChannel(uri)); + } + + private ManagedChannel getChannel(URI uri) { + checkArgument(Objects.equals(GRPC_SCHEME, uri.getScheme()), + "Invalid URI scheme: %s", uri.getScheme()); + + return channels.compute(uri, (u, ch) -> { + if (ch != null && !ch.isShutdown()) { + return ch; + } else { + return createChannel(u); + } + }); + } + + private ManagedChannel createChannel(URI uri) { + log.debug("Creating channel for {}", uri); + return NettyChannelBuilder.forAddress(uri.getHost(), uri.getPort()) + .negotiationType(NegotiationType.PLAINTEXT) + .build(); + } + +} diff --git a/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceServer.java b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceServer.java new file mode 100644 index 00000000..4f43fa65 --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceServer.java @@ -0,0 +1,385 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.grpc; + +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.stream.Collectors.toList; +import static org.onosproject.incubator.rpc.grpc.GrpcDeviceUtils.translate; +import static org.onosproject.net.DeviceId.deviceId; + +import java.io.IOException; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Modified; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onosproject.grpc.Device.DeviceConnected; +import org.onosproject.grpc.Device.DeviceDisconnected; +import org.onosproject.grpc.Device.DeviceProviderMsg; +import org.onosproject.grpc.Device.DeviceProviderServiceMsg; +import org.onosproject.grpc.Device.IsReachableResponse; +import org.onosproject.grpc.Device.PortStatusChanged; +import org.onosproject.grpc.Device.ReceivedRoleReply; +import org.onosproject.grpc.Device.RegisterProvider; +import org.onosproject.grpc.Device.UpdatePortStatistics; +import org.onosproject.grpc.Device.UpdatePorts; +import org.onosproject.grpc.DeviceProviderRegistryRpcGrpc; +import org.onosproject.grpc.DeviceProviderRegistryRpcGrpc.DeviceProviderRegistryRpc; +import org.onosproject.net.DeviceId; +import org.onosproject.net.MastershipRole; +import org.onosproject.net.device.DeviceProvider; +import org.onosproject.net.device.DeviceProviderRegistry; +import org.onosproject.net.device.DeviceProviderService; +import org.onosproject.net.provider.ProviderId; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.collect.Sets; + +import io.grpc.Server; +import io.grpc.netty.NettyServerBuilder; +import io.grpc.stub.StreamObserver; + +// gRPC Server on Metro-side +// Translates request received on RPC channel, and calls corresponding Service on +// Metro-ONOS cluster. +/** + * Server side implementation of gRPC based RemoteService. + */ +@Component(immediate = true) +public class GrpcRemoteServiceServer { + + private static final String RPC_PROVIDER_NAME = "org.onosproject.rpc.provider.grpc"; + + // TODO pick a number + public static final int DEFAULT_LISTEN_PORT = 11984; + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceProviderRegistry deviceProviderRegistry; + + + @Property(name = "listenPort", intValue = DEFAULT_LISTEN_PORT, + label = "Port to listen on") + protected int listenPort = DEFAULT_LISTEN_PORT; + + private Server server; + private final Set registeredProviders = Sets.newConcurrentHashSet(); + + @Activate + protected void activate(ComponentContext context) throws IOException { + modified(context); + + log.debug("Server starting on {}", listenPort); + try { + server = NettyServerBuilder.forPort(listenPort) + .addService(DeviceProviderRegistryRpcGrpc.bindService(new DeviceProviderRegistryServerProxy())) + .build().start(); + } catch (IOException e) { + log.error("Failed to start gRPC server", e); + throw e; + } + + log.info("Started on {}", listenPort); + } + + @Deactivate + protected void deactivate() { + + registeredProviders.stream() + .forEach(deviceProviderRegistry::unregister); + + server.shutdown(); + // Should we wait for shutdown? + log.info("Stopped"); + } + + @Modified + public void modified(ComponentContext context) { + // TODO support dynamic reconfiguration and restarting server? + } + + // RPC Server-side code + // RPC session Factory + /** + * Relays DeviceProviderRegistry calls from RPC client. + */ + class DeviceProviderRegistryServerProxy implements DeviceProviderRegistryRpc { + + @Override + public StreamObserver register(StreamObserver toDeviceProvider) { + log.trace("DeviceProviderRegistryServerProxy#register called!"); + + DeviceProviderServerProxy provider = new DeviceProviderServerProxy(toDeviceProvider); + + return new DeviceProviderServiceServerProxy(provider, toDeviceProvider); + } + } + + // Lower -> Upper Controller message + // RPC Server-side code + // RPC session handler + private final class DeviceProviderServiceServerProxy + implements StreamObserver { + + // intentionally shadowing + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final DeviceProviderServerProxy pairedProvider; + private final StreamObserver toDeviceProvider; + + private final Cache> outstandingIsReachable; + + // wrapped providerService + private DeviceProviderService deviceProviderService; + + + DeviceProviderServiceServerProxy(DeviceProviderServerProxy provider, + StreamObserver toDeviceProvider) { + this.pairedProvider = provider; + this.toDeviceProvider = toDeviceProvider; + outstandingIsReachable = CacheBuilder.newBuilder() + .expireAfterWrite(1, TimeUnit.MINUTES) + .build(); + + // pair RPC session in other direction + provider.pair(this); + } + + @Override + public void onNext(DeviceProviderServiceMsg msg) { + try { + log.trace("DeviceProviderServiceServerProxy received: {}", msg); + onMethod(msg); + } catch (Exception e) { + log.error("Exception thrown handling {}", msg, e); + onError(e); + throw e; + } + } + + /** + * Translates received RPC message to {@link DeviceProviderService} method calls. + * @param msg DeviceProviderService message + */ + private void onMethod(DeviceProviderServiceMsg msg) { + switch (msg.getMethodCase()) { + case REGISTER_PROVIDER: + RegisterProvider registerProvider = msg.getRegisterProvider(); + // TODO Do we care about provider name? + pairedProvider.setProviderId(new ProviderId(registerProvider.getProviderScheme(), RPC_PROVIDER_NAME)); + registeredProviders.add(pairedProvider); + deviceProviderService = deviceProviderRegistry.register(pairedProvider); + break; + + case DEVICE_CONNECTED: + DeviceConnected deviceConnected = msg.getDeviceConnected(); + deviceProviderService.deviceConnected(deviceId(deviceConnected.getDeviceId()), + translate(deviceConnected.getDeviceDescription())); + break; + case DEVICE_DISCONNECTED: + DeviceDisconnected deviceDisconnected = msg.getDeviceDisconnected(); + deviceProviderService.deviceDisconnected(deviceId(deviceDisconnected.getDeviceId())); + break; + case UPDATE_PORTS: + UpdatePorts updatePorts = msg.getUpdatePorts(); + deviceProviderService.updatePorts(deviceId(updatePorts.getDeviceId()), + updatePorts.getPortDescriptionsList() + .stream() + .map(GrpcDeviceUtils::translate) + .collect(toList())); + break; + case PORT_STATUS_CHANGED: + PortStatusChanged portStatusChanged = msg.getPortStatusChanged(); + deviceProviderService.portStatusChanged(deviceId(portStatusChanged.getDeviceId()), + translate(portStatusChanged.getPortDescription())); + break; + case RECEIVED_ROLE_REPLY: + ReceivedRoleReply receivedRoleReply = msg.getReceivedRoleReply(); + deviceProviderService.receivedRoleReply(deviceId(receivedRoleReply.getDeviceId()), + translate(receivedRoleReply.getRequested()), + translate(receivedRoleReply.getResponse())); + break; + case UPDATE_PORT_STATISTICS: + UpdatePortStatistics updatePortStatistics = msg.getUpdatePortStatistics(); + deviceProviderService.updatePortStatistics(deviceId(updatePortStatistics.getDeviceId()), + updatePortStatistics.getPortStatisticsList() + .stream() + .map(GrpcDeviceUtils::translate) + .collect(toList())); + break; + + // return value of DeviceProvider#isReachable + case IS_REACHABLE_RESPONSE: + IsReachableResponse isReachableResponse = msg.getIsReachableResponse(); + int xid = isReachableResponse.getXid(); + boolean isReachable = isReachableResponse.getIsReachable(); + CompletableFuture result = outstandingIsReachable.asMap().remove(xid); + if (result != null) { + result.complete(isReachable); + } + break; + + case METHOD_NOT_SET: + default: + log.warn("Unexpected message received {}", msg); + break; + } + } + + @Override + public void onCompleted() { + log.info("DeviceProviderServiceServerProxy completed"); + deviceProviderRegistry.unregister(pairedProvider); + registeredProviders.remove(pairedProvider); + toDeviceProvider.onCompleted(); + } + + @Override + public void onError(Throwable e) { + log.error("DeviceProviderServiceServerProxy#onError", e); + deviceProviderRegistry.unregister(pairedProvider); + registeredProviders.remove(pairedProvider); + // TODO What is the proper clean up for bi-di stream on error? + // sample suggests no-op + toDeviceProvider.onError(e); + } + + + /** + * Registers Future for {@link DeviceProvider#isReachable(DeviceId)} return value. + * @param xid IsReachable call ID. + * @param reply Future to + */ + void register(int xid, CompletableFuture reply) { + outstandingIsReachable.put(xid, reply); + } + + } + + // Upper -> Lower Controller message + /** + * Relay DeviceProvider calls to RPC client. + */ + private final class DeviceProviderServerProxy + implements DeviceProvider { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + // xid for isReachable calls + private final AtomicInteger xidPool = new AtomicInteger(); + private final StreamObserver toDeviceProvider; + + private DeviceProviderServiceServerProxy deviceProviderServiceProxy = null; + private ProviderId providerId; + + DeviceProviderServerProxy(StreamObserver toDeviceProvider) { + this.toDeviceProvider = toDeviceProvider; + } + + void setProviderId(ProviderId pid) { + this.providerId = pid; + } + + /** + * Registers RPC stream in other direction. + * @param deviceProviderServiceProxy {@link DeviceProviderServiceServerProxy} + */ + void pair(DeviceProviderServiceServerProxy deviceProviderServiceProxy) { + this.deviceProviderServiceProxy = deviceProviderServiceProxy; + } + + @Override + public void triggerProbe(DeviceId deviceId) { + log.trace("triggerProbe({})", deviceId); + DeviceProviderMsg.Builder msgBuilder = DeviceProviderMsg.newBuilder(); + msgBuilder.setTriggerProbe(msgBuilder.getTriggerProbeBuilder() + .setDeviceId(deviceId.toString()) + .build()); + DeviceProviderMsg triggerProbeMsg = msgBuilder.build(); + toDeviceProvider.onNext(triggerProbeMsg); + // TODO Catch Exceptions and call onError() + } + + @Override + public void roleChanged(DeviceId deviceId, MastershipRole newRole) { + log.trace("roleChanged({}, {})", deviceId, newRole); + DeviceProviderMsg.Builder msgBuilder = DeviceProviderMsg.newBuilder(); + msgBuilder.setRoleChanged(msgBuilder.getRoleChangedBuilder() + .setDeviceId(deviceId.toString()) + .setNewRole(translate(newRole)) + .build()); + toDeviceProvider.onNext(msgBuilder.build()); + // TODO Catch Exceptions and call onError() + } + + @Override + public boolean isReachable(DeviceId deviceId) { + log.trace("isReachable({})", deviceId); + CompletableFuture result = new CompletableFuture<>(); + final int xid = xidPool.incrementAndGet(); + + DeviceProviderMsg.Builder msgBuilder = DeviceProviderMsg.newBuilder(); + msgBuilder.setIsReachableRequest(msgBuilder.getIsReachableRequestBuilder() + .setXid(xid) + .setDeviceId(deviceId.toString()) + .build()); + + // Associate xid and register above future some where + // in DeviceProviderService channel to receive reply + if (deviceProviderServiceProxy != null) { + deviceProviderServiceProxy.register(xid, result); + } + + // send message down RPC + toDeviceProvider.onNext(msgBuilder.build()); + + // wait for reply + try { + return result.get(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + log.debug("isReachable({}) was Interrupted", deviceId, e); + Thread.currentThread().interrupt(); + } catch (TimeoutException e) { + log.warn("isReachable({}) Timed out", deviceId, e); + } catch (ExecutionException e) { + log.error("isReachable({}) Execution failed", deviceId, e); + // close session? + } + return false; + // TODO Catch Exceptions and call onError() + } + + @Override + public ProviderId id() { + return checkNotNull(providerId, "not initialized yet"); + } + + } +} diff --git a/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/package-info.java b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/package-info.java new file mode 100644 index 00000000..d667ea77 --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * gRPC based RemoteServiceProvider implementation. + */ +package org.onosproject.incubator.rpc.grpc; diff --git a/framework/src/onos/incubator/rpc-grpc/src/main/proto/Device.proto b/framework/src/onos/incubator/rpc-grpc/src/main/proto/Device.proto new file mode 100644 index 00000000..aae46d96 --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/src/main/proto/Device.proto @@ -0,0 +1,131 @@ +syntax = "proto3"; +option java_package = "org.onosproject.grpc"; + +import "Port.proto"; +package Device; + +enum DeviceType { + OTHER = 0; + SWITCH = 1; + ROUTER = 2; + ROADM = 3; + OTN = 4; + ROADM_OTN = 5; + FIREWALL = 6; + BALANCER = 7; + IPS = 8; + IDS = 9; + CONTROLLER = 10; + VIRTUAL = 11; + FIBER_SWITCH = 12; + MICROWAVE = 13; +} + +message DeviceDescription { + string device_Uri = 1; + DeviceType type = 2; + string manufacturer = 3; + string hw_version = 4; + string sw_version = 5; + string serial_number = 6; + string chassis_id = 7; + map annotations = 8; +} + +enum MastershipRole { + NONE = 0; + MASTER = 1; + STANDBY = 2; +} + +message DeviceConnected { + // DeviceID as String DeviceId#toString + string device_id = 1; + DeviceDescription device_description = 2; +} + +message DeviceDisconnected { + // DeviceID as String DeviceId#toString + string device_id = 1; +} + +message UpdatePorts { + // DeviceID as String DeviceId#toString + string device_id = 1; + repeated Port.PortDescription port_descriptions= 2; +} + +message PortStatusChanged { + // DeviceID as String DeviceId#toString + string device_id = 1; + Port.PortDescription port_description= 2; +} + +message ReceivedRoleReply { + // DeviceID as String DeviceId#toString + string device_id = 1; + MastershipRole requested = 2; + MastershipRole response = 3; +} + +message UpdatePortStatistics { + // DeviceID as String DeviceId#toString + string device_id = 1; + repeated Port.PortStatistics port_statistics = 2; +} + +message RegisterProvider { + // DeviceProvider's ProviderId scheme + string provider_scheme = 1; +} + +message DeviceProviderServiceMsg { + oneof method { + DeviceConnected device_connected= 1; + DeviceDisconnected device_disconnected = 2; + UpdatePorts update_ports= 3; + PortStatusChanged port_status_changed = 4; + ReceivedRoleReply received_role_reply = 5; + UpdatePortStatistics update_port_statistics = 6; + + // This message is for return value of DeviceProvider#isReachable + IsReachableResponse is_reachable_response = 7; + + // This MUST be the 1st message over the stream + RegisterProvider register_provider = 8; + } +} + +message TriggerProbe { + // DeviceID as String DeviceId#toString + string device_id = 1; +} + +message RoleChanged { + // DeviceID as String DeviceId#toString + string device_id = 1; + MastershipRole new_role = 2; +} + +message IsReachableRequest { + int32 xid = 1; + // DeviceID as String DeviceId#toString + string device_id = 2; +} + +message IsReachableResponse { + int32 xid = 1; + bool is_reachable = 2; +} + +message DeviceProviderMsg { + oneof method { + TriggerProbe trigger_probe = 1; + RoleChanged role_changed = 2; + IsReachableRequest is_reachable_request= 3; + } +} + +service DeviceProviderRegistryRpc { + rpc Register(stream DeviceProviderServiceMsg) returns (stream DeviceProviderMsg); +} diff --git a/framework/src/onos/incubator/rpc-grpc/src/main/proto/Port.proto b/framework/src/onos/incubator/rpc-grpc/src/main/proto/Port.proto new file mode 100644 index 00000000..f32193cc --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/src/main/proto/Port.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; +option java_package = "org.onosproject.grpc"; + +package Port; + +enum PortType { + // Signifies copper-based connectivity. + COPPER = 0; + // Signifies optical fiber-based connectivity. + FIBER = 1; + // Signifies optical fiber-based packet port. + PACKET = 2; + // Signifies optical fiber-based optical tributary port (called T-port). + //The signal from the client side will be formed into a ITU G.709 (OTN) frame. + ODUCLT = 3; + // Signifies optical fiber-based Line-side port (called L-port). + OCH = 4; + // Signifies optical fiber-based WDM port (called W-port). + //Optical Multiplexing Section (See ITU G.709). + OMS = 5; + // Signifies virtual port. + VIRTUAL = 6; +} + +// TODO What are we going to do with more specific PortDescription ... +message PortDescription { + // PortNumber as String PortNumber#toString + string port_number = 1; + bool is_enabled = 2; + PortType type = 3; + int64 port_speed = 4; + map annotations = 8; +} + +message PortStatistics { + int32 port = 1; + int64 packets_received = 2; + int64 packets_sent = 3; + // TODO add all other fields +} diff --git a/framework/src/onos/incubator/rpc-grpc/src/test/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceTest.java b/framework/src/onos/incubator/rpc-grpc/src/test/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceTest.java new file mode 100644 index 00000000..69db5714 --- /dev/null +++ b/framework/src/onos/incubator/rpc-grpc/src/test/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceTest.java @@ -0,0 +1,398 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.grpc; + +import static org.junit.Assert.*; +import static org.onosproject.net.DeviceId.deviceId; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.URI; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang3.RandomUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.packet.ChassisId; +import org.onosproject.incubator.rpc.RemoteServiceContext; +import org.onosproject.incubator.rpc.RemoteServiceContextProvider; +import org.onosproject.incubator.rpc.RemoteServiceContextProviderService; +import org.onosproject.incubator.rpc.RemoteServiceProviderRegistry; +import org.onosproject.net.DefaultAnnotations; +import org.onosproject.net.Device.Type; +import org.onosproject.net.DeviceId; +import org.onosproject.net.MastershipRole; +import org.onosproject.net.PortNumber; +import org.onosproject.net.SparseAnnotations; +import org.onosproject.net.device.DefaultDeviceDescription; +import org.onosproject.net.device.DefaultPortDescription; +import org.onosproject.net.device.DeviceDescription; +import org.onosproject.net.device.DeviceProvider; +import org.onosproject.net.device.DeviceProviderRegistry; +import org.onosproject.net.device.DeviceProviderService; +import org.onosproject.net.device.PortDescription; +import org.onosproject.net.device.PortStatistics; +import org.onosproject.net.provider.AbstractProviderRegistry; +import org.onosproject.net.provider.AbstractProviderService; +import org.onosproject.net.provider.ProviderId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ImmutableList; + +/** + * Set of tests of the gRPC RemoteService components. + */ +public class GrpcRemoteServiceTest { + + private static final DeviceId DEVICE_ID = deviceId("dev:000001"); + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private static final ProviderId PID = new ProviderId("test", "com.exmaple.test"); + + private static final URI DURI = URI.create("dev:000001"); + + private static final String MFR = "mfr"; + + private static final String HW = "hw"; + + private static final String SW = "sw"; + + private static final String SN = "serial"; + + private static final ChassisId CHASSIS = new ChassisId(42); + + private static final SparseAnnotations ANON = DefaultAnnotations.builder() + .set("foo", "var") + .build(); + + private static final PortNumber PORT = PortNumber.portNumber(99); + + private static final DeviceDescription DDESC + = new DefaultDeviceDescription(DURI, Type.SWITCH, MFR, HW, SW, SN, + CHASSIS, ANON); + + private GrpcRemoteServiceServer server; + private GrpcRemoteServiceProvider client; + + private DeviceProvider svSideDeviceProvider; + + private MTestDeviceProviderService svDeviceProviderService; + + private CountDownLatch serverReady; + + private URI uri; + + public static int pickListenPort() { + try { + // pick unused port + ServerSocket socket = new ServerSocket(0); + int port = socket.getLocalPort(); + socket.close(); + return port; + } catch (IOException e) { + // something went wrong, try picking randomly + return RandomUtils.nextInt(49152, 0xFFFF + 1); + } + } + + @Before + public void setUp() throws Exception { + serverReady = new CountDownLatch(1); + server = new GrpcRemoteServiceServer(); + server.deviceProviderRegistry = new MTestDeviceProviderRegistry(); + // todo: pass proper ComponentContext + server.listenPort = pickListenPort(); + uri = URI.create("grpc://localhost:" + server.listenPort); + server.activate(null); + + client = new GrpcRemoteServiceProvider(); + client.rpcRegistry = new NoOpRemoteServiceProviderRegistry(); + client.activate(); + } + + @After + public void tearDown() { + client.deactivate(); + server.deactivate(); + } + + private static void assertEqualsButNotSame(Object expected, Object actual) { + assertEquals(expected, actual); + assertNotSame("Cannot be same instance if it properly went through gRPC", + expected, actual); + } + + @Test + public void basics() throws InterruptedException { + RemoteServiceContext remoteServiceContext = client.get(uri); + assertNotNull(remoteServiceContext); + + DeviceProviderRegistry deviceProviderRegistry = remoteServiceContext.get(DeviceProviderRegistry.class); + assertNotNull(deviceProviderRegistry); + + CTestDeviceProvider clDeviceProvider = new CTestDeviceProvider(); + DeviceProviderService clDeviceProviderService = deviceProviderRegistry.register(clDeviceProvider); + + assertTrue(serverReady.await(10, TimeUnit.SECONDS)); + + // client to server communication + clDeviceProviderService.deviceConnected(DEVICE_ID, DDESC); + assertTrue(svDeviceProviderService.deviceConnected.await(10, TimeUnit.SECONDS)); + assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.deviceConnectedDid); + assertEqualsButNotSame(DDESC, svDeviceProviderService.deviceConnectedDesc); + + PortDescription portDescription = new DefaultPortDescription(PORT, true, ANON); + List portDescriptions = ImmutableList.of(portDescription); + clDeviceProviderService.updatePorts(DEVICE_ID, portDescriptions); + assertTrue(svDeviceProviderService.updatePorts.await(10, TimeUnit.SECONDS)); + assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.updatePortsDid); + assertEqualsButNotSame(portDescriptions, svDeviceProviderService.updatePortsDescs); + + MastershipRole cRole = MastershipRole.MASTER; + MastershipRole dRole = MastershipRole.STANDBY; + clDeviceProviderService.receivedRoleReply(DEVICE_ID, cRole, dRole); + assertTrue(svDeviceProviderService.receivedRoleReply.await(10, TimeUnit.SECONDS)); + assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.receivedRoleReplyDid); + assertEquals(cRole, svDeviceProviderService.receivedRoleReplyRequested); + assertEquals(dRole, svDeviceProviderService.receivedRoleReplyResponse); + + clDeviceProviderService.portStatusChanged(DEVICE_ID, portDescription); + assertTrue(svDeviceProviderService.portStatusChanged.await(10, TimeUnit.SECONDS)); + assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.portStatusChangedDid); + assertEqualsButNotSame(portDescription, svDeviceProviderService.portStatusChangedDesc); + + Collection portStatistics = Collections.emptyList(); + clDeviceProviderService.updatePortStatistics(DEVICE_ID, portStatistics); + assertTrue(svDeviceProviderService.updatePortStatistics.await(10, TimeUnit.SECONDS)); + assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.updatePortStatisticsDid); + assertEqualsButNotSame(portStatistics, svDeviceProviderService.updatePortStatisticsStats); + + clDeviceProviderService.deviceDisconnected(DEVICE_ID); + assertTrue(svDeviceProviderService.deviceDisconnected.await(10, TimeUnit.SECONDS)); + assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.deviceDisconnectedDid); + + + + // server to client communication + svSideDeviceProvider.triggerProbe(DEVICE_ID); + assertTrue(clDeviceProvider.triggerProbe.await(10, TimeUnit.SECONDS)); + assertEquals(DEVICE_ID, clDeviceProvider.triggerProbeDid); + assertNotSame("Cannot be same instance if it properly went through gRPC", + DEVICE_ID, clDeviceProvider.triggerProbeDid); + + svSideDeviceProvider.roleChanged(DEVICE_ID, MastershipRole.STANDBY); + assertTrue(clDeviceProvider.roleChanged.await(10, TimeUnit.SECONDS)); + assertEquals(DEVICE_ID, clDeviceProvider.roleChangedDid); + assertNotSame("Cannot be same instance if it properly went through gRPC", + DEVICE_ID, clDeviceProvider.roleChangedDid); + assertEquals(MastershipRole.STANDBY, clDeviceProvider.roleChangedNewRole); + + clDeviceProvider.isReachableReply = false; + assertEquals(clDeviceProvider.isReachableReply, + svSideDeviceProvider.isReachable(DEVICE_ID)); + assertTrue(clDeviceProvider.isReachable.await(10, TimeUnit.SECONDS)); + assertEquals(DEVICE_ID, clDeviceProvider.isReachableDid); + assertNotSame("Cannot be same instance if it properly went through gRPC", + DEVICE_ID, clDeviceProvider.isReachableDid); + } + + /** + * Device Provider on CO side. + */ + public class CTestDeviceProvider implements DeviceProvider { + + final CountDownLatch triggerProbe = new CountDownLatch(1); + DeviceId triggerProbeDid; + + final CountDownLatch roleChanged = new CountDownLatch(1); + DeviceId roleChangedDid; + MastershipRole roleChangedNewRole; + + final CountDownLatch isReachable = new CountDownLatch(1); + DeviceId isReachableDid; + boolean isReachableReply = false; + + @Override + public ProviderId id() { + return PID; + } + + @Override + public void triggerProbe(DeviceId deviceId) { + log.info("triggerProbe({}) on Client called", deviceId); + triggerProbeDid = deviceId; + triggerProbe.countDown(); + } + + @Override + public void roleChanged(DeviceId deviceId, MastershipRole newRole) { + log.info("roleChanged({},{}) on Client called", deviceId, newRole); + roleChangedDid = deviceId; + roleChangedNewRole = newRole; + roleChanged.countDown(); + } + + @Override + public boolean isReachable(DeviceId deviceId) { + log.info("isReachable({}) on Client called", deviceId); + isReachableDid = deviceId; + isReachable.countDown(); + return isReachableReply; + } + + } + + class NoOpRemoteServiceProviderRegistry + implements RemoteServiceProviderRegistry { + + @Override + public RemoteServiceContextProviderService register(RemoteServiceContextProvider provider) { + return new RemoteServiceContextProviderService() { + + @Override + public RemoteServiceContextProvider provider() { + return provider; + } + }; + } + + @Override + public void unregister(RemoteServiceContextProvider provider) { + } + + @Override + public Set getProviders() { + return Collections.emptySet(); + } + } + + /** + * DeviceProvider on Metro side. + */ + public class MTestDeviceProviderRegistry + extends AbstractProviderRegistry + implements DeviceProviderRegistry { + + @Override + protected DeviceProviderService createProviderService(DeviceProvider provider) { + log.info("createProviderService({})", provider); + svSideDeviceProvider = provider; + svDeviceProviderService = new MTestDeviceProviderService(provider); + serverReady.countDown(); + return svDeviceProviderService; + } + + } + + private final class MTestDeviceProviderService + extends AbstractProviderService + implements DeviceProviderService { + + public MTestDeviceProviderService(DeviceProvider provider) { + super(provider); + } + + + final CountDownLatch deviceConnected = new CountDownLatch(1); + DeviceId deviceConnectedDid; + DeviceDescription deviceConnectedDesc; + + @Override + public void deviceConnected(DeviceId deviceId, + DeviceDescription deviceDescription) { + log.info("deviceConnected({}, {}) on Server called", deviceId, deviceDescription); + deviceConnectedDid = deviceId; + deviceConnectedDesc = deviceDescription; + deviceConnected.countDown(); + } + + + final CountDownLatch updatePorts = new CountDownLatch(1); + DeviceId updatePortsDid; + List updatePortsDescs; + + @Override + public void updatePorts(DeviceId deviceId, + List portDescriptions) { + log.info("updatePorts({}, {}) on Server called", deviceId, portDescriptions); + updatePortsDid = deviceId; + updatePortsDescs = portDescriptions; + updatePorts.countDown(); + } + + final CountDownLatch receivedRoleReply = new CountDownLatch(1); + DeviceId receivedRoleReplyDid; + MastershipRole receivedRoleReplyRequested; + MastershipRole receivedRoleReplyResponse; + + @Override + public void receivedRoleReply(DeviceId deviceId, MastershipRole requested, + MastershipRole response) { + log.info("receivedRoleReply({}, {}, {}) on Server called", deviceId, requested, response); + receivedRoleReplyDid = deviceId; + receivedRoleReplyRequested = requested; + receivedRoleReplyResponse = response; + receivedRoleReply.countDown(); + } + + final CountDownLatch portStatusChanged = new CountDownLatch(1); + DeviceId portStatusChangedDid; + PortDescription portStatusChangedDesc; + + + @Override + public void portStatusChanged(DeviceId deviceId, + PortDescription portDescription) { + log.info("portStatusChanged({}, {}) on Server called", deviceId, portDescription); + portStatusChangedDid = deviceId; + portStatusChangedDesc = portDescription; + portStatusChanged.countDown(); + } + + final CountDownLatch updatePortStatistics = new CountDownLatch(1); + DeviceId updatePortStatisticsDid; + Collection updatePortStatisticsStats; + + + @Override + public void updatePortStatistics(DeviceId deviceId, + Collection portStatistics) { + log.info("updatePortStatistics({}, {}) on Server called", deviceId, portStatistics); + updatePortStatisticsDid = deviceId; + updatePortStatisticsStats = portStatistics; + updatePortStatistics.countDown(); + } + + final CountDownLatch deviceDisconnected = new CountDownLatch(1); + DeviceId deviceDisconnectedDid; + + @Override + public void deviceDisconnected(DeviceId deviceId) { + log.info("deviceDisconnected({}) on Server called", deviceId); + deviceDisconnectedDid = deviceId; + deviceDisconnected.countDown(); + } + } + +} diff --git a/framework/src/onos/incubator/rpc/pom.xml b/framework/src/onos/incubator/rpc/pom.xml new file mode 100644 index 00000000..8619f92e --- /dev/null +++ b/framework/src/onos/incubator/rpc/pom.xml @@ -0,0 +1,135 @@ + + + + 4.0.0 + + onos-incubator + org.onosproject + 1.4.0-SNAPSHOT + + + onos-incubator-rpc + bundle + + ONOS inter-cluster RPC service + http://onosproject.org + + + org.onosproject.incubator.rpc + + + + + org.onosproject + onos-api + + + + org.onosproject + onlab-osgi + + + + junit + junit + test + + + + org.onosproject + onos-api + test + tests + + + + org.onosproject + onos-incubator-api + + + + org.apache.felix + org.apache.felix.scr.annotations + provided + + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.felix + maven-scr-plugin + + + generate-scr-srcdescriptor + + scr + + + + + + bundle + war + + + + + org.onosproject + onos-maven-plugin + + + cfg + generate-resources + + cfg + + + + swagger + generate-sources + + swagger + + + + app + package + + app + + + + + + + + diff --git a/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/AbstractProviderRegistry.java b/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/AbstractProviderRegistry.java new file mode 100644 index 00000000..2a8dda32 --- /dev/null +++ b/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/AbstractProviderRegistry.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.impl; + +import java.util.Map; +import java.util.Set; + +import org.onosproject.incubator.rpc.RemoteServiceContextProvider; +import org.onosproject.incubator.rpc.RemoteServiceContextProviderService; +import org.onosproject.incubator.rpc.RemoteServiceProviderRegistry; +import org.onosproject.net.provider.ProviderId; + +import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; + +// Probably should change name or add missing feature (provider from scheme) to +// org.onosproject.net.provider.AbstractProviderRegistry +@Beta +abstract class AbstractProviderRegistry + implements RemoteServiceProviderRegistry { + + + private final Map pidToProvider = Maps.newConcurrentMap(); + private final Map schemeToProvider = Maps.newConcurrentMap(); + + public AbstractProviderRegistry() { + super(); + } + + protected abstract RemoteServiceContextProviderService createProviderService(RemoteServiceContextProvider provider); + + @Override + public synchronized RemoteServiceContextProviderService register(RemoteServiceContextProvider provider) { + // TODO check if it already exists + pidToProvider.put(provider.id(), provider); + schemeToProvider.put(provider.id().scheme(), provider); + return createProviderService(provider); + } + + @Override + public synchronized void unregister(RemoteServiceContextProvider provider) { + pidToProvider.remove(provider.id(), provider); + schemeToProvider.remove(provider.id().scheme(), provider); + } + + @Override + public Set getProviders() { + return ImmutableSet.copyOf(pidToProvider.keySet()); + } + + protected RemoteServiceContextProvider getProvider(ProviderId pid) { + return pidToProvider.get(pid); + } + + protected RemoteServiceContextProvider getProvider(String scheme) { + return schemeToProvider.get(scheme); + } + +} diff --git a/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/LocalRemoteServiceProvider.java b/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/LocalRemoteServiceProvider.java new file mode 100644 index 00000000..d38248ab --- /dev/null +++ b/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/LocalRemoteServiceProvider.java @@ -0,0 +1,124 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.impl; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.net.URI; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; +import org.onosproject.incubator.rpc.RemoteServiceContext; +import org.onosproject.incubator.rpc.RemoteServiceContextProvider; +import org.onosproject.incubator.rpc.RemoteServiceContextProviderService; +import org.onosproject.incubator.rpc.RemoteServiceProviderRegistry; +import org.onosproject.net.provider.ProviderId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.annotations.Beta; + +/** + * Sample implementation of RemoteServiceContextProvider. + * + * Scheme: "local", calling corresponding local service on request. + * Only expected for testing until real RPC implementation is ready. + * + * Note: This is expected to be removed or separated out as separate bundle + * once other RPC implementaion became available. + */ +@Beta +@Component(immediate = true) +public class LocalRemoteServiceProvider implements RemoteServiceContextProvider { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private RemoteServiceContext theOne = new LocalServiceContext(); + + private static final ProviderId PID = new ProviderId("local", "org.onosproject.rpc.provider.local"); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RemoteServiceProviderRegistry rpcRegistry; + + private final Map, Object> services = new ConcurrentHashMap<>(); + + private RemoteServiceContextProviderService providerService; + + @Activate + protected void activate() { + + services.put(SomeOtherService.class, new SomeOtherServiceImpl()); + + providerService = rpcRegistry.register(this); + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + rpcRegistry.unregister(this); + log.info("Stopped"); + } + + @Override + public ProviderId id() { + return PID; + } + + @Override + public RemoteServiceContext get(URI uri) { + checkArgument(Objects.equals(uri.getScheme(), "local")); + return theOne; + } + + private final class LocalServiceContext implements RemoteServiceContext { + + private final ServiceDirectory directory = new DefaultServiceDirectory(); + + @Override + public T get(Class serviceClass) { + @SuppressWarnings("unchecked") + T service = (T) services.get(serviceClass); + if (service != null) { + return service; + } + // look up OSGi services on this host. + // provided to unblock development depending on RPC. + return directory.get(serviceClass); + } + } + + // Service provided by RPC can be non-OSGi Service + public static interface SomeOtherService { + String hello(); + } + + public static class SomeOtherServiceImpl implements SomeOtherService { + + @Override + public String hello() { + return "Goodbye"; + } + } + +} diff --git a/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/RemoteServiceManager.java b/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/RemoteServiceManager.java new file mode 100644 index 00000000..3b851739 --- /dev/null +++ b/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/RemoteServiceManager.java @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.impl; + +import java.net.URI; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Service; +import org.onosproject.incubator.rpc.RemoteServiceContext; +import org.onosproject.incubator.rpc.RemoteServiceDirectory; +import org.onosproject.incubator.rpc.RemoteServiceContextProvider; +import org.onosproject.incubator.rpc.RemoteServiceContextProviderService; +import org.onosproject.incubator.rpc.RemoteServiceProviderRegistry; +import org.onosproject.net.provider.AbstractProviderService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.annotations.Beta; + +/** + * Provides RemoteService related APIs. + */ +@Beta +@Component(immediate = true) +@Service +public class RemoteServiceManager extends AbstractProviderRegistry + implements RemoteServiceDirectory, RemoteServiceProviderRegistry { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Activate + protected void activate() { + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + log.info("Stopped"); + } + + @Override + public RemoteServiceContext get(URI uri) { + RemoteServiceContextProvider factory = getProvider(uri.getScheme()); + if (factory != null) { + return factory.get(uri); + } + throw new UnsupportedOperationException(uri.getScheme() + " not supported"); + } + + private final class InternalRemoteServiceContextProviderService + extends AbstractProviderService + implements RemoteServiceContextProviderService { + + public InternalRemoteServiceContextProviderService(RemoteServiceContextProvider provider) { + super(provider); + } + } + + // make this abstract method if slicing out + @Override + protected RemoteServiceContextProviderService createProviderService(RemoteServiceContextProvider provider) { + return new InternalRemoteServiceContextProviderService(provider); + } + +} diff --git a/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/package-info.java b/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/package-info.java new file mode 100644 index 00000000..c77b4bec --- /dev/null +++ b/framework/src/onos/incubator/rpc/src/main/java/org/onosproject/incubator/rpc/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Implementation of the inter-cluster RPC service. + */ +package org.onosproject.incubator.rpc.impl; diff --git a/framework/src/onos/incubator/rpc/src/test/java/org/onosproject/incubator/rpc/impl/RemoteServiceManagerTest.java b/framework/src/onos/incubator/rpc/src/test/java/org/onosproject/incubator/rpc/impl/RemoteServiceManagerTest.java new file mode 100644 index 00000000..1bfa1e42 --- /dev/null +++ b/framework/src/onos/incubator/rpc/src/test/java/org/onosproject/incubator/rpc/impl/RemoteServiceManagerTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.incubator.rpc.impl; + +import static org.junit.Assert.*; + +import java.net.URI; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onosproject.incubator.rpc.RemoteServiceContext; +import org.onosproject.incubator.rpc.RemoteServiceDirectory; +import org.onosproject.incubator.rpc.impl.LocalRemoteServiceProvider.SomeOtherService; + +/** + * Set of tests of the RemoteServiceManager component. + */ +public class RemoteServiceManagerTest { + + private static final URI LOCAL_URI = URI.create("local://whateverIgnored"); + + private RemoteServiceManager rpcManager; + private RemoteServiceDirectory rpcDirectory; + + private LocalRemoteServiceProvider rpcProvider; + + @Before + public void setUp() { + rpcManager = new RemoteServiceManager(); + rpcManager.activate(); + rpcDirectory = rpcManager; + + rpcProvider = new LocalRemoteServiceProvider(); + rpcProvider.rpcRegistry = rpcManager; + rpcProvider.activate(); + + } + + @After + public void tearDown() { + rpcProvider.deactivate(); + + rpcManager.deactivate(); + } + + @Test + public void basics() { + RemoteServiceContext remoteServiceContext = rpcDirectory.get(LOCAL_URI); + assertNotNull("Expecting valid RPC context", remoteServiceContext); + + SomeOtherService someService = remoteServiceContext.get(SomeOtherService.class); + assertNotNull("Expecting reference to sample service", someService); + + assertEquals("Goodbye", someService.hello()); + } + +} diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/DistributedLabelResourceStore.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/DistributedLabelResourceStore.java index d129def7..a7183de8 100644 --- a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/DistributedLabelResourceStore.java +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/resource/impl/DistributedLabelResourceStore.java @@ -212,8 +212,7 @@ public class DistributedLabelResourceStore @Override public boolean createGlobalPool(LabelResourceId beginLabel, LabelResourceId endLabel) { - LabelResourcePool pool = new LabelResourcePool( - GLOBAL_RESOURCE_POOL_DEVICE_ID, + LabelResourcePool pool = new LabelResourcePool(GLOBAL_RESOURCE_POOL_DEVICE_ID, beginLabel.labelId(), endLabel.labelId()); return this.internalCreate(pool); @@ -251,8 +250,7 @@ public class DistributedLabelResourceStore .get(pool.deviceId()); if (poolOld == null) { resourcePool.put(pool.deviceId(), pool); - LabelResourceEvent event = new LabelResourceEvent( - Type.POOL_CREATED, + LabelResourceEvent event = new LabelResourceEvent(Type.POOL_CREATED, pool); notifyDelegate(event); return true; @@ -292,8 +290,7 @@ public class DistributedLabelResourceStore Versioned poolOld = resourcePool.get(deviceId); if (poolOld != null) { resourcePool.remove(deviceId); - LabelResourceEvent event = new LabelResourceEvent( - Type.POOL_CREATED, + LabelResourceEvent event = new LabelResourceEvent(Type.POOL_DESTROYED, poolOld.value()); notifyDelegate(event); } @@ -309,8 +306,7 @@ public class DistributedLabelResourceStore if (device == null) { return Collections.emptyList(); } - LabelResourceRequest request = new LabelResourceRequest( - deviceId, + LabelResourceRequest request = new LabelResourceRequest(deviceId, LabelResourceRequest.Type.APPLY, applyNum, null); NodeId master = mastershipService.getMasterFor(deviceId); @@ -345,8 +341,7 @@ public class DistributedLabelResourceStore log.info("the free number of the label resource pool of deviceId {} is not enough."); return Collections.emptyList(); } - Set releaseLabels = new HashSet( - pool.releaseLabelId()); + Set releaseLabels = new HashSet(pool.releaseLabelId()); long tmp = releaseLabels.size() > applyNum ? applyNum : releaseLabels .size(); LabelResource resource = null; @@ -394,8 +389,7 @@ public class DistributedLabelResourceStore } ImmutableSet collection = ImmutableSet.copyOf(maps .get(deviceId)); - request = new LabelResourceRequest( - deviceId, + request = new LabelResourceRequest(deviceId, LabelResourceRequest.Type.RELEASE, 0, collection); NodeId master = mastershipService.getMasterFor(deviceId); @@ -430,8 +424,7 @@ public class DistributedLabelResourceStore log.info("the label resource pool of device id {} does not exist"); return false; } - Set storeSet = new HashSet( - pool.releaseLabelId()); + Set storeSet = new HashSet(pool.releaseLabelId()); LabelResource labelResource = null; long realReleasedNum = 0; for (Iterator it = release.iterator(); it.hasNext();) { @@ -499,8 +492,7 @@ public class DistributedLabelResourceStore @Override public Collection applyFromGlobalPool(long applyNum) { - LabelResourceRequest request = new LabelResourceRequest( - DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID), + LabelResourceRequest request = new LabelResourceRequest(DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID), LabelResourceRequest.Type.APPLY, applyNum, null); return this.internalApply(request); @@ -511,17 +503,14 @@ public class DistributedLabelResourceStore Set set = new HashSet(); DefaultLabelResource resource = null; for (LabelResourceId labelResource : release) { - resource = new DefaultLabelResource( - DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID), + resource = new DefaultLabelResource(DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID), labelResource); set.add(resource); } - LabelResourceRequest request = new LabelResourceRequest( - DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID), + LabelResourceRequest request = new LabelResourceRequest(DeviceId.deviceId(GLOBAL_RESOURCE_POOL_DEVICE_ID), LabelResourceRequest.Type.APPLY, 0, - ImmutableSet - .copyOf(set)); + ImmutableSet.copyOf(set)); return this.internalRelease(request); } diff --git a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java index 78c6468e..f0ad2b01 100644 --- a/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java +++ b/framework/src/onos/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java @@ -148,7 +148,7 @@ public class DistributedTunnelStore @Override public TunnelId createOrUpdateTunnel(Tunnel tunnel) { // tunnelIdAsKeyStore. - if (tunnel.tunnelId() != null && !"".equals(tunnel.tunnelId())) { + if (tunnel.tunnelId() != null && !"".equals(tunnel.tunnelId().toString())) { Tunnel old = tunnelIdAsKeyStore.get(tunnel.tunnelId()); if (old == null) { log.info("This tunnel[" + tunnel.tunnelId() + "] is not available."); @@ -290,9 +290,10 @@ public class DistributedTunnelStore TunnelSubscription order = new TunnelSubscription(appId, null, null, tunnelId, null, null, annotations); Tunnel result = tunnelIdAsKeyStore.get(tunnelId); - if (result != null || Tunnel.State.INACTIVE.equals(result.state())) { + if (result == null || Tunnel.State.INACTIVE.equals(result.state())) { return null; } + orderSet.add(order); orderRelationship.put(appId, orderSet); return result; diff --git a/framework/src/onos/pom.xml b/framework/src/onos/pom.xml index 78fbcf2d..4d49abaa 100644 --- a/framework/src/onos/pom.xml +++ b/framework/src/onos/pom.xml @@ -47,7 +47,6 @@ protocols - ovsdb bgp providers @@ -144,12 +143,6 @@ 18.0 - - io.netty - netty - 3.9.0.Final - - com.google.guava guava-testlib @@ -187,6 +180,12 @@ 3.2.1 + + commons-pool + commons-pool + 1.6 + + org.codehaus.jackson jackson-core-asl @@ -438,22 +437,26 @@ onos-bgpio ${project.version} - - commons-pool - commons-pool - 1.6 - + org.onosproject onos-bgp-api ${project.version} - org.onosproject onos-app-bgp-api ${project.version} + + + + + io.netty + netty + 3.9.0.Final + + io.netty netty-common @@ -474,17 +477,20 @@ netty-handler ${netty4.version} + io.netty netty-codec ${netty4.version} + io.netty netty-transport-native-epoll ${netty4.version} ${os.detected.classifier} + joda-time joda-time @@ -681,7 +687,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 2.13 + 2.16 org.onosproject @@ -724,7 +730,7 @@ org.apache.maven.plugins maven-pmd-plugin - 3.2 + 3.5 @@ -747,7 +753,7 @@ org.jacoco jacoco-maven-plugin - 0.7.2.201409121644 + 0.7.5.201505241946 default-prepare-agent @@ -772,7 +778,6 @@ org.apache.maven.plugins maven-checkstyle-plugin - 2.12.1 onos/checkstyle.xml @@ -781,7 +786,6 @@ org.apache.maven.plugins maven-pmd-plugin - 3.2 diff --git a/framework/src/onos/protocols/netconf/api/pom.xml b/framework/src/onos/protocols/netconf/api/pom.xml new file mode 100644 index 00000000..ed8a5302 --- /dev/null +++ b/framework/src/onos/protocols/netconf/api/pom.xml @@ -0,0 +1,45 @@ + + + + 4.0.0 + + org.onosproject + onos-netconf + 1.4.0-SNAPSHOT + + onos-netconf-api + bundle + + ONOS NETCONF plugin API + + + commons-pool + commons-pool + + + io.netty + netty-transport + + + io.netty + netty-transport-native-epoll + ${netty4.version} + + + + diff --git a/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfController.java b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfController.java new file mode 100644 index 00000000..6411c011 --- /dev/null +++ b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfController.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.netconf; + +import org.onlab.packet.IpAddress; +import org.onosproject.net.DeviceId; + +import java.util.Map; + +/** + * Abstraction of an NETCONF controller. Serves as a one stop shop for obtaining + * NetconfDevice and (un)register listeners on NETCONF device events. + */ +public interface NetconfController { + + /** + * Adds Device Event Listener. + * + * @param listener node listener + */ + void addDeviceListener(NetconfDeviceListener listener); + + /** + * Removes Device Listener. + * + * @param listener node listener + */ + void removeDeviceListener(NetconfDeviceListener listener); + + /** + * Tries to connect to a specific NETCONF device, if the connection is succesful + * it creates and adds the device to the ONOS core as a NetconfDevice. + * + * @param deviceInfo info about the device to add + * @return NetconfDevice Netconf device + */ + NetconfDevice connectDevice(NetconfDeviceInfo deviceInfo); + + /** + * Removes a Netconf device. + * + * @param deviceInfo info about the device to remove + */ + void removeDevice(NetconfDeviceInfo deviceInfo); + + /** + * Gets all the nodes information. + * + * @return map of devices + */ + Map getDevicesMap(); + + /** + * Gets a Netconf Device by node identifier. + * + * @param deviceInfo node identifier + * @return NetconfDevice Netconf device + */ + NetconfDevice getNetconfDevice(DeviceId deviceInfo); + + /** + * Gets a Netconf Device by node identifier. + * + * @param ip device ip + * @param port device port + * @return NetconfDevice Netconf device + */ + NetconfDevice getNetconfDevice(IpAddress ip, int port); + +} diff --git a/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDevice.java b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDevice.java new file mode 100644 index 00000000..1974782b --- /dev/null +++ b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDevice.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.netconf; + +/** + * Interface representing a NETCONF device. + */ +public interface NetconfDevice { + + + /** + * Returns whether a device is a NETCONF device with a capabilities list + * and is accessible. + * + * @return true if device is accessible, false otherwise + */ + boolean isActive(); + + /** + * Returns a NETCONF session context for this device. + * + * @return netconf session + */ + NetconfSession getSession(); + + /** + * Ensures that all sessions are closed. + * A device cannot be used after disconnect is called. + */ + void disconnect(); + + /** + * return all the info associated with this device. + * @return NetconfDeviceInfo + */ + NetconfDeviceInfo getDeviceInfo(); +} \ No newline at end of file diff --git a/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceInfo.java b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceInfo.java new file mode 100644 index 00000000..cb0e240a --- /dev/null +++ b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceInfo.java @@ -0,0 +1,173 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.netconf; + +import com.google.common.base.Preconditions; +import org.onlab.packet.IpAddress; +import org.onosproject.net.DeviceId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Objects; + +/** + * Represents a Netconf device information. + */ +public class NetconfDeviceInfo { + + public static final Logger log = LoggerFactory + .getLogger(NetconfDeviceInfo.class); + + private String name; + private String password; + private IpAddress ipAddress; + private int port; + private File keyFile; + + + /** + * Information for contacting the controller. + * + * @param name the connection type + * @param password the password for the device + * @param ipAddress the ip address + * @param port the tcp port + */ + public NetconfDeviceInfo(String name, String password, IpAddress ipAddress, + int port) { + Preconditions.checkArgument(!name.equals(""), "Empty device name"); + Preconditions.checkNotNull(port > 0, "Negative port"); + Preconditions.checkNotNull(ipAddress, "Null ip address"); + this.name = name; + this.password = password; + this.ipAddress = ipAddress; + this.port = port; + } + + /** + * Information for contacting the controller. + * + * @param name the connection type + * @param password the password for the device + * @param ipAddress the ip address + * @param port the tcp port + * @param keyString the string cointaing the key. + */ + public NetconfDeviceInfo(String name, String password, IpAddress ipAddress, + int port, String keyString) { + Preconditions.checkArgument(!name.equals(""), "Empty device name"); + Preconditions.checkNotNull(port > 0, "Negative port"); + Preconditions.checkNotNull(ipAddress, "Null ip address"); + this.name = name; + this.password = password; + this.ipAddress = ipAddress; + this.port = port; + this.keyFile = new File(keyString); + } + + /** + * Exposes the name of the controller. + * + * @return String name + */ + public String name() { + return name; + } + + /** + * Exposes the password of the controller. + * + * @return String password + */ + public String password() { + return password; + } + + /** + * Exposes the ip address of the controller. + * + * @return IpAddress ip address + */ + public IpAddress ip() { + return ipAddress; + } + + /** + * Exposes the port of the controller. + * + * @return int port address + */ + public int port() { + return port; + } + + /** + * Exposes the keyFile of the controller. + * + * @return int port address + */ + public File getKeyFile() { + return keyFile; + } + + /** + * Return the info about the device in a string. + * String format: "netconf:name@ip:port" + * + * @return String device info + */ + public String toString() { + return "netconf:" + name + "@" + ipAddress + ":" + port; + } + + /** + * Return the DeviceId about the device containing the URI. + * + * @return DeviceId + */ + public DeviceId getDeviceId() { + + try { + return DeviceId.deviceId(new URI(this.toString())); + } catch (URISyntaxException e) { + log.debug("Unable to build deviceID for device {} ", this, e); + } + return null; + } + + @Override + public int hashCode() { + return Objects.hash(ipAddress, port, name); + } + + @Override + public boolean equals(Object toBeCompared) { + if (toBeCompared instanceof NetconfDeviceInfo) { + NetconfDeviceInfo netconfDeviceInfo = (NetconfDeviceInfo) toBeCompared; + if (netconfDeviceInfo.name().equals(name) + && netconfDeviceInfo.ip().equals(ipAddress) + && netconfDeviceInfo.port() == port + && netconfDeviceInfo.password().equals(password)) { + return true; + } + } + return false; + } +} diff --git a/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceListener.java b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceListener.java new file mode 100644 index 00000000..9c46d4f6 --- /dev/null +++ b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceListener.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.netconf; + +/** + * Allows for providers interested in node events to be notified. + */ +public interface NetconfDeviceListener { + + /** + * Notifies that the node was added. + * + * @param nodeId the node where the event occurred + */ + void deviceAdded(NetconfDeviceInfo nodeId); + + /** + * Notifies that the node was removed. + * + * @param nodeId the node where the event occurred + */ + void deviceRemoved(NetconfDeviceInfo nodeId); +} diff --git a/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java new file mode 100644 index 00000000..73c435f6 --- /dev/null +++ b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java @@ -0,0 +1,129 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.netconf; + +import java.util.List; + +/** + * NETCONF session object that allows NETCONF operations on top with the physical + * device on top of an SSH connection. + */ +// TODO change return type of methdos to +public interface NetconfSession { + + /** + * Retrives the requested configuration, different from get-config. + * @param request the XML containing the request to the server. + * @return device running configuration + */ + String get(String request); + + /** + * Executes an RPC to the server. + * @param request the XML containing the RPC for the server. + * @return Server response or ERROR + */ + String doRPC(String request); + + /** + * Retrives the specified configuration. + * + * @param targetConfiguration the type of configuration to retrieve. + * @return specified configuration. + */ + String getConfig(String targetConfiguration); + + /** + * Retrives part of the specivied configuration based on the filterSchema. + * + * @param targetConfiguration the type of configuration to retrieve. + * @param configurationFilterSchema XML schema to filter the configuration + * elements we are interested in + * @return device running configuration. + */ + String getConfig(String targetConfiguration, String configurationFilterSchema); + + /** + * Retrives part of the specified configuration based on the filterSchema. + * + * @param newConfiguration configuration to set + * @return true if the configuration was edited correctly + */ + + boolean editConfig(String newConfiguration); + + /** + * Copies the new configuration, an Url or a complete configuration xml tree + * to the target configuration. + * The target configuration can't be the running one + * + * @param targetConfiguration the type of configuration to retrieve. + * @param newConfiguration configuration to set + * @return true if the configuration was copied correctly + */ + boolean copyConfig(String targetConfiguration, String newConfiguration); + + /** + * Deletes part of the specified configuration based on the filterSchema. + * + * @param targetConfiguration the name of the configuration to delete + * @return true if the configuration was copied correctly + */ + boolean deleteConfig(String targetConfiguration); + + /** + * Locks the candidate configuration. + * + * @return true if successful. + */ + boolean lock(); + + /** + * Unlocks the candidate configuration. + * + * @return true if successful. + */ + boolean unlock(); + + /** + * Closes the Netconf session with the device. + * the first time it tries gracefully, then kills it forcefully + * @return true if closed + */ + boolean close(); + + /** + * Gets the session ID of the Netconf session. + * + * @return Session ID as a string. + */ + String getSessionId(); + + /** + * Gets the capabilities of the Netconf server associated to this session. + * + * @return Network capabilities as a string. + */ + String getServerCapabilities(); + + /** + * Sets the device capabilities. + * @param capabilities list of capabilities the device has. + */ + void setDeviceCapabilities(List capabilities); + +} diff --git a/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/package-info.java b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/package-info.java new file mode 100644 index 00000000..5562bd33 --- /dev/null +++ b/framework/src/onos/protocols/netconf/api/src/main/java/org/onosproject/netconf/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Created by ray on 10/30/15. + */ +package org.onosproject.netconf; diff --git a/framework/src/onos/protocols/netconf/ctl/pom.xml b/framework/src/onos/protocols/netconf/ctl/pom.xml new file mode 100644 index 00000000..e022acba --- /dev/null +++ b/framework/src/onos/protocols/netconf/ctl/pom.xml @@ -0,0 +1,91 @@ + + + + 4.0.0 + + org.onosproject + onos-netconf + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-netconf-ctl + bundle + + + + org.osgi + org.osgi.compendium + + + org.onosproject + onos-netconf-api + ${project.version} + + + ch.ethz.ganymed + ganymed-ssh2 + 262 + + + + + + + + org.apache.felix + maven-bundle-plugin + + + ch.ethz.ssh2.* + ganymed-ssh2 + + + + + + diff --git a/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java b/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java new file mode 100644 index 00000000..a572a2bc --- /dev/null +++ b/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfControllerImpl.java @@ -0,0 +1,143 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.netconf.ctl; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.IpAddress; +import org.onosproject.net.DeviceId; +import org.onosproject.netconf.NetconfController; +import org.onosproject.netconf.NetconfDevice; +import org.onosproject.netconf.NetconfDeviceInfo; +import org.onosproject.netconf.NetconfDeviceListener; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * The implementation of NetconfController. + */ +@Component(immediate = true) +@Service +public class NetconfControllerImpl implements NetconfController { + + public static final Logger log = LoggerFactory + .getLogger(NetconfControllerImpl.class); + + public Map netconfDeviceMap = new ConcurrentHashMap<>(); + + protected Set netconfDeviceListeners = new CopyOnWriteArraySet<>(); + + @Activate + public void activate(ComponentContext context) { + log.info("Started"); + } + + @Deactivate + public void deactivate() { + netconfDeviceMap.clear(); + log.info("Stopped"); + } + + @Override + public void addDeviceListener(NetconfDeviceListener listener) { + if (!netconfDeviceListeners.contains(listener)) { + netconfDeviceListeners.add(listener); + } + } + + @Override + public void removeDeviceListener(NetconfDeviceListener listener) { + netconfDeviceListeners.remove(listener); + } + + @Override + public NetconfDevice getNetconfDevice(DeviceId deviceInfo) { + return netconfDeviceMap.get(deviceInfo); + } + + @Override + public NetconfDevice getNetconfDevice(IpAddress ip, int port) { + NetconfDevice device = null; + for (DeviceId info : netconfDeviceMap.keySet()) { + if (IpAddress.valueOf(info.uri().getHost()).equals(ip) && + info.uri().getPort() == port) { + return netconfDeviceMap.get(info); + } + } + return device; + } + + @Override + public NetconfDevice connectDevice(NetconfDeviceInfo deviceInfo) { + if (netconfDeviceMap.containsKey(deviceInfo.getDeviceId())) { + log.warn("Device {} is already present"); + return netconfDeviceMap.get(deviceInfo.getDeviceId()); + } else { + log.info("Creating NETCONF device {}", deviceInfo); + return createDevice(deviceInfo); + } + } + + @Override + public void removeDevice(NetconfDeviceInfo deviceInfo) { + if (netconfDeviceMap.containsKey(deviceInfo.getDeviceId())) { + log.warn("Device {} is not present"); + } else { + stopDevice(deviceInfo); + } + } + + private NetconfDevice createDevice(NetconfDeviceInfo deviceInfo) { + NetconfDevice netconfDevice = null; + try { + netconfDevice = new NetconfDeviceImpl(deviceInfo); + for (NetconfDeviceListener l : netconfDeviceListeners) { + l.deviceAdded(deviceInfo); + } + netconfDeviceMap.put(deviceInfo.getDeviceId(), netconfDevice); + } catch (IOException e) { + throw new IllegalStateException("Cannot create NETCONF device " + + "with device Info: " + + deviceInfo + " \n" + e); + } + return netconfDevice; + } + + private void stopDevice(NetconfDeviceInfo deviceInfo) { + netconfDeviceMap.get(deviceInfo.getDeviceId()).disconnect(); + netconfDeviceMap.remove(deviceInfo.getDeviceId()); + for (NetconfDeviceListener l : netconfDeviceListeners) { + l.deviceRemoved(deviceInfo); + } + } + + @Override + public Map getDevicesMap() { + return netconfDeviceMap; + } + + +} diff --git a/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java b/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java new file mode 100644 index 00000000..3141aafc --- /dev/null +++ b/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfDeviceImpl.java @@ -0,0 +1,66 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.netconf.ctl; + +import org.onosproject.netconf.NetconfDevice; +import org.onosproject.netconf.NetconfDeviceInfo; +import org.onosproject.netconf.NetconfSession; + +import java.io.IOException; + +/** + * Implementation of a NETCONF device. + */ +public class NetconfDeviceImpl implements NetconfDevice { + + private NetconfDeviceInfo netconfDeviceInfo; + private boolean deviceState = false; + private NetconfSession netconfSession; + //private String config; + + public NetconfDeviceImpl(NetconfDeviceInfo deviceInfo) throws IOException { + netconfDeviceInfo = deviceInfo; + try { + netconfSession = new NetconfSessionImpl(netconfDeviceInfo); + } catch (IOException e) { + throw new IOException("Cannot create connection and session", e); + } + deviceState = true; + //config = netconfSession.getConfig("running"); + } + + @Override + public boolean isActive() { + return deviceState; + } + + @Override + public NetconfSession getSession() { + return netconfSession; + } + + @Override + public void disconnect() { + deviceState = false; + netconfSession.close(); + } + + @Override + public NetconfDeviceInfo getDeviceInfo() { + return netconfDeviceInfo; + } +} diff --git a/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java b/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java new file mode 100644 index 00000000..8619abc0 --- /dev/null +++ b/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/NetconfSessionImpl.java @@ -0,0 +1,396 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.netconf.ctl; + +import ch.ethz.ssh2.Connection; +import ch.ethz.ssh2.Session; +import com.google.common.base.Preconditions; +import org.onosproject.netconf.NetconfDeviceInfo; +import org.onosproject.netconf.NetconfSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Implementation of a NETCONF session to talk to a device. + */ +public class NetconfSessionImpl implements NetconfSession { + + public static final Logger log = LoggerFactory + .getLogger(NetconfSessionImpl.class); + private static final int CONNECTION_TIMEOUT = 0; + + + private Connection netconfConnection; + private NetconfDeviceInfo deviceInfo; + private Session sshSession; + private boolean connectionActive; + private BufferedReader bufferReader = null; + private PrintWriter out = null; + private int messageID = 0; + + private List deviceCapabilities = + new ArrayList<>( + Arrays.asList("urn:ietf:params:netconf:base:1.0")); + + private String serverCapabilities; + private String endpattern = "]]>]]>"; + + + public NetconfSessionImpl(NetconfDeviceInfo deviceInfo) throws IOException { + this.deviceInfo = deviceInfo; + connectionActive = false; + startConnection(); + } + + + private void startConnection() throws IOException { + if (!connectionActive) { + netconfConnection = new Connection(deviceInfo.ip().toString(), deviceInfo.port()); + netconfConnection.connect(null, CONNECTION_TIMEOUT, 0); + boolean isAuthenticated; + try { + if (deviceInfo.getKeyFile() != null) { + isAuthenticated = netconfConnection.authenticateWithPublicKey( + deviceInfo.name(), deviceInfo.getKeyFile(), + deviceInfo.password()); + } else { + log.info("authenticate with username {} and password {}", + deviceInfo.name(), deviceInfo.password()); + isAuthenticated = netconfConnection.authenticateWithPassword( + deviceInfo.name(), deviceInfo.password()); + } + } catch (IOException e) { + throw new IOException("Authentication connection failed:" + + e.getMessage()); + } + + connectionActive = true; + Preconditions.checkArgument(isAuthenticated, + "Authentication password and username failed"); + startSshSession(); + } + } + + private void startSshSession() throws IOException { + try { + sshSession = netconfConnection.openSession(); + sshSession.startSubSystem("netconf"); + bufferReader = new BufferedReader(new InputStreamReader( + sshSession.getStdout())); + out = new PrintWriter(sshSession.getStdin()); + sendHello(); + } catch (IOException e) { + throw new IOException("Failed to create ch.ethz.ssh2.Session session:" + + e.getMessage()); + } + } + + private void sendHello() throws IOException { + serverCapabilities = doRequest(createHelloString()); + } + + private String createHelloString() { + StringBuilder hellobuffer = new StringBuilder(); + hellobuffer.append("\n"); + hellobuffer.append("\n"); + hellobuffer.append(" \n"); + deviceCapabilities.forEach( + cap -> hellobuffer.append(" " + cap + "\n")); + hellobuffer.append(" \n"); + hellobuffer.append("\n"); + hellobuffer.append(endpattern); + return hellobuffer.toString(); + + } + + @Override + public String doRPC(String request) { + String reply = "ERROR"; + try { + reply = doRequest(request); + if (checkReply(reply)) { + return reply; + } else { + return "ERROR " + reply; + } + } catch (IOException e) { + log.error("Problem in the reading from the SSH connection " + e); + } + return reply; + } + + private String doRequest(String request) throws IOException { + log.info("sshState " + sshSession.getState() + "request" + request); + if (sshSession.getState() != 2) { + try { + startSshSession(); + } catch (IOException e) { + log.info("the connection had to be reopened"); + startConnection(); + } + sendHello(); + } + log.info("sshState after" + sshSession.getState()); + out.print(request); + out.flush(); + messageID++; + return readOne(); + } + + @Override + public String get(String request) { + return doRPC(request); + } + + @Override + public String getConfig(String targetConfiguration) { + return getConfig(targetConfiguration, null); + } + + @Override + public String getConfig(String targetConfiguration, String configurationSchema) { + StringBuilder rpc = new StringBuilder(""); + rpc.append("\n"); + rpc.append("\n"); + rpc.append("\n"); + rpc.append("<" + targetConfiguration + "/>"); + rpc.append(""); + if (configurationSchema != null) { + rpc.append("\n"); + rpc.append(configurationSchema + "\n"); + rpc.append("\n"); + } + rpc.append("\n"); + rpc.append("\n"); + rpc.append(endpattern); + String reply = null; + try { + reply = doRequest(rpc.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + + return checkReply(reply) ? reply : null; + } + + @Override + public boolean editConfig(String newConfiguration) { + newConfiguration = newConfiguration + endpattern; + String reply = null; + try { + reply = doRequest(newConfiguration); + } catch (IOException e) { + e.printStackTrace(); + } + return checkReply(reply); + } + + @Override + public boolean copyConfig(String targetConfiguration, String newConfiguration) { + newConfiguration = newConfiguration.trim(); + if (!newConfiguration.startsWith("")) { + newConfiguration = "" + newConfiguration + + ""; + } + StringBuilder rpc = new StringBuilder(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append("<" + targetConfiguration + "/>"); + rpc.append(""); + rpc.append(""); + rpc.append("<" + newConfiguration + "/>"); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(endpattern); + String reply = null; + try { + reply = doRequest(rpc.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + + return checkReply(reply); + } + + @Override + public boolean deleteConfig(String targetConfiguration) { + if (targetConfiguration.equals("running")) { + log.warn("Target configuration for delete operation can't be \"running\"", + targetConfiguration); + return false; + } + StringBuilder rpc = new StringBuilder(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append("<" + targetConfiguration + "/>"); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(endpattern); + String reply = null; + try { + reply = doRequest(rpc.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + + return checkReply(reply); + } + + @Override + public boolean lock() { + StringBuilder rpc = new StringBuilder(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(endpattern); + String reply = null; + try { + reply = doRequest(rpc.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + return checkReply(reply); + } + + @Override + public boolean unlock() { + StringBuilder rpc = new StringBuilder(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(""); + rpc.append(endpattern); + String reply = null; + try { + reply = doRequest(rpc.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + return checkReply(reply); + } + + @Override + public boolean close() { + return close(false); + } + + private boolean close(boolean force) { + StringBuilder rpc = new StringBuilder(); + rpc.append(""); + if (force) { + rpc.append(""); + } else { + rpc.append(""); + } + rpc.append(""); + rpc.append(""); + rpc.append(endpattern); + return checkReply(rpc.toString()) ? true : close(true); + } + + @Override + public String getSessionId() { + if (serverCapabilities.contains("")) { + String[] outer = serverCapabilities.split(""); + Preconditions.checkArgument(outer.length != 1, + "Error in retrieving the session id"); + String[] value = outer[1].split(""); + Preconditions.checkArgument(value.length != 1, + "Error in retrieving the session id"); + return value[0]; + } else { + return String.valueOf(-1); + } + } + + @Override + public String getServerCapabilities() { + return serverCapabilities; + } + + @Override + public void setDeviceCapabilities(List capabilities) { + deviceCapabilities = capabilities; + } + + private boolean checkReply(String reply) { + if (reply != null) { + if (!reply.contains("")) { + return true; + } else if (reply.contains("") + || (reply.contains("") + && reply.contains("warning"))) { + return true; + } + } + return false; + } + + private String readOne() throws IOException { + //TODO try a simple string + final StringWriter reply = new StringWriter(); + while (true) { + int charRead = bufferReader.read(); + if (charRead == -1) { + throw new IOException("Session closed"); + } + + for (int i = 0; i < endpattern.length(); i++) { + if (charRead == endpattern.charAt(i)) { + if (i < endpattern.length() - 1) { + charRead = bufferReader.read(); + } else { + return reply.getBuffer().toString(); + } + } else { + String s = endpattern.substring(0, i); + for (int j = 0; i < s.length(); j++) { + reply.write(s.charAt(j)); + } + reply.write(charRead); + break; + } + } + } + } + +} diff --git a/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/package-info.java b/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/package-info.java new file mode 100644 index 00000000..84992bf2 --- /dev/null +++ b/framework/src/onos/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Created by ray on 10/30/15. + */ +package org.onosproject.netconf.ctl; diff --git a/framework/src/onos/protocols/netconf/pom.xml b/framework/src/onos/protocols/netconf/pom.xml new file mode 100644 index 00000000..d2f5c432 --- /dev/null +++ b/framework/src/onos/protocols/netconf/pom.xml @@ -0,0 +1,83 @@ + + + + 4.0.0 + + org.onosproject + onos-protocols + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-netconf + pom + + + api + rfc + ctl + + + ONOS NETCONF southbound libraries + + + junit + junit + test + + + org.onosproject + onlab-misc + + + org.onosproject + onlab-junit + + + io.netty + netty-buffer + + + io.netty + netty-handler + + + org.apache.felix + org.apache.felix.scr.annotations + + + org.onosproject + onos-core-net + ${project.version} + + + + + + + org.apache.felix + maven-bundle-plugin + + + org.apache.felix + maven-scr-plugin + + + + diff --git a/framework/src/onos/protocols/netconf/rfc/pom.xml b/framework/src/onos/protocols/netconf/rfc/pom.xml new file mode 100644 index 00000000..832937bc --- /dev/null +++ b/framework/src/onos/protocols/netconf/rfc/pom.xml @@ -0,0 +1,30 @@ + + + + 4.0.0 + + org.onosproject + onos-netconf + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-netconf-rfc + bundle + diff --git a/framework/src/onos/protocols/netconf/rfc/src/main/java/org/onosproject/netconf/rfc/Foo.java b/framework/src/onos/protocols/netconf/rfc/src/main/java/org/onosproject/netconf/rfc/Foo.java new file mode 100644 index 00000000..06963b0c --- /dev/null +++ b/framework/src/onos/protocols/netconf/rfc/src/main/java/org/onosproject/netconf/rfc/Foo.java @@ -0,0 +1,7 @@ +package org.onosproject.netconf.rfc; + +/** + * Created by tom on 10/19/15. + */ +public class Foo { +} diff --git a/framework/src/onos/protocols/netconf/rfc/src/main/java/org/onosproject/netconf/rfc/package-info.java b/framework/src/onos/protocols/netconf/rfc/src/main/java/org/onosproject/netconf/rfc/package-info.java new file mode 100644 index 00000000..616a7ce5 --- /dev/null +++ b/framework/src/onos/protocols/netconf/rfc/src/main/java/org/onosproject/netconf/rfc/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Created by ray on 10/30/15. + */ +package org.onosproject.netconf.rfc; diff --git a/framework/src/onos/protocols/openflow/api/pom.xml b/framework/src/onos/protocols/openflow/api/pom.xml new file mode 100644 index 00000000..e535ac64 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/pom.xml @@ -0,0 +1,93 @@ + + + + 4.0.0 + + + org.onosproject + onos-of + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-of-api + bundle + + ONOS OpenFlow controller subsystem API + + + + + org.onosproject + openflowj + ${openflowj.version} + + + io.netty + netty + + + org.onosproject + onos-api + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + + + io.netty:netty + com.google.guava:guava + org.slf4j:slfj-api + ch.qos.logback:logback-core + ch.qos.logback:logback-classic + com.google.code.findbugs:annotations + + + + + + package + + shade + + + + + + org.apache.felix + maven-bundle-plugin + + + + org.onosproject.openflow.*,org.projectfloodlight.openflow.* + + + + + + + + diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/DefaultOpenFlowPacketContext.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/DefaultOpenFlowPacketContext.java new file mode 100644 index 00000000..af92a1d0 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/DefaultOpenFlowPacketContext.java @@ -0,0 +1,182 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import org.onlab.packet.DeserializationException; +import org.onlab.packet.Ethernet; +import org.projectfloodlight.openflow.protocol.OFPacketIn; +import org.projectfloodlight.openflow.protocol.OFPacketOut; +import org.projectfloodlight.openflow.protocol.OFVersion; +import org.projectfloodlight.openflow.protocol.action.OFAction; +import org.projectfloodlight.openflow.protocol.action.OFActionOutput; +import org.projectfloodlight.openflow.protocol.match.MatchField; +import org.projectfloodlight.openflow.types.OFBufferId; +import org.projectfloodlight.openflow.types.OFPort; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.BufferUnderflowException; +import java.util.Collections; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.onosproject.security.AppGuard.checkPermission; +import static org.onosproject.security.AppPermission.Type.*; + + +/** + * Default implementation of an OpenFlowPacketContext. + */ +public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext { + + private final AtomicBoolean free = new AtomicBoolean(true); + private final AtomicBoolean isBuilt = new AtomicBoolean(false); + private final OpenFlowSwitch sw; + private final OFPacketIn pktin; + private OFPacketOut pktout = null; + + private final boolean isBuffered; + + private DefaultOpenFlowPacketContext(OpenFlowSwitch s, OFPacketIn pkt) { + this.sw = s; + this.pktin = pkt; + this.isBuffered = pktin.getBufferId() != OFBufferId.NO_BUFFER; + } + + @Override + public void send() { + checkPermission(PACKET_WRITE); + + if (block() && isBuilt.get()) { + sw.sendMsg(pktout); + } + } + + @Override + public void build(OFPort outPort) { + if (isBuilt.getAndSet(true)) { + return; + } + OFPacketOut.Builder builder = sw.factory().buildPacketOut(); + OFAction act = buildOutput(outPort.getPortNumber()); + pktout = builder.setXid(pktin.getXid()) + .setInPort(pktinInPort()) + .setBufferId(OFBufferId.NO_BUFFER) + .setData(pktin.getData()) +// .setBufferId(pktin.getBufferId()) + .setActions(Collections.singletonList(act)) + .build(); + } + + @Override + public void build(Ethernet ethFrame, OFPort outPort) { + if (isBuilt.getAndSet(true)) { + return; + } + OFPacketOut.Builder builder = sw.factory().buildPacketOut(); + OFAction act = buildOutput(outPort.getPortNumber()); + pktout = builder.setXid(pktin.getXid()) + .setBufferId(OFBufferId.NO_BUFFER) + .setInPort(pktinInPort()) + .setActions(Collections.singletonList(act)) + .setData(ethFrame.serialize()) + .build(); + } + + @Override + public Ethernet parsed() { + checkPermission(PACKET_READ); + + try { + return Ethernet.deserializer().deserialize(pktin.getData(), 0, pktin.getData().length); + } catch (BufferUnderflowException | NullPointerException | + DeserializationException e) { + Logger log = LoggerFactory.getLogger(getClass()); + log.error("packet deserialization problem : {}", e.getMessage()); + return null; + } + } + + @Override + public Dpid dpid() { + checkPermission(PACKET_READ); + + return new Dpid(sw.getId()); + } + + /** + * Creates an OpenFlow packet context based on a packet-in. + * + * @param s OpenFlow switch + * @param pkt OpenFlow packet-in + * @return the OpenFlow packet context + */ + public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s, + OFPacketIn pkt) { + return new DefaultOpenFlowPacketContext(s, pkt); + } + + @Override + public Integer inPort() { + checkPermission(PACKET_READ); + + return pktinInPort().getPortNumber(); + } + + private OFPort pktinInPort() { + if (pktin.getVersion() == OFVersion.OF_10) { + return pktin.getInPort(); + } + return pktin.getMatch().get(MatchField.IN_PORT); + } + + @Override + public byte[] unparsed() { + checkPermission(PACKET_READ); + + return pktin.getData().clone(); + + } + + private OFActionOutput buildOutput(Integer port) { + OFActionOutput act = sw.factory().actions() + .buildOutput() + .setPort(OFPort.of(port)) + .build(); + return act; + } + + @Override + public boolean block() { + checkPermission(PACKET_WRITE); + + return free.getAndSet(false); + } + + @Override + public boolean isHandled() { + checkPermission(PACKET_READ); + + return !free.get(); + } + + @Override + public boolean isBuffered() { + checkPermission(PACKET_READ); + + return isBuffered; + } + +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/Dpid.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/Dpid.java new file mode 100644 index 00000000..6e0f65be --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/Dpid.java @@ -0,0 +1,132 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import org.projectfloodlight.openflow.util.HexString; + +import java.net.URI; +import java.net.URISyntaxException; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.onlab.util.Tools.fromHex; +import static org.onlab.util.Tools.toHex; + +/** + * The class representing a network switch DPID. + * This class is immutable. + */ +public final class Dpid { + + private static final String SCHEME = "of"; + private static final long UNKNOWN = 0; + private final long value; + + /** + * Default constructor. + */ + public Dpid() { + this.value = Dpid.UNKNOWN; + } + + /** + * Constructor from a long value. + * + * @param value the value to use. + */ + public Dpid(long value) { + this.value = value; + } + + /** + * Constructor from a string. + * + * @param value the value to use. + */ + public Dpid(String value) { + this.value = HexString.toLong(value); + } + + /** + * Get the value of the DPID. + * + * @return the value of the DPID. + */ + public long value() { + return value; + } + + /** + * Convert the DPID value to a ':' separated hexadecimal string. + * + * @return the DPID value as a ':' separated hexadecimal string. + */ + @Override + public String toString() { + return HexString.toHexString(this.value); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof Dpid)) { + return false; + } + + Dpid otherDpid = (Dpid) other; + + return value == otherDpid.value; + } + + @Override + public int hashCode() { + return Long.hashCode(value); + } + + /** + * Returns DPID created from the given device URI. + * + * @param uri device URI + * @return dpid + */ + public static Dpid dpid(URI uri) { + checkArgument(uri.getScheme().equals(SCHEME), "Unsupported URI scheme"); + return new Dpid(fromHex(uri.getSchemeSpecificPart())); + } + + /** + * Produces device URI from the given DPID. + * + * @param dpid device dpid + * @return device URI + */ + public static URI uri(Dpid dpid) { + return uri(dpid.value); + } + + /** + * Produces device URI from the given DPID long. + * + * @param value device dpid as long + * @return device URI + */ + public static URI uri(long value) { + try { + return new URI(SCHEME, toHex(value), null); + } catch (URISyntaxException e) { + return null; + } + } + +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ExtensionTreatmentInterpreter.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ExtensionTreatmentInterpreter.java new file mode 100644 index 00000000..dc57977f --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ExtensionTreatmentInterpreter.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.openflow.controller; + +import com.google.common.annotations.Beta; +import org.onosproject.net.driver.HandlerBehaviour; +import org.onosproject.net.flow.instructions.ExtensionTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; +import org.projectfloodlight.openflow.protocol.OFFactory; +import org.projectfloodlight.openflow.protocol.action.OFAction; + +/** + * Interprets extension instructions and converts them to/from OpenFlow objects. + */ +@Beta +public interface ExtensionTreatmentInterpreter extends HandlerBehaviour { + + /** + * Returns true if the given extension instruction is supported by this + * driver. + * + * @param extensionTreatmentType extension instruction type + * @return true if the instruction is supported, otherwise false + */ + boolean supported(ExtensionTreatmentType extensionTreatmentType); + + /** + * Maps an extension instruction to an OpenFlow action. + * + * @param factory OpenFlow factory + * @param extensionTreatment extension instruction + * @return OpenFlow action + */ + OFAction mapInstruction(OFFactory factory, ExtensionTreatment extensionTreatment); + + /** + * Maps an OpenFlow action to an extension instruction. + * + * @param action OpenFlow action + * @return extension instruction + */ + ExtensionTreatment mapAction(OFAction action); + +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowController.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowController.java new file mode 100644 index 00000000..2c68fa0b --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowController.java @@ -0,0 +1,130 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import org.projectfloodlight.openflow.protocol.OFMessage; + +/** + * Abstraction of an OpenFlow controller. Serves as a one stop + * shop for obtaining OpenFlow devices and (un)register listeners + * on OpenFlow events + */ +public interface OpenFlowController { + + /** + * Returns all switches known to this OF controller. + * @return Iterable of dpid elements + */ + Iterable getSwitches(); + + /** + * Returns all master switches known to this OF controller. + * @return Iterable of dpid elements + */ + Iterable getMasterSwitches(); + + /** + * Returns all equal switches known to this OF controller. + * @return Iterable of dpid elements + */ + Iterable getEqualSwitches(); + + + /** + * Returns the actual switch for the given Dpid. + * @param dpid the switch to fetch + * @return the interface to this switch + */ + OpenFlowSwitch getSwitch(Dpid dpid); + + /** + * Returns the actual master switch for the given Dpid, if one exists. + * @param dpid the switch to fetch + * @return the interface to this switch + */ + OpenFlowSwitch getMasterSwitch(Dpid dpid); + + /** + * Returns the actual equal switch for the given Dpid, if one exists. + * @param dpid the switch to fetch + * @return the interface to this switch + */ + OpenFlowSwitch getEqualSwitch(Dpid dpid); + + /** + * Register a listener for meta events that occur to OF + * devices. + * @param listener the listener to notify + */ + void addListener(OpenFlowSwitchListener listener); + + /** + * Unregister a listener. + * + * @param listener the listener to unregister + */ + void removeListener(OpenFlowSwitchListener listener); + + /** + * Register a listener for packet events. + * @param priority the importance of this listener, lower values are more important + * @param listener the listener to notify + */ + void addPacketListener(int priority, PacketListener listener); + + /** + * Unregister a listener. + * + * @param listener the listener to unregister + */ + void removePacketListener(PacketListener listener); + + /** + * Register a listener for OF msg events. + * + * @param listener the listener to notify + */ + void addEventListener(OpenFlowEventListener listener); + + /** + * Unregister a listener. + * + * @param listener the listener to unregister + */ + void removeEventListener(OpenFlowEventListener listener); + + /** + * Send a message to a particular switch. + * @param dpid the switch to send to. + * @param msg the message to send + */ + void write(Dpid dpid, OFMessage msg); + + /** + * Process a message and notify the appropriate listeners. + * + * @param dpid the dpid the message arrived on + * @param msg the message to process. + */ + void processPacket(Dpid dpid, OFMessage msg); + + /** + * Sets the role for a given switch. + * @param role the desired role + * @param dpid the switch to set the role for. + */ + void setRole(Dpid dpid, RoleState role); +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowEventListener.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowEventListener.java new file mode 100644 index 00000000..5deccf5e --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowEventListener.java @@ -0,0 +1,33 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import org.projectfloodlight.openflow.protocol.OFMessage; + + +/** + * Notifies providers about openflow msg events. + */ +public interface OpenFlowEventListener { + + /** + * Handles the message event. + * + * @param dpid switch data path identifier + * @param msg the message + */ + void handleMessage(Dpid dpid, OFMessage msg); +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowOpticalSwitch.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowOpticalSwitch.java new file mode 100644 index 00000000..af678d63 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowOpticalSwitch.java @@ -0,0 +1,23 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +/** + * A marker interface for optical switches, which require the ability to pass + * port information to a Device provider. + */ +public interface OpenFlowOpticalSwitch extends OpenFlowSwitch, WithTypedPorts { +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowPacketContext.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowPacketContext.java new file mode 100644 index 00000000..740d89d0 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowPacketContext.java @@ -0,0 +1,90 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import org.onlab.packet.Ethernet; +import org.projectfloodlight.openflow.types.OFPort; + +/** + * A representation of a packet context which allows any provider + * to view a packet in event, but may block the response to the + * event if blocked has been called. This packet context can be used + * to react to the packet in event with a packet out. + */ +public interface OpenFlowPacketContext { + + /** + * Blocks further responses (ie. send() calls) on this + * packet in event. + * @return true if blocks + */ + boolean block(); + + /** + * Checks whether the packet has been handled. + * @return true if handled, false otherwise. + */ + boolean isHandled(); + + /** + * Provided build has been called send the packet + * out the switch it came in on. + */ + void send(); + + /** + * Build the packet out in response to this packet in event. + * @param outPort the out port to send to packet out of. + */ + void build(OFPort outPort); + + /** + * Build the packet out in response to this packet in event. + * @param ethFrame the actual packet to send out. + * @param outPort the out port to send to packet out of. + */ + void build(Ethernet ethFrame, OFPort outPort); + + /** + * Provided a handle onto the parsed payload. + * @return the parsed form of the payload. + */ + Ethernet parsed(); + + /** + * Provide an unparsed copy of the data. + * @return the unparsed form of the payload. + */ + byte[] unparsed(); + + /** + * Provide the dpid of the switch where the packet in arrived. + * @return the dpid of the switch. + */ + Dpid dpid(); + + /** + * Provide the port on which the packet arrived. + * @return the port + */ + Integer inPort(); + + /** + * Indicates that this packet is buffered at the switch. + * @return buffer indication + */ + boolean isBuffered(); +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java new file mode 100644 index 00000000..b6ec5744 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java @@ -0,0 +1,160 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import org.onosproject.net.Device; +import org.projectfloodlight.openflow.protocol.OFFactory; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFPortDesc; + +import java.util.List; + +/** + * Represents to provider facing side of a switch. + */ +public interface OpenFlowSwitch { + + /** + * Writes the message to the driver. + *

+ * Note: Messages may be silently dropped/lost due to IOExceptions or + * role. If this is a concern, then a caller should use barriers. + *

+ * + * @param msg the message to write + */ + void sendMsg(OFMessage msg); + + /** + * Writes the OFMessage list to the driver. + *

+ * Note: Messages may be silently dropped/lost due to IOExceptions or + * role. If this is a concern, then a caller should use barriers. + *

+ * + * @param msgs the messages to be written + */ + void sendMsg(List msgs); + + /** + * Handle a message from the switch. + * @param fromSwitch the message to handle + */ + void handleMessage(OFMessage fromSwitch); + + /** + * Sets the role for this switch. + * @param role the role to set. + */ + void setRole(RoleState role); + + /** + * Fetch the role for this switch. + * @return the role. + */ + RoleState getRole(); + + /** + * Fetches the ports of this switch. + * @return unmodifiable list of the ports. + */ + List getPorts(); + + /** + * Provides the factory for this OF version. + * @return OF version specific factory. + */ + OFFactory factory(); + + /** + * Gets a string version of the ID for this switch. + * + * @return string version of the ID + */ + String getStringId(); + + /** + * Gets the datapathId of the switch. + * + * @return the switch dpid in long format + */ + long getId(); + + /** + * fetch the manufacturer description. + * @return the description + */ + String manufacturerDescription(); + + /** + * fetch the datapath description. + * @return the description + */ + String datapathDescription(); + + /** + * fetch the hardware description. + * @return the description + */ + String hardwareDescription(); + + /** + * fetch the software description. + * @return the description + */ + String softwareDescription(); + + /** + * fetch the serial number. + * @return the serial + */ + String serialNumber(); + + /** + * Checks if the switch is still connected. + * + * @return whether the switch is still connected + */ + boolean isConnected(); + + /** + * Disconnects the switch by closing the TCP connection. Results in a call + * to the channel handler's channelDisconnected method for cleanup + */ + void disconnectSwitch(); + + /** + * Notifies the controller that the device has responded to a set-role request. + * + * @param requested the role requested by the controller + * @param response the role set at the device + */ + void returnRoleReply(RoleState requested, RoleState response); + + /** + * Returns the switch device type. + * + * @return device type + */ + Device.Type deviceType(); + + /** + * Identifies the channel used to communicate with the switch. + * + * @return string representation of the connection to the device + */ + String channelId(); +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitchListener.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitchListener.java new file mode 100644 index 00000000..2da41335 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitchListener.java @@ -0,0 +1,58 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import org.projectfloodlight.openflow.protocol.OFPortStatus; + +/** + * Allows for providers interested in Switch events to be notified. + */ +public interface OpenFlowSwitchListener { + + /** + * Notify that the switch was added. + * @param dpid the switch where the event occurred + */ + void switchAdded(Dpid dpid); + + /** + * Notify that the switch was removed. + * @param dpid the switch where the event occurred. + */ + void switchRemoved(Dpid dpid); + + /** + * Notify that the switch has changed in some way. + * @param dpid the switch that changed + */ + void switchChanged(Dpid dpid); + + /** + * Notify that a port has changed. + * @param dpid the switch on which the change happened. + * @param status the new state of the port. + */ + void portChanged(Dpid dpid, OFPortStatus status); + + /** + * Notify that a role imposed on a switch failed to take hold. + * + * @param dpid the switch that failed role assertion + * @param requested the role controller requested + * @param response role reply from the switch + */ + void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response); +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/PacketListener.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/PacketListener.java new file mode 100644 index 00000000..817a6cdf --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/PacketListener.java @@ -0,0 +1,29 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +/** + * Notifies providers about Packet in events. + */ +public interface PacketListener { + + /** + * Handles the packet. + * + * @param pktCtx the packet context + */ + void handlePacket(OpenFlowPacketContext pktCtx); +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/PortDescPropertyType.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/PortDescPropertyType.java new file mode 100644 index 00000000..3a0f1a0d --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/PortDescPropertyType.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +/** + * Port description property types (OFPPDPT enums) in OF 1.3 <. + */ +public enum PortDescPropertyType { + ETHERNET(0), /* Ethernet port */ + OPTICAL(1), /* Optical port */ + OPTICAL_TRANSPORT(2), /* OF1.3 Optical transport extension */ + PIPELINE_INPUT(2), /* Ingress pipeline */ + PIPELINE_OUTPUT(3), /* Egress pipeline */ + RECIRCULATE(4), /* Recirculation */ + EXPERIMENTER(0xffff); /* Experimenter-implemented */ + + private final int value; + + PortDescPropertyType(int v) { + value = v; + } + + public int valueOf() { + return value; + } +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/RoleState.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/RoleState.java new file mode 100644 index 00000000..b8304f39 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/RoleState.java @@ -0,0 +1,40 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import org.projectfloodlight.openflow.protocol.OFControllerRole; + +/** + * The role of the controller as it pertains to a particular switch. + * Note that this definition of the role enum is different from the + * OF1.3 definition. It is maintained here to be backward compatible to + * earlier versions of the controller code. This enum is translated + * to the OF1.3 enum, before role messages are sent to the switch. + * See sendRoleRequestMessage method in OFSwitchImpl + */ +public enum RoleState { + EQUAL(OFControllerRole.ROLE_EQUAL), + MASTER(OFControllerRole.ROLE_MASTER), + SLAVE(OFControllerRole.ROLE_SLAVE); + + private RoleState(OFControllerRole nxRole) { + nxRole.ordinal(); + } + +} + + + diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ThirdPartyMessage.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ThirdPartyMessage.java new file mode 100644 index 00000000..59ef33cf --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ThirdPartyMessage.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFType; +import org.projectfloodlight.openflow.protocol.OFVersion; + +import com.google.common.hash.PrimitiveSink; +/** + * Used to support for the third party privacy flow rule. + * it implements OFMessage interface to use exist adapter API. + */ +public class ThirdPartyMessage implements OFMessage { + + private final byte[] payLoad; //privacy flow rule + + public ThirdPartyMessage(byte[] payLoad) { + this.payLoad = payLoad; + } + + public byte[] payLoad() { + return payLoad; + } + + @Override + public void putTo(PrimitiveSink sink) { + // Do nothing here for now. + } + + @Override + public OFVersion getVersion() { + // Do nothing here for now. + return null; + } + + @Override + public OFType getType() { + // Do nothing here for now. + return null; + } + + @Override + public long getXid() { + // Do nothing here for now. + return 0; + } + + @Override + public void writeTo(ChannelBuffer channelBuffer) { + // Do nothing here for now. + } + + @Override + public Builder createBuilder() { + // Do nothing here for now. + return null; + } + +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/WithTypedPorts.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/WithTypedPorts.java new file mode 100644 index 00000000..8b82b4a7 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/WithTypedPorts.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import java.util.List; +import java.util.Set; + +import org.projectfloodlight.openflow.protocol.OFObject; + +/** + * An interface implemented by OpenFlow devices that enables providers to + * retrieve ports based on port property. + */ +public interface WithTypedPorts { + + /** + * Return a list of interfaces (ports) of the type associated with this + * OpenFlow switch. + * + * @param type The port description property type of requested ports + * @return A potentially empty list of ports. + */ + List getPortsOf(PortDescPropertyType type); + + /** + * Returns the port property types supported by the driver implementing this + * interface. + * + * @return A set of port property types + */ + Set getPortTypes(); +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java new file mode 100644 index 00000000..c7174192 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java @@ -0,0 +1,493 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.openflow.controller.driver; + +import com.google.common.collect.Lists; +import org.jboss.netty.channel.Channel; +import org.onlab.packet.IpAddress; +import org.onosproject.net.Device; +import org.onosproject.net.driver.AbstractHandlerBehaviour; +import org.onosproject.openflow.controller.Dpid; +import org.onosproject.openflow.controller.RoleState; +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFErrorMsg; +import org.projectfloodlight.openflow.protocol.OFExperimenter; +import org.projectfloodlight.openflow.protocol.OFFactories; +import org.projectfloodlight.openflow.protocol.OFFactory; +import org.projectfloodlight.openflow.protocol.OFFeaturesReply; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleRequest; +import org.projectfloodlight.openflow.protocol.OFPortDesc; +import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFPortStatus; +import org.projectfloodlight.openflow.protocol.OFRoleReply; +import org.projectfloodlight.openflow.protocol.OFRoleRequest; +import org.projectfloodlight.openflow.protocol.OFVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +/** + * An abstract representation of an OpenFlow switch. Can be extended by others + * to serve as a base for their vendor specific representation of a switch. + */ +public abstract class AbstractOpenFlowSwitch extends AbstractHandlerBehaviour + implements OpenFlowSwitchDriver { + + protected final Logger log = LoggerFactory.getLogger(getClass()); + + private Channel channel; + protected String channelId; + + private boolean connected; + protected boolean startDriverHandshakeCalled = false; + private Dpid dpid; + private OpenFlowAgent agent; + private final AtomicInteger xidCounter = new AtomicInteger(0); + + private OFVersion ofVersion; + + protected List ports = new ArrayList<>(); + + protected boolean tableFull; + + private RoleHandler roleMan; + + // TODO this is accessed from multiple threads, but volatile may have performance implications + protected volatile RoleState role; + + protected OFFeaturesReply features; + protected OFDescStatsReply desc; + + private final AtomicReference> messagesPendingMastership + = new AtomicReference<>(); + + @Override + public void init(Dpid dpid, OFDescStatsReply desc, OFVersion ofv) { + this.dpid = dpid; + this.desc = desc; + this.ofVersion = ofv; + } + + //************************ + // Channel related + //************************ + + @Override + public final void disconnectSwitch() { + this.channel.close(); + } + + @Override + public void sendMsg(OFMessage msg) { + this.sendMsg(Collections.singletonList(msg)); + } + + @Override + public final void sendMsg(List msgs) { + /* + It is possible that in this block, we transition to SLAVE/EQUAL. + If this is the case, the supplied messages will race with the + RoleRequest message, and they could be rejected by the switch. + In the interest of performance, we will not protect this block with + a synchronization primitive, because the message would have just been + dropped anyway. + */ + if (role == RoleState.MASTER) { + // fast path send when we are master + + sendMsgsOnChannel(msgs); + return; + } + // check to see if mastership transition is in progress + synchronized (messagesPendingMastership) { + /* + messagesPendingMastership is used as synchronization variable for + all mastership related changes. In this block, mastership (including + role update) will have either occurred or not. + */ + if (role == RoleState.MASTER) { + // transition to MASTER complete, send messages + sendMsgsOnChannel(msgs); + return; + } + + List messages = messagesPendingMastership.get(); + if (messages != null) { + // we are transitioning to MASTER, so add messages to queue + messages.addAll(msgs); + log.debug("Enqueue message for switch {}. queue size after is {}", + dpid, messages.size()); + } else { + // not transitioning to MASTER + log.warn("Dropping message for switch {} (role: {}, connected: {}): {}", + dpid, role, channel.isConnected(), msgs); + } + } + } + + private void sendMsgsOnChannel(List msgs) { + if (channel.isConnected()) { + channel.write(msgs); + } else { + log.warn("Dropping messages for switch {} because channel is not connected: {}", + dpid, msgs); + } + } + + @Override + public final void sendRoleRequest(OFMessage msg) { + if (msg instanceof OFRoleRequest || + msg instanceof OFNiciraControllerRoleRequest) { + sendMsgsOnChannel(Collections.singletonList(msg)); + return; + } + throw new IllegalArgumentException("Someone is trying to send " + + "a non role request message"); + } + + @Override + public final void sendHandshakeMessage(OFMessage message) { + if (!this.isDriverHandshakeComplete()) { + sendMsgsOnChannel(Collections.singletonList(message)); + } + } + + @Override + public final boolean isConnected() { + return this.connected; + } + + @Override + public final void setConnected(boolean connected) { + this.connected = connected; + } + + @Override + public final void setChannel(Channel channel) { + this.channel = channel; + final SocketAddress address = channel.getRemoteAddress(); + if (address instanceof InetSocketAddress) { + final InetSocketAddress inetAddress = (InetSocketAddress) address; + final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress()); + if (ipAddress.isIp4()) { + channelId = ipAddress.toString() + ':' + inetAddress.getPort(); + } else { + channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort(); + } + } + } + + @Override + public String channelId() { + return channelId; + } + + //************************ + // Switch features related + //************************ + + @Override + public final long getId() { + return this.dpid.value(); + } + + @Override + public final String getStringId() { + return this.dpid.toString(); + } + + @Override + public final void setOFVersion(OFVersion ofV) { + this.ofVersion = ofV; + } + + @Override + public void setTableFull(boolean full) { + this.tableFull = full; + } + + @Override + public void setFeaturesReply(OFFeaturesReply featuresReply) { + this.features = featuresReply; + } + + @Override + public abstract Boolean supportNxRole(); + + //************************ + // Message handling + //************************ + /** + * Handle the message coming from the dataplane. + * + * @param m the actual message + */ + @Override + public final void handleMessage(OFMessage m) { + if (this.role == RoleState.MASTER || m instanceof OFPortStatus) { + this.agent.processMessage(dpid, m); + } + } + + @Override + public RoleState getRole() { + return role; + } + + @Override + public final boolean connectSwitch() { + return this.agent.addConnectedSwitch(dpid, this); + } + + @Override + public final boolean activateMasterSwitch() { + return this.agent.addActivatedMasterSwitch(dpid, this); + } + + @Override + public final boolean activateEqualSwitch() { + return this.agent.addActivatedEqualSwitch(dpid, this); + } + + @Override + public final void transitionToEqualSwitch() { + this.agent.transitionToEqualSwitch(dpid); + } + + @Override + public final void transitionToMasterSwitch() { + this.agent.transitionToMasterSwitch(dpid); + synchronized (messagesPendingMastership) { + List messages = messagesPendingMastership.get(); + if (messages != null) { + this.sendMsg(messages); + log.debug("Sending {} pending messages to switch {}", + messages.size(), dpid); + messagesPendingMastership.set(null); + } + // perform role transition after clearing messages queue + this.role = RoleState.MASTER; + } + } + + @Override + public final void removeConnectedSwitch() { + this.agent.removeConnectedSwitch(dpid); + } + + @Override + public OFFactory factory() { + return OFFactories.getFactory(ofVersion); + } + + @Override + public void setPortDescReply(OFPortDescStatsReply portDescReply) { + this.ports.add(portDescReply); + } + + @Override + public void setPortDescReplies(List portDescReplies) { + this.ports.addAll(portDescReplies); + } + + @Override + public void returnRoleReply(RoleState requested, RoleState response) { + this.agent.returnRoleReply(dpid, requested, response); + } + + @Override + public abstract void startDriverHandshake(); + + @Override + public abstract boolean isDriverHandshakeComplete(); + + @Override + public abstract void processDriverHandshakeMessage(OFMessage m); + + + // Role Handling + + @Override + public void setRole(RoleState role) { + try { + if (role == RoleState.SLAVE || role == RoleState.EQUAL) { + // perform role transition to SLAVE/EQUAL before sending role request + this.role = role; + } + if (this.roleMan.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE)) { + log.debug("Sending role {} to switch {}", role, getStringId()); + if (role == RoleState.MASTER) { + synchronized (messagesPendingMastership) { + if (messagesPendingMastership.get() == null) { + log.debug("Initializing new message queue for switch {}", dpid); + /* + The presence of messagesPendingMastership indicates that + a switch is currently transitioning to MASTER, but + is still awaiting role reply from switch. + */ + messagesPendingMastership.set(Lists.newArrayList()); + } + } + } + } else if (role == RoleState.MASTER) { + // role request not support; transition switch to MASTER + this.role = role; + } + } catch (IOException e) { + log.error("Unable to write to switch {}.", this.dpid); + } + } + + @Override + public void reassertRole() { + // TODO should messages be sent directly or queue during reassertion? + if (this.getRole() == RoleState.MASTER) { + log.warn("Received permission error from switch {} while " + + "being master. Reasserting master role.", + this.getStringId()); + this.setRole(RoleState.MASTER); + } + } + + @Override + public void handleRole(OFMessage m) throws SwitchStateException { + RoleReplyInfo rri = roleMan.extractOFRoleReply((OFRoleReply) m); + RoleRecvStatus rrs = roleMan.deliverRoleReply(rri); + if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) { + if (rri.getRole() == RoleState.MASTER) { + this.transitionToMasterSwitch(); + } else if (rri.getRole() == RoleState.EQUAL || + rri.getRole() == RoleState.SLAVE) { + this.transitionToEqualSwitch(); + } + } else { + log.warn("Failed to set role for {}", this.getStringId()); + } + } + + @Override + public void handleNiciraRole(OFMessage m) throws SwitchStateException { + RoleState r = this.roleMan.extractNiciraRoleReply((OFExperimenter) m); + if (r == null) { + // The message wasn't really a Nicira role reply. We just + // dispatch it to the OFMessage listeners in this case. + this.handleMessage(m); + return; + } + + RoleRecvStatus rrs = this.roleMan.deliverRoleReply( + new RoleReplyInfo(r, null, m.getXid())); + if (rrs == RoleRecvStatus.MATCHED_SET_ROLE) { + if (r == RoleState.MASTER) { + this.transitionToMasterSwitch(); + } else if (r == RoleState.EQUAL || + r == RoleState.SLAVE) { + this.transitionToEqualSwitch(); + } + } else { + this.disconnectSwitch(); + } + } + + @Override + public boolean handleRoleError(OFErrorMsg error) { + try { + return RoleRecvStatus.OTHER_EXPECTATION != this.roleMan.deliverError(error); + } catch (SwitchStateException e) { + this.disconnectSwitch(); + } + return true; + } + + @Override + public final void setAgent(OpenFlowAgent ag) { + if (this.agent == null) { + this.agent = ag; + } + } + + @Override + public final void setRoleHandler(RoleHandler roleHandler) { + if (this.roleMan == null) { + this.roleMan = roleHandler; + } + } + + @Override + public void setSwitchDescription(OFDescStatsReply d) { + this.desc = d; + } + + @Override + public int getNextTransactionId() { + return this.xidCounter.getAndIncrement(); + } + + @Override + public List getPorts() { + return this.ports.stream() + .flatMap(portReply -> portReply.getEntries().stream()) + .collect(Collectors.toList()); + } + + @Override + public String manufacturerDescription() { + return this.desc.getMfrDesc(); + } + + @Override + public String datapathDescription() { + return this.desc.getDpDesc(); + } + + @Override + public String hardwareDescription() { + return this.desc.getHwDesc(); + } + + @Override + public String softwareDescription() { + return this.desc.getSwDesc(); + } + + @Override + public String serialNumber() { + return this.desc.getSerialNum(); + } + + @Override + public Device.Type deviceType() { + return Device.Type.SWITCH; + } + + @Override + public String toString() { + return this.getClass().getName() + " [" + ((channel != null) + ? channel.getRemoteAddress() : "?") + + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]"; + } +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowAgent.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowAgent.java new file mode 100644 index 00000000..ad6dede1 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowAgent.java @@ -0,0 +1,102 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +import org.onosproject.openflow.controller.Dpid; +import org.onosproject.openflow.controller.OpenFlowSwitch; +import org.onosproject.openflow.controller.RoleState; +import org.projectfloodlight.openflow.protocol.OFMessage; + +/** + * Responsible for keeping track of the current set of switches + * connected to the system. As well as whether they are in Master + * role or not. + * + */ +public interface OpenFlowAgent { + + /** + * Add a switch that has just connected to the system. + * @param dpid the dpid to add + * @param sw the actual switch object. + * @return true if added, false otherwise. + */ + boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw); + + /** + * Checks if the activation for this switch is valid. + * @param dpid the dpid to check + * @return true if valid, false otherwise + */ + boolean validActivation(Dpid dpid); + + /** + * Called when a switch is activated, with this controller's role as MASTER. + * @param dpid the dpid to add. + * @param sw the actual switch + * @return true if added, false otherwise. + */ + boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw); + + /** + * Called when a switch is activated, with this controller's role as EQUAL. + * @param dpid the dpid to add. + * @param sw the actual switch + * @return true if added, false otherwise. + */ + boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw); + + /** + * Called when this controller's role for a switch transitions from equal + * to master. For 1.0 switches, we internally refer to the role 'slave' as + * 'equal' - so this transition is equivalent to 'addActivatedMasterSwitch'. + * @param dpid the dpid to transistion. + */ + void transitionToMasterSwitch(Dpid dpid); + + /** + * Called when this controller's role for a switch transitions to equal. + * For 1.0 switches, we internally refer to the role 'slave' as + * 'equal'. + * @param dpid the dpid to transistion. + */ + void transitionToEqualSwitch(Dpid dpid); + + /** + * Clear all state in controller switch maps for a switch that has + * disconnected from the local controller. Also release control for + * that switch from the global repository. Notify switch listeners. + * @param dpid the dpid to remove. + */ + void removeConnectedSwitch(Dpid dpid); + + /** + * Process a message coming from a switch. + * + * @param dpid the dpid the message came on. + * @param m the message to process + */ + void processMessage(Dpid dpid, OFMessage m); + + /** + * Notifies the controller that role assertion has failed. + * + * @param dpid the switch that failed role assertion + * @param requested the role controller requested + * @param response role reply from the switch + */ + void returnRoleReply(Dpid dpid, RoleState requested, RoleState response); +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java new file mode 100644 index 00000000..b259388c --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriver.java @@ -0,0 +1,221 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +import org.jboss.netty.channel.Channel; +import org.onosproject.net.driver.HandlerBehaviour; +import org.onosproject.openflow.controller.Dpid; +import org.onosproject.openflow.controller.OpenFlowSwitch; +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFErrorMsg; +import org.projectfloodlight.openflow.protocol.OFFeaturesReply; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFVersion; + +import java.util.List; + +/** + * Represents the driver side of an OpenFlow switch. + * This interface should never be exposed to consumers. + * + */ +public interface OpenFlowSwitchDriver extends OpenFlowSwitch, HandlerBehaviour { + + /** + * Sets the OpenFlow agent to be used. This method + * can only be called once. + * @param agent the agent to set. + */ + void setAgent(OpenFlowAgent agent); + + /** + * Sets the Role handler object. + * This method can only be called once. + * @param roleHandler the roleHandler class + */ + void setRoleHandler(RoleHandler roleHandler); + + /** + * Reasserts this controllers role to the switch. + * Useful in cases where the switch no longer agrees + * that this controller has the role it claims. + */ + void reassertRole(); + + /** + * Handle the situation where the role request triggers an error. + * @param error the error to handle. + * @return true if handled, false if not. + */ + boolean handleRoleError(OFErrorMsg error); + + /** + * If this driver know of Nicira style role messages, these should + * be handled here. + * @param m the role message to handle. + * @throws SwitchStateException if the message received was + * not a nicira role or was malformed. + */ + void handleNiciraRole(OFMessage m) throws SwitchStateException; + + /** + * Handle OF 1.x (where x > 0) role messages. + * @param m the role message to handle + * @throws SwitchStateException if the message received was + * not a nicira role or was malformed. + */ + void handleRole(OFMessage m) throws SwitchStateException; + + /** + * Announce to the OpenFlow agent that this switch has connected. + * @return true if successful, false if duplicate switch. + */ + boolean connectSwitch(); + + /** + * Activate this MASTER switch-controller relationship in the OF agent. + * @return true is successful, false is switch has not + * connected or is unknown to the system. + */ + boolean activateMasterSwitch(); + + /** + * Activate this EQUAL switch-controller relationship in the OF agent. + * @return true is successful, false is switch has not + * connected or is unknown to the system. + */ + boolean activateEqualSwitch(); + + /** + * Transition this switch-controller relationship to an EQUAL state. + */ + void transitionToEqualSwitch(); + + /** + * Transition this switch-controller relationship to an Master state. + */ + void transitionToMasterSwitch(); + + /** + * Remove this switch from the openflow agent. + */ + void removeConnectedSwitch(); + + /** + * Sets the ports on this switch. + * @param portDescReply the port set and descriptions + */ + void setPortDescReply(OFPortDescStatsReply portDescReply); + + /** + * Sets the ports on this switch. + * @param portDescReplies list of port set and descriptions + */ + void setPortDescReplies(List portDescReplies); + + /** + * Sets the features reply for this switch. + * @param featuresReply the features to set. + */ + void setFeaturesReply(OFFeaturesReply featuresReply); + + /** + * Sets the switch description. + * @param desc the descriptions + */ + void setSwitchDescription(OFDescStatsReply desc); + + /** + * Gets the next transaction id to use. + * @return the xid + */ + int getNextTransactionId(); + + + /** + * Sets the OF version for this switch. + * @param ofV the version to set. + */ + void setOFVersion(OFVersion ofV); + + /** + * Sets this switch has having a full flowtable. + * @param full true if full, false otherswise. + */ + void setTableFull(boolean full); + + /** + * Sets the associated Netty channel for this switch. + * @param channel the Netty channel + */ + void setChannel(Channel channel); + + /** + * Sets whether the switch is connected. + * + * @param connected whether the switch is connected + */ + void setConnected(boolean connected); + + /** + * Initialises the behaviour. + * @param dpid a dpid + * @param desc a switch description + * @param ofv OpenFlow version + */ + void init(Dpid dpid, OFDescStatsReply desc, OFVersion ofv); + + /** + * Does this switch support Nicira Role messages. + * @return true if supports, false otherwise. + */ + Boolean supportNxRole(); + + + /** + * Starts the driver specific handshake process. + */ + void startDriverHandshake(); + + /** + * Checks whether the driver specific handshake is complete. + * @return true is finished, false if not. + */ + boolean isDriverHandshakeComplete(); + + /** + * Process a message during the driver specific handshake. + * @param m the message to process. + */ + void processDriverHandshakeMessage(OFMessage m); + + /** + * Sends only role request messages. + * + * @param message a role request message. + */ + void sendRoleRequest(OFMessage message); + + /** + * Allows the handshaker behaviour to send messages during the + * handshake phase only. + * + * @param message an OpenFlow message + */ + void sendHandshakeMessage(OFMessage message); + +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriverFactory.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriverFactory.java new file mode 100644 index 00000000..a0d8f18f --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/OpenFlowSwitchDriverFactory.java @@ -0,0 +1,39 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +import org.onosproject.openflow.controller.Dpid; +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFVersion; + +/** + * Switch factory which returns concrete switch objects for the + * physical openflow switch in use. + * + */ +public interface OpenFlowSwitchDriverFactory { + + + /** + * Constructs the real openflow switch representation. + * @param dpid the dpid for this switch. + * @param desc its description. + * @param ofv the OF version in use + * @return the openflow switch representation. + */ + OpenFlowSwitchDriver getOFSwitchImpl(Dpid dpid, + OFDescStatsReply desc, OFVersion ofv); +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleHandler.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleHandler.java new file mode 100644 index 00000000..b4068886 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleHandler.java @@ -0,0 +1,114 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +import java.io.IOException; + +import org.onosproject.openflow.controller.RoleState; +import org.projectfloodlight.openflow.protocol.OFErrorMsg; +import org.projectfloodlight.openflow.protocol.OFExperimenter; +import org.projectfloodlight.openflow.protocol.OFRoleReply; + +/** + * Role handling. + * + */ +public interface RoleHandler { + + /** + * Extract the role from an OFVendor message. + * + * Extract the role from an OFVendor message if the message is a + * Nicira role reply. Otherwise return null. + * + * @param experimenterMsg The vendor message to parse. + * @return The role in the message if the message is a Nicira role + * reply, null otherwise. + * @throws SwitchStateException If the message is a Nicira role reply + * but the numeric role value is unknown. + */ + RoleState extractNiciraRoleReply(OFExperimenter experimenterMsg) + throws SwitchStateException; + + /** + * Send a role request with the given role to the switch and update + * the pending request and timestamp. + * Sends an OFPT_ROLE_REQUEST to an OF1.3 switch, OR + * Sends an NX_ROLE_REQUEST to an OF1.0 switch if configured to support it + * in the IOFSwitch driver. If not supported, this method sends nothing + * and returns 'false'. The caller should take appropriate action. + * + * One other optimization we do here is that for OF1.0 switches with + * Nicira role message support, we force the Role.EQUAL to become + * Role.SLAVE, as there is no defined behavior for the Nicira role OTHER. + * We cannot expect it to behave like SLAVE. We don't have this problem with + * OF1.3 switches, because Role.EQUAL is well defined and we can simulate + * SLAVE behavior by using ASYNC messages. + * + * @param role role to request + * @param exp expectation + * @throws IOException when I/O exception of some sort has occurred + * @return false if and only if the switch does not support role-request + * messages, according to the switch driver; true otherwise. + */ + boolean sendRoleRequest(RoleState role, RoleRecvStatus exp) + throws IOException; + + /** + * Extract the role information from an OF1.3 Role Reply Message. + * @param rrmsg role reply message + * @return RoleReplyInfo object + * @throws SwitchStateException If unknown role encountered + */ + RoleReplyInfo extractOFRoleReply(OFRoleReply rrmsg) + throws SwitchStateException; + + /** + * Deliver a received role reply. + * + * Check if a request is pending and if the received reply matches the + * the expected pending reply (we check both role and xid) we set + * the role for the switch/channel. + * + * If a request is pending but doesn't match the reply we ignore it, and + * return + * + * If no request is pending we disconnect with a SwitchStateException + * + * @param rri information about role-reply in format that + * controller can understand. + * @return result comparing expected and received reply + * @throws SwitchStateException if no request is pending + */ + RoleRecvStatus deliverRoleReply(RoleReplyInfo rri) + throws SwitchStateException; + + + /** + * Called if we receive an error message. If the xid matches the + * pending request we handle it otherwise we ignore it. + * + * Note: since we only keep the last pending request we might get + * error messages for earlier role requests that we won't be able + * to handle + * @param error error message + * @return result comparing expected and received reply + * @throws SwitchStateException if switch did not support requested role + */ + RoleRecvStatus deliverError(OFErrorMsg error) + throws SwitchStateException; + +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleRecvStatus.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleRecvStatus.java new file mode 100644 index 00000000..88c4cc70 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleRecvStatus.java @@ -0,0 +1,52 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +/** + * When we remove a pending role request we use this enum to indicate how we + * arrived at the decision. When we send a role request to the switch, we + * also use this enum to indicate what we expect back from the switch, so the + * role changer can match the reply to our expectation. + */ +public enum RoleRecvStatus { + /** The switch returned an error indicating that roles are not. + * supported*/ + UNSUPPORTED, + /** The request timed out. */ + NO_REPLY, + /** The reply was old, there is a newer request pending. */ + OLD_REPLY, + /** + * The reply's role matched the role that this controller set in the + * request message - invoked either initially at startup or to reassert + * current role. + */ + MATCHED_CURRENT_ROLE, + /** + * The reply's role matched the role that this controller set in the + * request message - this is the result of a callback from the + * global registry, followed by a role request sent to the switch. + */ + MATCHED_SET_ROLE, + /** + * The reply's role was a response to the query made by this controller. + */ + REPLY_QUERY, + /** We received a role reply message from the switch + * but the expectation was unclear, or there was no expectation. + */ + OTHER_EXPECTATION, +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleReplyInfo.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleReplyInfo.java new file mode 100644 index 00000000..dc9b6bad --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/RoleReplyInfo.java @@ -0,0 +1,48 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +import org.onosproject.openflow.controller.RoleState; +import org.projectfloodlight.openflow.types.U64; + +/** + * Helper class returns role reply information in the format understood + * by the controller. + */ +public class RoleReplyInfo { + private final RoleState role; + private final U64 genId; + private final long xid; + + public RoleReplyInfo(RoleState role, U64 genId, long xid) { + this.role = role; + this.genId = genId; + this.xid = xid; + } + public RoleState getRole() { + return role; + } + public U64 getGenId() { + return genId; + } + public long getXid() { + return xid; + } + @Override + public String toString() { + return "[Role:" + role + " GenId:" + genId + " Xid:" + xid + "]"; + } +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeAlreadyStarted.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeAlreadyStarted.java new file mode 100644 index 00000000..96b4bd73 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeAlreadyStarted.java @@ -0,0 +1,29 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +/** + * Thrown when IOFSwitch.startDriverHandshake() is called more than once. + * + */ +public class SwitchDriverSubHandshakeAlreadyStarted extends + SwitchDriverSubHandshakeException { + private static final long serialVersionUID = -5491845708752443501L; + + public SwitchDriverSubHandshakeAlreadyStarted() { + super(); + } +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeCompleted.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeCompleted.java new file mode 100644 index 00000000..b0f59fe5 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeCompleted.java @@ -0,0 +1,34 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +import org.projectfloodlight.openflow.protocol.OFMessage; + + +/** + * Indicates that a message was passed to a switch driver's subhandshake + * handling code but the driver has already completed the sub-handshake. + * + */ +public class SwitchDriverSubHandshakeCompleted + extends SwitchDriverSubHandshakeException { + private static final long serialVersionUID = -8817822245846375995L; + + public SwitchDriverSubHandshakeCompleted(OFMessage m) { + super("Sub-Handshake is already complete but received message " + + m.getType()); + } +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeException.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeException.java new file mode 100644 index 00000000..1bc750ab --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +/** + * Base class for exception thrown by switch driver sub-handshake processing. + * + */ +public class SwitchDriverSubHandshakeException extends RuntimeException { + private static final long serialVersionUID = -6257836781419604438L; + + protected SwitchDriverSubHandshakeException() { + super(); + } + + protected SwitchDriverSubHandshakeException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + + protected SwitchDriverSubHandshakeException(String arg0) { + super(arg0); + } + + protected SwitchDriverSubHandshakeException(Throwable arg0) { + super(arg0); + } + +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeNotStarted.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeNotStarted.java new file mode 100644 index 00000000..a073683c --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeNotStarted.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +/** + * Thrown when a switch driver's sub-handshake has not been started but an + * operation requiring the sub-handshake has been attempted. + * + */ +public class SwitchDriverSubHandshakeNotStarted extends + SwitchDriverSubHandshakeException { + private static final long serialVersionUID = -5491845708752443501L; + + public SwitchDriverSubHandshakeNotStarted() { + super(); + } +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeStateException.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeStateException.java new file mode 100644 index 00000000..3f4be813 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchDriverSubHandshakeStateException.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.driver; + +/** + * Thrown when a switch driver's sub-handshake state-machine receives an + * unexpected OFMessage and/or is in an invald state. + * + */ +public class SwitchDriverSubHandshakeStateException extends + SwitchDriverSubHandshakeException { + private static final long serialVersionUID = -8249926069195147051L; + + public SwitchDriverSubHandshakeStateException(String msg) { + super(msg); + } +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchStateException.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchStateException.java new file mode 100644 index 00000000..30c4e917 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/SwitchStateException.java @@ -0,0 +1,49 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.openflow.controller.driver; + +/** + * This exception indicates an error or unexpected message during + * message handling. E.g., if an OFMessage is received that is illegal or + * unexpected given the current handshake state. + * + * We don't allow wrapping other exception in a switch state exception. We + * only log the SwitchStateExceptions message so the causing exceptions + * stack trace is generally not available. + * + */ +public class SwitchStateException extends Exception { + + private static final long serialVersionUID = 9153954512470002631L; + + public SwitchStateException() { + super(); + } + + public SwitchStateException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + + public SwitchStateException(String arg0) { + super(arg0); + } + + public SwitchStateException(Throwable arg0) { + super(arg0); + } + +} diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/package-info.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/package-info.java new file mode 100644 index 00000000..c03a5840 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * OpenFlow controller switch driver API. + */ +package org.onosproject.openflow.controller.driver; diff --git a/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/package-info.java b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/package-info.java new file mode 100644 index 00000000..54778426 --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * OpenFlow controller API. + */ +package org.onosproject.openflow.controller; diff --git a/framework/src/onos/protocols/openflow/api/src/test/java/org/onosproject/openflow/controller/OpenflowControllerAdapter.java b/framework/src/onos/protocols/openflow/api/src/test/java/org/onosproject/openflow/controller/OpenflowControllerAdapter.java new file mode 100644 index 00000000..f4fe490f --- /dev/null +++ b/framework/src/onos/protocols/openflow/api/src/test/java/org/onosproject/openflow/controller/OpenflowControllerAdapter.java @@ -0,0 +1,89 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller; + +import org.projectfloodlight.openflow.protocol.OFMessage; + +/** + * Test adapter for the OpenFlow controller interface. + */ +public class OpenflowControllerAdapter implements OpenFlowController { + @Override + public Iterable getSwitches() { + return null; + } + + @Override + public Iterable getMasterSwitches() { + return null; + } + + @Override + public Iterable getEqualSwitches() { + return null; + } + + @Override + public OpenFlowSwitch getSwitch(Dpid dpid) { + return null; + } + + @Override + public OpenFlowSwitch getMasterSwitch(Dpid dpid) { + return null; + } + + @Override + public OpenFlowSwitch getEqualSwitch(Dpid dpid) { + return null; + } + + @Override + public void addListener(OpenFlowSwitchListener listener) { + } + + @Override + public void removeListener(OpenFlowSwitchListener listener) { + } + + @Override + public void addPacketListener(int priority, PacketListener listener) { + } + + @Override + public void removePacketListener(PacketListener listener) { + } + + @Override + public void write(Dpid dpid, OFMessage msg) { + } + + @Override + public void processPacket(Dpid dpid, OFMessage msg) { + } + + @Override + public void setRole(Dpid dpid, RoleState role) { + } + + @Override + public void addEventListener(OpenFlowEventListener listener) { + } + + @Override + public void removeEventListener(OpenFlowEventListener listener) { + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/pom.xml b/framework/src/onos/protocols/openflow/ctl/pom.xml new file mode 100644 index 00000000..56d48550 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + + org.onosproject + onos-of + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-of-ctl + bundle + + ONOS OpenFlow controller subsystem API + + + + org.onosproject + onos-of-api + + + io.netty + netty + + + org.apache.felix + org.apache.felix.scr.annotations + + + org.osgi + org.osgi.compendium + + + + + + + org.apache.felix + maven-scr-plugin + + + org.onosproject + onos-maven-plugin + + + + + diff --git a/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java new file mode 100644 index 00000000..56b3a99c --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java @@ -0,0 +1,328 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.openflow.controller.impl; + +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.group.ChannelGroup; +import org.jboss.netty.channel.group.DefaultChannelGroup; +import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; +import org.onlab.util.ItemNotFoundException; +import org.onosproject.net.DeviceId; +import org.onosproject.net.driver.DefaultDriverData; +import org.onosproject.net.driver.DefaultDriverHandler; +import org.onosproject.net.driver.Driver; +import org.onosproject.net.driver.DriverService; +import org.onosproject.openflow.controller.Dpid; +import org.onosproject.openflow.controller.driver.OpenFlowAgent; +import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver; +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFFactories; +import org.projectfloodlight.openflow.protocol.OFFactory; +import org.projectfloodlight.openflow.protocol.OFVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.TrustManagerFactory; +import java.io.FileInputStream; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.net.InetSocketAddress; +import java.security.KeyStore; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.onlab.util.Tools.get; +import static org.onlab.util.Tools.groupedThreads; +import static org.onosproject.net.DeviceId.deviceId; +import static org.onosproject.openflow.controller.Dpid.uri; + + +/** + * The main controller class. Handles all setup and network listeners + * - Distributed ownership control of switch through IControllerRegistryService + */ +public class Controller { + + protected static final Logger log = LoggerFactory.getLogger(Controller.class); + + protected static final OFFactory FACTORY13 = OFFactories.getFactory(OFVersion.OF_13); + protected static final OFFactory FACTORY10 = OFFactories.getFactory(OFVersion.OF_10); + private static final boolean TLS_DISABLED = false; + private static final short MIN_KS_LENGTH = 6; + + protected HashMap controllerNodeIPsCache; + + private ChannelGroup cg; + + // Configuration options + protected List openFlowPorts = ImmutableList.of(6633, 6653); + protected int workerThreads = 16; + + // Start time of the controller + protected long systemStartTime; + + private OpenFlowAgent agent; + + private NioServerSocketChannelFactory execFactory; + + protected String ksLocation; + protected String tsLocation; + protected char[] ksPwd; + protected char[] tsPwd; + protected SSLEngine serverSslEngine; + + // Perf. related configuration + protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024; + private DriverService driverService; + private boolean enableOfTls = TLS_DISABLED; + + // *************** + // Getters/Setters + // *************** + + public OFFactory getOFMessageFactory10() { + return FACTORY10; + } + + + public OFFactory getOFMessageFactory13() { + return FACTORY13; + } + + // ************** + // Initialization + // ************** + + /** + * Tell controller that we're ready to accept switches loop. + */ + public void run() { + + try { + final ServerBootstrap bootstrap = createServerBootStrap(); + + bootstrap.setOption("reuseAddr", true); + bootstrap.setOption("child.keepAlive", true); + bootstrap.setOption("child.tcpNoDelay", true); + bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE); + + ChannelPipelineFactory pfact = + new OpenflowPipelineFactory(this, null, serverSslEngine); + bootstrap.setPipelineFactory(pfact); + cg = new DefaultChannelGroup(); + openFlowPorts.forEach(port -> { + InetSocketAddress sa = new InetSocketAddress(port); + cg.add(bootstrap.bind(sa)); + log.info("Listening for switch connections on {}", sa); + }); + + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + private ServerBootstrap createServerBootStrap() { + + if (workerThreads == 0) { + execFactory = new NioServerSocketChannelFactory( + Executors.newCachedThreadPool(groupedThreads("onos/of", "boss-%d")), + Executors.newCachedThreadPool(groupedThreads("onos/of", "worker-%d"))); + return new ServerBootstrap(execFactory); + } else { + execFactory = new NioServerSocketChannelFactory( + Executors.newCachedThreadPool(groupedThreads("onos/of", "boss-%d")), + Executors.newCachedThreadPool(groupedThreads("onos/of", "worker-%d")), workerThreads); + return new ServerBootstrap(execFactory); + } + } + + public void setConfigParams(Dictionary properties) { + String ports = get(properties, "openflowPorts"); + if (!Strings.isNullOrEmpty(ports)) { + this.openFlowPorts = Stream.of(ports.split(",")) + .map(s -> Integer.parseInt(s)) + .collect(Collectors.toList()); + } + log.debug("OpenFlow ports set to {}", this.openFlowPorts); + + String threads = get(properties, "workerThreads"); + if (!Strings.isNullOrEmpty(threads)) { + this.workerThreads = Integer.parseInt(threads); + } + log.debug("Number of worker threads set to {}", this.workerThreads); + } + + /** + * Initialize internal data structures. + */ + public void init() { + // These data structures are initialized here because other + // module's startUp() might be called before ours + this.controllerNodeIPsCache = new HashMap<>(); + + this.systemStartTime = System.currentTimeMillis(); + + try { + getTlsParameters(); + if (enableOfTls) { + initSsl(); + } + } catch (Exception ex) { + log.error("SSL init failed: {}", ex.getMessage()); + } + + } + + private void getTlsParameters() { + String tempString = System.getProperty("enableOFTLS"); + enableOfTls = Strings.isNullOrEmpty(tempString) ? TLS_DISABLED : Boolean.parseBoolean(tempString); + log.info("OpenFlow Security is {}", enableOfTls ? "enabled" : "disabled"); + if (enableOfTls) { + ksLocation = System.getProperty("javax.net.ssl.keyStore"); + if (Strings.isNullOrEmpty(ksLocation)) { + enableOfTls = TLS_DISABLED; + return; + } + tsLocation = System.getProperty("javax.net.ssl.trustStore"); + if (Strings.isNullOrEmpty(tsLocation)) { + enableOfTls = TLS_DISABLED; + return; + } + ksPwd = System.getProperty("javax.net.ssl.keyStorePassword").toCharArray(); + if (MIN_KS_LENGTH > ksPwd.length) { + enableOfTls = TLS_DISABLED; + return; + } + tsPwd = System.getProperty("javax.net.ssl.trustStorePassword").toCharArray(); + if (MIN_KS_LENGTH > tsPwd.length) { + enableOfTls = TLS_DISABLED; + return; + } + } + } + + private void initSsl() throws Exception { + + TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + KeyStore ts = KeyStore.getInstance("JKS"); + ts.load(new FileInputStream(tsLocation), tsPwd); + tmFactory.init(ts); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(new FileInputStream(ksLocation), ksPwd); + kmf.init(ks, ksPwd); + + SSLContext serverContext = SSLContext.getInstance("TLS"); + serverContext.init(kmf.getKeyManagers(), tmFactory.getTrustManagers(), null); + + serverSslEngine = serverContext.createSSLEngine(); + + serverSslEngine.setNeedClientAuth(true); + serverSslEngine.setUseClientMode(false); + serverSslEngine.setEnabledProtocols(serverSslEngine.getSupportedProtocols()); + serverSslEngine.setEnabledCipherSuites(serverSslEngine.getSupportedCipherSuites()); + serverSslEngine.setEnableSessionCreation(true); + } + + // ************** + // Utility methods + // ************** + + public Map getMemory() { + Map m = new HashMap<>(); + Runtime runtime = Runtime.getRuntime(); + m.put("total", runtime.totalMemory()); + m.put("free", runtime.freeMemory()); + return m; + } + + + public Long getSystemUptime() { + RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean(); + return rb.getUptime(); + } + + public long getSystemStartTime() { + return (this.systemStartTime); + } + + /** + * Forward to the driver-manager to get an IOFSwitch instance. + * + * @param dpid data path id + * @param desc switch description + * @param ofv OpenFlow version + * @return switch instance + */ + protected OpenFlowSwitchDriver getOFSwitchInstance(long dpid, + OFDescStatsReply desc, + OFVersion ofv) { + Dpid dpidObj = new Dpid(dpid); + + Driver driver; + try { + driver = driverService.getDriver(DeviceId.deviceId(Dpid.uri(dpidObj))); + } catch (ItemNotFoundException e) { + driver = driverService.getDriver(desc.getMfrDesc(), desc.getHwDesc(), desc.getSwDesc()); + } + + if (driver != null && driver.hasBehaviour(OpenFlowSwitchDriver.class)) { + Dpid did = new Dpid(dpid); + DefaultDriverHandler handler = + new DefaultDriverHandler(new DefaultDriverData(driver, deviceId(uri(did)))); + OpenFlowSwitchDriver ofSwitchDriver = + driver.createBehaviour(handler, OpenFlowSwitchDriver.class); + ofSwitchDriver.init(did, desc, ofv); + ofSwitchDriver.setAgent(agent); + ofSwitchDriver.setRoleHandler(new RoleManager(ofSwitchDriver)); + log.info("OpenFlow handshaker found for device {}: {}", dpid, ofSwitchDriver); + return ofSwitchDriver; + } + log.error("No OpenFlow driver for {} : {}", dpid, desc); + return null; + + } + + public void start(OpenFlowAgent ag, DriverService driverService) { + log.info("Starting OpenFlow IO"); + this.agent = ag; + this.driverService = driverService; + this.init(); + this.run(); + } + + + public void stop() { + log.info("Stopping OpenFlow IO"); + cg.close(); + execFactory.shutdown(); + } + +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/HandshakeTimeoutException.java b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/HandshakeTimeoutException.java new file mode 100644 index 00000000..bbe307be --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/HandshakeTimeoutException.java @@ -0,0 +1,28 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.openflow.controller.impl; + +/** + * Exception is thrown when the handshake fails to complete. + * before a specified time + * + */ +public class HandshakeTimeoutException extends Exception { + + private static final long serialVersionUID = 6859880268940337312L; + +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/HandshakeTimeoutHandler.java b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/HandshakeTimeoutHandler.java new file mode 100644 index 00000000..fbbe3428 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/HandshakeTimeoutHandler.java @@ -0,0 +1,93 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.openflow.controller.impl; + +import java.util.concurrent.TimeUnit; + +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.channel.SimpleChannelUpstreamHandler; +import org.jboss.netty.util.Timeout; +import org.jboss.netty.util.Timer; +import org.jboss.netty.util.TimerTask; + +/** + * Trigger a timeout if a switch fails to complete handshake soon enough. + */ +public class HandshakeTimeoutHandler + extends SimpleChannelUpstreamHandler { + static final HandshakeTimeoutException EXCEPTION = + new HandshakeTimeoutException(); + + final OFChannelHandler channelHandler; + final Timer timer; + final long timeoutNanos; + volatile Timeout timeout; + + public HandshakeTimeoutHandler(OFChannelHandler channelHandler, + Timer timer, + long timeoutSeconds) { + super(); + this.channelHandler = channelHandler; + this.timer = timer; + this.timeoutNanos = TimeUnit.SECONDS.toNanos(timeoutSeconds); + + } + + @Override + public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) + throws Exception { + if (timeoutNanos > 0) { + timeout = timer.newTimeout(new HandshakeTimeoutTask(ctx), + timeoutNanos, TimeUnit.NANOSECONDS); + } + ctx.sendUpstream(e); + } + + @Override + public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) + throws Exception { + if (timeout != null) { + timeout.cancel(); + timeout = null; + } + } + + private final class HandshakeTimeoutTask implements TimerTask { + + private final ChannelHandlerContext ctx; + + HandshakeTimeoutTask(ChannelHandlerContext ctx) { + this.ctx = ctx; + } + + @Override + public void run(Timeout t) throws Exception { + if (t.isCancelled()) { + return; + } + + if (!ctx.getChannel().isOpen()) { + return; + } + if (!channelHandler.isHandshakeComplete()) { + Channels.fireExceptionCaught(ctx, EXCEPTION); + } + } + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java new file mode 100644 index 00000000..ff92b77e --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java @@ -0,0 +1,1320 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//CHECKSTYLE:OFF +package org.onosproject.openflow.controller.impl; + +import java.io.IOException; +import java.nio.channels.ClosedChannelException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.RejectedExecutionException; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.ExceptionEvent; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; +import org.jboss.netty.handler.timeout.IdleStateEvent; +import org.jboss.netty.handler.timeout.ReadTimeoutException; +import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver; +import org.onosproject.openflow.controller.driver.SwitchStateException; +import org.projectfloodlight.openflow.exceptions.OFParseError; +import org.projectfloodlight.openflow.protocol.OFAsyncGetReply; +import org.projectfloodlight.openflow.protocol.OFBadRequestCode; +import org.projectfloodlight.openflow.protocol.OFBarrierReply; +import org.projectfloodlight.openflow.protocol.OFBarrierRequest; +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFDescStatsRequest; +import org.projectfloodlight.openflow.protocol.OFEchoReply; +import org.projectfloodlight.openflow.protocol.OFEchoRequest; +import org.projectfloodlight.openflow.protocol.OFErrorMsg; +import org.projectfloodlight.openflow.protocol.OFErrorType; +import org.projectfloodlight.openflow.protocol.OFExperimenter; +import org.projectfloodlight.openflow.protocol.OFFactory; +import org.projectfloodlight.openflow.protocol.OFFeaturesReply; +import org.projectfloodlight.openflow.protocol.OFFlowModFailedCode; +import org.projectfloodlight.openflow.protocol.OFFlowRemoved; +import org.projectfloodlight.openflow.protocol.OFGetConfigReply; +import org.projectfloodlight.openflow.protocol.OFGetConfigRequest; +import org.projectfloodlight.openflow.protocol.OFHello; +import org.projectfloodlight.openflow.protocol.OFHelloElem; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFPacketIn; +import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFPortDescStatsRequest; +import org.projectfloodlight.openflow.protocol.OFPortStatus; +import org.projectfloodlight.openflow.protocol.OFQueueGetConfigReply; +import org.projectfloodlight.openflow.protocol.OFRoleReply; +import org.projectfloodlight.openflow.protocol.OFSetConfig; +import org.projectfloodlight.openflow.protocol.OFStatsReply; +import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags; +import org.projectfloodlight.openflow.protocol.OFStatsType; +import org.projectfloodlight.openflow.protocol.OFType; +import org.projectfloodlight.openflow.protocol.OFVersion; +import org.projectfloodlight.openflow.protocol.errormsg.OFBadRequestErrorMsg; +import org.projectfloodlight.openflow.protocol.errormsg.OFFlowModFailedErrorMsg; +import org.projectfloodlight.openflow.types.U32; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Channel handler deals with the switch connection and dispatches + * switch messages to the appropriate locations. + */ +class OFChannelHandler extends IdleStateAwareChannelHandler { + private static final Logger log = LoggerFactory.getLogger(OFChannelHandler.class); + + private static final String RESET_BY_PEER = "Connection reset by peer"; + private static final String BROKEN_PIPE = "Broken pipe"; + + private final Controller controller; + private OpenFlowSwitchDriver sw; + private long thisdpid; // channelHandler cached value of connected switch id + private Channel channel; + // State needs to be volatile because the HandshakeTimeoutHandler + // needs to check if the handshake is complete + private volatile ChannelState state; + + // When a switch with a duplicate dpid is found (i.e we already have a + // connected switch with the same dpid), the new switch is immediately + // disconnected. At that point netty callsback channelDisconnected() which + // proceeds to cleaup switch state - we need to ensure that it does not cleanup + // switch state for the older (still connected) switch + private volatile Boolean duplicateDpidFound; + + // Temporary storage for switch-features and port-description + private OFFeaturesReply featuresReply; + private List portDescReplies; + //private OFPortDescStatsReply portDescReply; + // a concurrent ArrayList to temporarily store port status messages + // before we are ready to deal with them + private final CopyOnWriteArrayList pendingPortStatusMsg; + + //Indicates the openflow version used by this switch + protected OFVersion ofVersion; + protected OFFactory factory13; + protected OFFactory factory10; + + /** transaction Ids to use during handshake. Since only one thread + * calls into an OFChannelHandler instance, we don't need atomic. + * We will count down + */ + private int handshakeTransactionIds = -1; + + /** + * Create a new unconnected OFChannelHandler. + * @param controller parent controller + */ + OFChannelHandler(Controller controller) { + this.controller = controller; + this.state = ChannelState.INIT; + this.pendingPortStatusMsg = new CopyOnWriteArrayList(); + this.portDescReplies = new ArrayList(); + factory13 = controller.getOFMessageFactory13(); + factory10 = controller.getOFMessageFactory10(); + duplicateDpidFound = Boolean.FALSE; + } + + + + // XXX S consider if necessary + public void disconnectSwitch() { + sw.disconnectSwitch(); + } + + + + //************************* + // Channel State Machine + //************************* + + /** + * The state machine for handling the switch/channel state. All state + * transitions should happen from within the state machine (and not from other + * parts of the code) + */ + enum ChannelState { + /** + * Initial state before channel is connected. + */ + INIT(false) { + @Override + void processOFMessage(OFChannelHandler h, OFMessage m) + throws IOException, SwitchStateException { + illegalMessageReceived(h, m); + } + + @Override + void processOFError(OFChannelHandler h, OFErrorMsg m) + throws IOException { + // need to implement since its abstract but it will never + // be called + } + + @Override + void processOFPortStatus(OFChannelHandler h, OFPortStatus m) + throws IOException { + unhandledMessageReceived(h, m); + } + }, + + /** + * We send a OF 1.3 HELLO to the switch and wait for a Hello from the switch. + * Once we receive the reply, we decide on OF 1.3 or 1.0 switch - no other + * protocol version is accepted. + * We send an OFFeaturesRequest depending on the protocol version selected + * Next state is WAIT_FEATURES_REPLY + */ + WAIT_HELLO(false) { + @Override + void processOFHello(OFChannelHandler h, OFHello m) + throws IOException { + // TODO We could check for the optional bitmap, but for now + // we are just checking the version number. + if (m.getVersion().getWireVersion() >= OFVersion.OF_13.getWireVersion()) { + log.debug("Received {} Hello from {} - switching to OF " + + "version 1.3", m.getVersion(), + h.channel.getRemoteAddress()); + h.sendHandshakeHelloMessage(); + h.ofVersion = OFVersion.OF_13; + } else if (m.getVersion().getWireVersion() >= OFVersion.OF_10.getWireVersion()) { + log.debug("Received {} Hello from {} - switching to OF " + + "version 1.0", m.getVersion(), + h.channel.getRemoteAddress()); + OFHello hi = + h.factory10.buildHello() + .setXid(h.handshakeTransactionIds--) + .build(); + h.channel.write(Collections.singletonList(hi)); + h.ofVersion = OFVersion.OF_10; + } else { + log.error("Received Hello of version {} from switch at {}. " + + "This controller works with OF1.0 and OF1.3 " + + "switches. Disconnecting switch ...", + m.getVersion(), h.channel.getRemoteAddress()); + h.channel.disconnect(); + return; + } + h.sendHandshakeFeaturesRequestMessage(); + h.setState(WAIT_FEATURES_REPLY); + } + @Override + void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m) + throws IOException, SwitchStateException { + illegalMessageReceived(h, m); + } + @Override + void processOFStatisticsReply(OFChannelHandler h, + OFStatsReply m) + throws IOException, SwitchStateException { + illegalMessageReceived(h, m); + } + @Override + void processOFError(OFChannelHandler h, OFErrorMsg m) { + logErrorDisconnect(h, m); + } + + @Override + void processOFPortStatus(OFChannelHandler h, OFPortStatus m) + throws IOException { + unhandledMessageReceived(h, m); + } + }, + + + /** + * We are waiting for a features reply message. Once we receive it, the + * behavior depends on whether this is a 1.0 or 1.3 switch. For 1.0, + * we send a SetConfig request, barrier, and GetConfig request and the + * next state is WAIT_CONFIG_REPLY. For 1.3, we send a Port description + * request and the next state is WAIT_PORT_DESC_REPLY. + */ + WAIT_FEATURES_REPLY(false) { + @Override + void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m) + throws IOException { + h.thisdpid = m.getDatapathId().getLong(); + log.debug("Received features reply for switch at {} with dpid {}", + h.getSwitchInfoString(), h.thisdpid); + + h.featuresReply = m; //temp store + if (h.ofVersion == OFVersion.OF_10) { + h.sendHandshakeSetConfig(); + h.setState(WAIT_CONFIG_REPLY); + } else { + //version is 1.3, must get switchport information + h.sendHandshakeOFPortDescRequest(); + h.setState(WAIT_PORT_DESC_REPLY); + } + } + @Override + void processOFStatisticsReply(OFChannelHandler h, + OFStatsReply m) + throws IOException, SwitchStateException { + illegalMessageReceived(h, m); + } + @Override + void processOFError(OFChannelHandler h, OFErrorMsg m) { + logErrorDisconnect(h, m); + } + + @Override + void processOFPortStatus(OFChannelHandler h, OFPortStatus m) + throws IOException { + h.pendingPortStatusMsg.add(m); + } + }, + + /** + * We are waiting for a description of the 1.3 switch ports. + * Once received, we send a SetConfig request + * Next State is WAIT_CONFIG_REPLY + */ + WAIT_PORT_DESC_REPLY(false) { + + @Override + void processOFStatisticsReply(OFChannelHandler h, OFStatsReply m) + throws SwitchStateException { + // Read port description + if (m.getStatsType() != OFStatsType.PORT_DESC) { + log.warn("Expecting port description stats but received stats " + + "type {} from {}. Ignoring ...", m.getStatsType(), + h.channel.getRemoteAddress()); + return; + } + if (m.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { + log.debug("Stats reply indicates more stats from sw {} for " + + "port description", + h.getSwitchInfoString()); + h.portDescReplies.add((OFPortDescStatsReply)m); + return; + } + else { + h.portDescReplies.add((OFPortDescStatsReply)m); + } + //h.portDescReply = (OFPortDescStatsReply) m; // temp store + log.info("Received port desc reply for switch at {}", + h.getSwitchInfoString()); + try { + h.sendHandshakeSetConfig(); + } catch (IOException e) { + log.error("Unable to send setConfig after PortDescReply. " + + "Error: {}", e.getMessage()); + } + h.setState(WAIT_CONFIG_REPLY); + } + + @Override + void processOFError(OFChannelHandler h, OFErrorMsg m) + throws IOException, SwitchStateException { + logErrorDisconnect(h, m); + + } + + @Override + void processOFPortStatus(OFChannelHandler h, OFPortStatus m) + throws IOException, SwitchStateException { + h.pendingPortStatusMsg.add(m); + + } + }, + + /** + * We are waiting for a config reply message. Once we receive it + * we send a DescriptionStatsRequest to the switch. + * Next state: WAIT_DESCRIPTION_STAT_REPLY + */ + WAIT_CONFIG_REPLY(false) { + @Override + void processOFGetConfigReply(OFChannelHandler h, OFGetConfigReply m) + throws IOException { + if (m.getMissSendLen() == 0xffff) { + log.trace("Config Reply from switch {} confirms " + + "miss length set to 0xffff", + h.getSwitchInfoString()); + } else { + // FIXME: we can't really deal with switches that don't send + // full packets. Shouldn't we drop the connection here? + log.warn("Config Reply from switch {} has" + + "miss length set to {}", + h.getSwitchInfoString(), + m.getMissSendLen()); + } + h.sendHandshakeDescriptionStatsRequest(); + h.setState(WAIT_DESCRIPTION_STAT_REPLY); + } + + @Override + void processOFBarrierReply(OFChannelHandler h, OFBarrierReply m) { + // do nothing; + } + + @Override + void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m) + throws IOException, SwitchStateException { + illegalMessageReceived(h, m); + } + @Override + void processOFStatisticsReply(OFChannelHandler h, + OFStatsReply m) + throws IOException, SwitchStateException { + log.error("Received multipart(stats) message sub-type {}", + m.getStatsType()); + illegalMessageReceived(h, m); + } + + @Override + void processOFError(OFChannelHandler h, OFErrorMsg m) { + logErrorDisconnect(h, m); + } + + @Override + void processOFPortStatus(OFChannelHandler h, OFPortStatus m) + throws IOException { + h.pendingPortStatusMsg.add(m); + } + }, + + + /** + * We are waiting for a OFDescriptionStat message from the switch. + * Once we receive any stat message we try to parse it. If it's not + * a description stats message we disconnect. If its the expected + * description stats message, we: + * - use the switch driver to bind the switch and get an IOFSwitch instance + * - setup the IOFSwitch instance + * - add switch controller and send the initial role + * request to the switch. + * Next state: WAIT_INITIAL_ROLE + * In the typical case, where switches support role request messages + * the next state is where we expect the role reply message. + * In the special case that where the switch does not support any kind + * of role request messages, we don't send a role message, but we do + * request mastership from the registry service. This controller + * should become master once we hear back from the registry service. + * All following states will have a h.sw instance! + */ + WAIT_DESCRIPTION_STAT_REPLY(false) { + @Override + void processOFStatisticsReply(OFChannelHandler h, OFStatsReply m) + throws SwitchStateException { + // Read description, if it has been updated + if (m.getStatsType() != OFStatsType.DESC) { + log.warn("Expecting Description stats but received stats " + + "type {} from {}. Ignoring ...", m.getStatsType(), + h.channel.getRemoteAddress()); + return; + } + OFDescStatsReply drep = (OFDescStatsReply) m; + log.info("Received switch description reply {} from switch at {}", + drep, h.channel.getRemoteAddress()); + // Here is where we differentiate between different kinds of switches + h.sw = h.controller.getOFSwitchInstance(h.thisdpid, drep, h.ofVersion); + + h.sw.setOFVersion(h.ofVersion); + h.sw.setFeaturesReply(h.featuresReply); + //h.sw.setPortDescReply(h.portDescReply); + h.sw.setPortDescReplies(h.portDescReplies); + h.sw.setConnected(true); + h.sw.setChannel(h.channel); +// boolean success = h.sw.connectSwitch(); +// +// if (!success) { +// disconnectDuplicate(h); +// return; +// } + // set switch information + + + + log.debug("Switch {} bound to class {}, description {}", + h.sw, h.sw.getClass(), drep); + //Put switch in EQUAL mode until we hear back from the global registry + //log.debug("Setting new switch {} to EQUAL and sending Role request", + // h.sw.getStringId()); + //h.sw.activateEqualSwitch(); + //h.setSwitchRole(RoleState.EQUAL); + + h.sw.startDriverHandshake(); + if (h.sw.isDriverHandshakeComplete()) { + if (!h.sw.connectSwitch()) { + disconnectDuplicate(h); + } + handlePendingPortStatusMessages(h); + h.setState(ACTIVE); + } else { + h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE); + } + + } + + @Override + void processOFError(OFChannelHandler h, OFErrorMsg m) { + logErrorDisconnect(h, m); + } + + @Override + void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m) + throws IOException, SwitchStateException { + illegalMessageReceived(h, m); + } + + @Override + void processOFPortStatus(OFChannelHandler h, OFPortStatus m) + throws IOException { + h.pendingPortStatusMsg.add(m); + } + }, + + + /** + * We are waiting for the respective switch driver to complete its + * configuration. Notice that we do not consider this to be part of the main + * switch-controller handshake. But we do consider it as a step that comes + * before we declare the switch as available to the controller. + * Next State: depends on the role of this controller for this switch - either + * MASTER or EQUAL. + */ + WAIT_SWITCH_DRIVER_SUB_HANDSHAKE(true) { + + @Override + void processOFError(OFChannelHandler h, OFErrorMsg m) + throws IOException { + // will never be called. We override processOFMessage + } + + + + @Override + void processOFMessage(OFChannelHandler h, OFMessage m) + throws IOException, SwitchStateException { + + if (h.sw.isDriverHandshakeComplete()) { + moveToActive(h); + h.state.processOFMessage(h, m); + return; + + } + + if (m.getType() == OFType.ECHO_REQUEST) { + processOFEchoRequest(h, (OFEchoRequest) m); + } else if (m.getType() == OFType.ECHO_REPLY) { + processOFEchoReply(h, (OFEchoReply) m); + } else if (m.getType() == OFType.ROLE_REPLY) { + h.sw.handleRole(m); + } else if (m.getType() == OFType.ERROR) { + if (!h.sw.handleRoleError((OFErrorMsg)m)) { + h.sw.processDriverHandshakeMessage(m); + if (h.sw.isDriverHandshakeComplete()) { + moveToActive(h); + } + } + } else { + if (m.getType() == OFType.EXPERIMENTER && + ((OFExperimenter) m).getExperimenter() == + RoleManager.NICIRA_EXPERIMENTER) { + h.sw.handleNiciraRole(m); + } else { + h.sw.processDriverHandshakeMessage(m); + if (h.sw.isDriverHandshakeComplete()) { + moveToActive(h); + } + } + } + } + + @Override + void processOFPortStatus(OFChannelHandler h, OFPortStatus m) + throws IOException, SwitchStateException { + h.pendingPortStatusMsg.add(m); + } + + private void moveToActive(OFChannelHandler h) { + boolean success = h.sw.connectSwitch(); + handlePendingPortStatusMessages(h); + h.setState(ACTIVE); + if (!success) { + disconnectDuplicate(h); + } + } + + }, + + + /** + * This controller is in MASTER role for this switch. We enter this state + * after requesting and winning control from the global registry. + * The main handshake as well as the switch-driver sub-handshake + * is complete at this point. + * // XXX S reconsider below + * In the (near) future we may deterministically assign controllers to + * switches at startup. + * We only leave this state if the switch disconnects or + * if we send a role request for SLAVE /and/ receive the role reply for + * SLAVE. + */ + ACTIVE(true) { + @Override + void processOFError(OFChannelHandler h, OFErrorMsg m) + throws IOException, SwitchStateException { + // if we get here, then the error message is for something else + if (m.getErrType() == OFErrorType.BAD_REQUEST && + ((OFBadRequestErrorMsg) m).getCode() == + OFBadRequestCode.EPERM) { + // We are the master controller and the switch returned + // a permission error. This is a likely indicator that + // the switch thinks we are slave. Reassert our + // role + // FIXME: this could be really bad during role transitions + // if two controllers are master (even if its only for + // a brief period). We might need to see if these errors + // persist before we reassert + + h.sw.reassertRole(); + } else if (m.getErrType() == OFErrorType.FLOW_MOD_FAILED && + ((OFFlowModFailedErrorMsg) m).getCode() == + OFFlowModFailedCode.ALL_TABLES_FULL) { + h.sw.setTableFull(true); + } else { + logError(h, m); + } + h.dispatchMessage(m); + } + + @Override + void processOFStatisticsReply(OFChannelHandler h, + OFStatsReply m) { + if (m.getStatsType().equals(OFStatsType.PORT_DESC)) { + h.sw.setPortDescReply((OFPortDescStatsReply) m); + } + h.dispatchMessage(m); + } + + @Override + void processOFExperimenter(OFChannelHandler h, OFExperimenter m) + throws SwitchStateException { + h.sw.handleNiciraRole(m); + } + + @Override + void processOFRoleReply(OFChannelHandler h, OFRoleReply m) + throws SwitchStateException { + h.sw.handleRole(m); + } + + @Override + void processOFPortStatus(OFChannelHandler h, OFPortStatus m) + throws SwitchStateException { + handlePortStatusMessage(h, m, true); + //h.dispatchMessage(m); + } + + @Override + void processOFPacketIn(OFChannelHandler h, OFPacketIn m) { +// OFPacketOut out = +// h.sw.factory().buildPacketOut() +// .setXid(m.getXid()) +// .setBufferId(m.getBufferId()).build(); +// h.sw.sendMsg(out); + h.dispatchMessage(m); + } + + @Override + void processOFFlowRemoved(OFChannelHandler h, + OFFlowRemoved m) { + h.dispatchMessage(m); + } + + @Override + void processOFBarrierReply(OFChannelHandler h, OFBarrierReply m) { + h.dispatchMessage(m); + } + + @Override + void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m) { + h.sw.setFeaturesReply(m); + h.dispatchMessage(m); + } + + }; + + private final boolean handshakeComplete; + ChannelState(boolean handshakeComplete) { + this.handshakeComplete = handshakeComplete; + } + + /** + * Is this a state in which the handshake has completed? + * @return true if the handshake is complete + */ + public boolean isHandshakeComplete() { + return handshakeComplete; + } + + /** + * Get a string specifying the switch connection, state, and + * message received. To be used as message for SwitchStateException + * or log messages + * @param h The channel handler (to get switch information_ + * @param m The OFMessage that has just been received + * @param details A string giving more details about the exact nature + * of the problem. + * @return display string + */ + // needs to be protected because enum members are actually subclasses + protected String getSwitchStateMessage(OFChannelHandler h, + OFMessage m, + String details) { + return String.format("Switch: [%s], State: [%s], received: [%s]" + + ", details: %s", + h.getSwitchInfoString(), + this.toString(), + m.getType().toString(), + details); + } + + /** + * We have an OFMessage we didn't expect given the current state and + * we want to treat this as an error. + * We currently throw an exception that will terminate the connection + * However, we could be more forgiving + * @param h the channel handler that received the message + * @param m the message + * @throws SwitchStateException we always throw the exception + */ + // needs to be protected because enum members are actually subclasses + protected void illegalMessageReceived(OFChannelHandler h, OFMessage m) + throws SwitchStateException { + String msg = getSwitchStateMessage(h, m, + "Switch should never send this message in the current state"); + throw new SwitchStateException(msg); + + } + + /** + * We have an OFMessage we didn't expect given the current state and + * we want to ignore the message. + * @param h the channel handler the received the message + * @param m the message + */ + protected void unhandledMessageReceived(OFChannelHandler h, + OFMessage m) { + if (log.isDebugEnabled()) { + String msg = getSwitchStateMessage(h, m, + "Ignoring unexpected message"); + log.debug(msg); + } + } + + /** + * Log an OpenFlow error message from a switch. + * @param h The switch that sent the error + * @param error The error message + */ + protected void logError(OFChannelHandler h, OFErrorMsg error) { + log.error("{} from switch {} in state {}", + error, + h.getSwitchInfoString(), + this.toString()); + } + + /** + * Log an OpenFlow error message from a switch and disconnect the + * channel. + * + * @param h the IO channel for this switch. + * @param error The error message + */ + protected void logErrorDisconnect(OFChannelHandler h, OFErrorMsg error) { + logError(h, error); + h.channel.disconnect(); + } + + /** + * log an error message for a duplicate dpid and disconnect this channel. + * @param h the IO channel for this switch. + */ + protected void disconnectDuplicate(OFChannelHandler h) { + log.error("Duplicated dpid or incompleted cleanup - " + + "disconnecting channel {}", h.getSwitchInfoString()); + h.duplicateDpidFound = Boolean.TRUE; + h.channel.disconnect(); + } + + + + /** + * Handles all pending port status messages before a switch is declared + * activated in MASTER or EQUAL role. Note that since this handling + * precedes the activation (and therefore notification to IOFSwitchListerners) + * the changes to ports will already be visible once the switch is + * activated. As a result, no notifications are sent out for these + * pending portStatus messages. + * + * @param h the channel handler that received the message + */ + protected void handlePendingPortStatusMessages(OFChannelHandler h) { + try { + handlePendingPortStatusMessages(h, 0); + } catch (SwitchStateException e) { + log.error(e.getMessage()); + } + } + + private void handlePendingPortStatusMessages(OFChannelHandler h, int index) + throws SwitchStateException { + if (h.sw == null) { + String msg = "State machine error: switch is null. Should never " + + "happen"; + throw new SwitchStateException(msg); + } + log.info("Processing {} pending port status messages for {}", + h.pendingPortStatusMsg.size(), h.sw.getStringId()); + + ArrayList temp = new ArrayList(); + for (OFPortStatus ps: h.pendingPortStatusMsg) { + temp.add(ps); + handlePortStatusMessage(h, ps, false); + } + // expensive but ok - we don't expect too many port-status messages + // note that we cannot use clear(), because of the reasons below + h.pendingPortStatusMsg.removeAll(temp); + temp.clear(); + // the iterator above takes a snapshot of the list - so while we were + // dealing with the pending port-status messages, we could have received + // newer ones. Handle them recursively, but break the recursion after + // five steps to avoid an attack. + if (!h.pendingPortStatusMsg.isEmpty() && ++index < 5) { + handlePendingPortStatusMessages(h, index); + } + } + + /** + * Handle a port status message. + * + * Handle a port status message by updating the port maps in the + * IOFSwitch instance and notifying Controller about the change so + * it can dispatch a switch update. + * + * @param h The OFChannelHhandler that received the message + * @param m The PortStatus message we received + * @param doNotify if true switch port changed events will be + * dispatched + * @throws SwitchStateException if the switch is not bound to the channel + * + */ + protected void handlePortStatusMessage(OFChannelHandler h, OFPortStatus m, + boolean doNotify) throws SwitchStateException { + if (h.sw == null) { + String msg = getSwitchStateMessage(h, m, + "State machine error: switch is null. Should never " + + "happen"); + throw new SwitchStateException(msg); + } + + h.sw.handleMessage(m); + } + + + /** + * Process an OF message received on the channel and + * update state accordingly. + * + * The main "event" of the state machine. Process the received message, + * send follow up message if required and update state if required. + * + * Switches on the message type and calls more specific event handlers + * for each individual OF message type. If we receive a message that + * is supposed to be sent from a controller to a switch we throw + * a SwitchStateExeption. + * + * The more specific handlers can also throw SwitchStateExceptions + * + * @param h The OFChannelHandler that received the message + * @param m The message we received. + * @throws SwitchStateException if the switch is not bound to the channel + * @throws IOException if unable to send message back to the switch + */ + void processOFMessage(OFChannelHandler h, OFMessage m) + throws IOException, SwitchStateException { + switch(m.getType()) { + case HELLO: + processOFHello(h, (OFHello) m); + break; + case BARRIER_REPLY: + processOFBarrierReply(h, (OFBarrierReply) m); + break; + case ECHO_REPLY: + processOFEchoReply(h, (OFEchoReply) m); + break; + case ECHO_REQUEST: + processOFEchoRequest(h, (OFEchoRequest) m); + break; + case ERROR: + processOFError(h, (OFErrorMsg) m); + break; + case FEATURES_REPLY: + processOFFeaturesReply(h, (OFFeaturesReply) m); + break; + case FLOW_REMOVED: + processOFFlowRemoved(h, (OFFlowRemoved) m); + break; + case GET_CONFIG_REPLY: + processOFGetConfigReply(h, (OFGetConfigReply) m); + break; + case PACKET_IN: + processOFPacketIn(h, (OFPacketIn) m); + break; + case PORT_STATUS: + processOFPortStatus(h, (OFPortStatus) m); + break; + case QUEUE_GET_CONFIG_REPLY: + processOFQueueGetConfigReply(h, (OFQueueGetConfigReply) m); + break; + case STATS_REPLY: // multipart_reply in 1.3 + processOFStatisticsReply(h, (OFStatsReply) m); + break; + case EXPERIMENTER: + processOFExperimenter(h, (OFExperimenter) m); + break; + case ROLE_REPLY: + processOFRoleReply(h, (OFRoleReply) m); + break; + case GET_ASYNC_REPLY: + processOFGetAsyncReply(h, (OFAsyncGetReply) m); + break; + + // The following messages are sent to switches. The controller + // should never receive them + case SET_CONFIG: + case GET_CONFIG_REQUEST: + case PACKET_OUT: + case PORT_MOD: + case QUEUE_GET_CONFIG_REQUEST: + case BARRIER_REQUEST: + case STATS_REQUEST: // multipart request in 1.3 + case FEATURES_REQUEST: + case FLOW_MOD: + case GROUP_MOD: + case TABLE_MOD: + case GET_ASYNC_REQUEST: + case SET_ASYNC: + case METER_MOD: + default: + illegalMessageReceived(h, m); + break; + } + } + + /*----------------------------------------------------------------- + * Default implementation for message handlers in any state. + * + * Individual states must override these if they want a behavior + * that differs from the default. + * + * In general, these handlers simply ignore the message and do + * nothing. + * + * There are some exceptions though, since some messages really + * are handled the same way in every state (e.g., ECHO_REQUST) or + * that are only valid in a single state (e.g., HELLO, GET_CONFIG_REPLY + -----------------------------------------------------------------*/ + + void processOFHello(OFChannelHandler h, OFHello m) + throws IOException, SwitchStateException { + // we only expect hello in the WAIT_HELLO state + log.warn("Received Hello outside WAIT_HELLO state; switch {} is not complaint.", + h.channel.getRemoteAddress()); + } + + void processOFBarrierReply(OFChannelHandler h, OFBarrierReply m) + throws IOException { + // Silently ignore. + } + + void processOFEchoRequest(OFChannelHandler h, OFEchoRequest m) + throws IOException { + if (h.ofVersion == null) { + log.error("No OF version set for {}. Not sending Echo REPLY", + h.channel.getRemoteAddress()); + return; + } + OFFactory factory = (h.ofVersion == OFVersion.OF_13) ? + h.controller.getOFMessageFactory13() : h.controller.getOFMessageFactory10(); + OFEchoReply reply = factory + .buildEchoReply() + .setXid(m.getXid()) + .setData(m.getData()) + .build(); + h.channel.write(Collections.singletonList(reply)); + } + + void processOFEchoReply(OFChannelHandler h, OFEchoReply m) + throws IOException { + // Do nothing with EchoReplies !! + } + + // no default implementation for OFError + // every state must override it + abstract void processOFError(OFChannelHandler h, OFErrorMsg m) + throws IOException, SwitchStateException; + + + void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m) + throws IOException, SwitchStateException { + unhandledMessageReceived(h, m); + } + + void processOFFlowRemoved(OFChannelHandler h, OFFlowRemoved m) + throws IOException { + unhandledMessageReceived(h, m); + } + + void processOFGetConfigReply(OFChannelHandler h, OFGetConfigReply m) + throws IOException, SwitchStateException { + // we only expect config replies in the WAIT_CONFIG_REPLY state + illegalMessageReceived(h, m); + } + + void processOFPacketIn(OFChannelHandler h, OFPacketIn m) + throws IOException { + unhandledMessageReceived(h, m); + } + + // no default implementation. Every state needs to handle it. + abstract void processOFPortStatus(OFChannelHandler h, OFPortStatus m) + throws IOException, SwitchStateException; + + void processOFQueueGetConfigReply(OFChannelHandler h, + OFQueueGetConfigReply m) + throws IOException { + unhandledMessageReceived(h, m); + } + + void processOFStatisticsReply(OFChannelHandler h, OFStatsReply m) + throws IOException, SwitchStateException { + unhandledMessageReceived(h, m); + } + + void processOFExperimenter(OFChannelHandler h, OFExperimenter m) + throws IOException, SwitchStateException { + // TODO: it might make sense to parse the vendor message here + // into the known vendor messages we support and then call more + // specific event handlers + unhandledMessageReceived(h, m); + } + + void processOFRoleReply(OFChannelHandler h, OFRoleReply m) + throws SwitchStateException, IOException { + unhandledMessageReceived(h, m); + } + + void processOFGetAsyncReply(OFChannelHandler h, + OFAsyncGetReply m) { + unhandledMessageReceived(h, m); + } + + } + + + + //************************* + // Channel handler methods + //************************* + + @Override + public void channelConnected(ChannelHandlerContext ctx, + ChannelStateEvent e) throws Exception { + channel = e.getChannel(); + log.info("New switch connection from {}", + channel.getRemoteAddress()); + /* + hack to wait for the switch to tell us what it's + max version is. This is not spec compliant and should + be removed as soon as switches behave better. + */ + //sendHandshakeHelloMessage(); + setState(ChannelState.WAIT_HELLO); + } + + @Override + public void channelDisconnected(ChannelHandlerContext ctx, + ChannelStateEvent e) throws Exception { + log.info("Switch disconnected callback for sw:{}. Cleaning up ...", + getSwitchInfoString()); + if (thisdpid != 0) { + if (!duplicateDpidFound) { + // if the disconnected switch (on this ChannelHandler) + // was not one with a duplicate-dpid, it is safe to remove all + // state for it at the controller. Notice that if the disconnected + // switch was a duplicate-dpid, calling the method below would clear + // all state for the original switch (with the same dpid), + // which we obviously don't want. + log.info("{}:removal called", getSwitchInfoString()); + if (sw != null) { + sw.removeConnectedSwitch(); + } + } else { + // A duplicate was disconnected on this ChannelHandler, + // this is the same switch reconnecting, but the original state was + // not cleaned up - XXX check liveness of original ChannelHandler + log.info("{}:duplicate found", getSwitchInfoString()); + duplicateDpidFound = Boolean.FALSE; + } + } else { + log.warn("no dpid in channelHandler registered for " + + "disconnected switch {}", getSwitchInfoString()); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) + throws Exception { + if (e.getCause() instanceof ReadTimeoutException) { + // switch timeout + log.error("Disconnecting switch {} due to read timeout", + getSwitchInfoString()); + ctx.getChannel().close(); + } else if (e.getCause() instanceof HandshakeTimeoutException) { + log.error("Disconnecting switch {}: failed to complete handshake", + getSwitchInfoString()); + ctx.getChannel().close(); + } else if (e.getCause() instanceof ClosedChannelException) { + log.debug("Channel for sw {} already closed", getSwitchInfoString()); + } else if (e.getCause() instanceof IOException) { + if (!e.getCause().getMessage().equals(RESET_BY_PEER) && + !e.getCause().getMessage().equals(BROKEN_PIPE)) { + log.error("Disconnecting switch {} due to IO Error: {}", + getSwitchInfoString(), e.getCause().getMessage()); + if (log.isDebugEnabled()) { + // still print stack trace if debug is enabled + log.debug("StackTrace for previous Exception: ", e.getCause()); + } + } + ctx.getChannel().close(); + } else if (e.getCause() instanceof SwitchStateException) { + log.error("Disconnecting switch {} due to switch state error: {}", + getSwitchInfoString(), e.getCause().getMessage()); + if (log.isDebugEnabled()) { + // still print stack trace if debug is enabled + log.debug("StackTrace for previous Exception: ", e.getCause()); + } + ctx.getChannel().close(); + } else if (e.getCause() instanceof OFParseError) { + log.error("Disconnecting switch " + + getSwitchInfoString() + + " due to message parse failure", + e.getCause()); + ctx.getChannel().close(); + } else if (e.getCause() instanceof RejectedExecutionException) { + log.warn("Could not process message: queue full"); + } else { + log.error("Error while processing message from switch " + + getSwitchInfoString() + + "state " + this.state, e.getCause()); + ctx.getChannel().close(); + } + } + + @Override + public String toString() { + return getSwitchInfoString(); + } + + @Override + public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) + throws Exception { + OFFactory factory = (ofVersion == OFVersion.OF_13) ? factory13 : factory10; + OFMessage m = factory.buildEchoRequest().build(); + log.debug("Sending Echo Request on idle channel: {}", + e.getChannel().getPipeline().getLast().toString()); + e.getChannel().write(Collections.singletonList(m)); + // XXX S some problems here -- echo request has no transaction id, and + // echo reply is not correlated to the echo request. + } + + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) + throws Exception { + if (e.getMessage() instanceof List) { + @SuppressWarnings("unchecked") + List msglist = (List) e.getMessage(); + + + for (OFMessage ofm : msglist) { + // Do the actual packet processing + state.processOFMessage(this, ofm); + } + } else { + state.processOFMessage(this, (OFMessage) e.getMessage()); + } + } + + + + //************************* + // Channel utility methods + //************************* + + /** + * Is this a state in which the handshake has completed? + * @return true if the handshake is complete + */ + public boolean isHandshakeComplete() { + return this.state.isHandshakeComplete(); + } + + private void dispatchMessage(OFMessage m) { + sw.handleMessage(m); + } + + /** + * Return a string describing this switch based on the already available + * information (DPID and/or remote socket). + * @return display string + */ + private String getSwitchInfoString() { + if (sw != null) { + return sw.toString(); + } + String channelString; + if (channel == null || channel.getRemoteAddress() == null) { + channelString = "?"; + } else { + channelString = channel.getRemoteAddress().toString(); + } + String dpidString; + if (featuresReply == null) { + dpidString = "?"; + } else { + dpidString = featuresReply.getDatapathId().toString(); + } + return String.format("[%s DPID[%s]]", channelString, dpidString); + } + + /** + * Update the channels state. Only called from the state machine. + * TODO: enforce restricted state transitions + * @param state + */ + private void setState(ChannelState state) { + this.state = state; + } + + /** + * Send hello message to the switch using the handshake transactions ids. + * @throws IOException + */ + private void sendHandshakeHelloMessage() throws IOException { + // The OF protocol requires us to start things off by sending the highest + // version of the protocol supported. + + // bitmap represents OF1.0 (ofp_version=0x01) and OF1.3 (ofp_version=0x04) + // see Sec. 7.5.1 of the OF1.3.4 spec + U32 bitmap = U32.ofRaw(0x00000012); + OFHelloElem hem = factory13.buildHelloElemVersionbitmap() + .setBitmaps(Collections.singletonList(bitmap)) + .build(); + OFMessage.Builder mb = factory13.buildHello() + .setXid(this.handshakeTransactionIds--) + .setElements(Collections.singletonList(hem)); + log.info("Sending OF_13 Hello to {}", channel.getRemoteAddress()); + channel.write(Collections.singletonList(mb.build())); + } + + /** + * Send featuresRequest msg to the switch using the handshake transactions ids. + * @throws IOException + */ + private void sendHandshakeFeaturesRequestMessage() throws IOException { + OFFactory factory = (ofVersion == OFVersion.OF_13) ? factory13 : factory10; + OFMessage m = factory.buildFeaturesRequest() + .setXid(this.handshakeTransactionIds--) + .build(); + channel.write(Collections.singletonList(m)); + } + + /** + * Send the configuration requests to tell the switch we want full + * packets. + * @throws IOException + */ + private void sendHandshakeSetConfig() throws IOException { + OFFactory factory = (ofVersion == OFVersion.OF_13) ? factory13 : factory10; + //log.debug("Sending CONFIG_REQUEST to {}", channel.getRemoteAddress()); + List msglist = new ArrayList(3); + + // Ensure we receive the full packet via PacketIn + // FIXME: We don't set the reassembly flags. + // Only send config to switches to send full packets, if they have a buffer. + // Saves a packet & OFSetConfig can't be handled by certain switches. + if(this.featuresReply.getNBuffers() > 0) { + OFSetConfig sc = factory + .buildSetConfig() + .setMissSendLen((short) 0xffff) + .setXid(this.handshakeTransactionIds--) + .build(); + msglist.add(sc); + } + + // Barrier + OFBarrierRequest br = factory + .buildBarrierRequest() + .setXid(this.handshakeTransactionIds--) + .build(); + msglist.add(br); + + // Verify (need barrier?) + OFGetConfigRequest gcr = factory + .buildGetConfigRequest() + .setXid(this.handshakeTransactionIds--) + .build(); + msglist.add(gcr); + channel.write(msglist); + } + + /** + * send a description state request. + * @throws IOException + */ + private void sendHandshakeDescriptionStatsRequest() throws IOException { + // Get Description to set switch-specific flags + OFFactory factory = (ofVersion == OFVersion.OF_13) ? factory13 : factory10; + OFDescStatsRequest dreq = factory + .buildDescStatsRequest() + .setXid(handshakeTransactionIds--) + .build(); + channel.write(Collections.singletonList(dreq)); + } + + private void sendHandshakeOFPortDescRequest() throws IOException { + // Get port description for 1.3 switch + OFPortDescStatsRequest preq = factory13 + .buildPortDescStatsRequest() + .setXid(handshakeTransactionIds--) + .build(); + channel.write(Collections.singletonList(preq)); + } + + ChannelState getStateForTesting() { + return state; + } + +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFMessageDecoder.java b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFMessageDecoder.java new file mode 100644 index 00000000..f52d27e5 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFMessageDecoder.java @@ -0,0 +1,55 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.openflow.controller.impl; + + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.projectfloodlight.openflow.protocol.OFFactories; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFMessageReader; + +/** + * Decode an openflow message from a Channel, for use in a netty pipeline. + */ +public class OFMessageDecoder extends FrameDecoder { + + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, + ChannelBuffer buffer) throws Exception { + if (!channel.isConnected()) { + // In testing, I see decode being called AFTER decode last. + // This check avoids that from reading corrupted frames + return null; + } + + // Note that a single call to decode results in reading a single + // OFMessage from the channel buffer, which is passed on to, and processed + // by, the controller (in OFChannelHandler). + // This is different from earlier behavior (with the original openflowj), + // where we parsed all the messages in the buffer, before passing on + // a list of the parsed messages to the controller. + // The performance *may or may not* not be as good as before. + OFMessageReader reader = OFFactories.getGenericReader(); + OFMessage message = reader.readFrom(buffer); + + return message; + } + +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFMessageEncoder.java b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFMessageEncoder.java new file mode 100644 index 00000000..4c1b16fe --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFMessageEncoder.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.openflow.controller.impl; + +import java.util.List; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; +import org.projectfloodlight.openflow.protocol.OFMessage; + +/** + * Encode an openflow message for output into a ChannelBuffer, for use in a + * netty pipeline. + */ +public class OFMessageEncoder extends OneToOneEncoder { + + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, + Object msg) throws Exception { + if (!(msg instanceof List)) { + return msg; + } + + @SuppressWarnings("unchecked") + List msglist = (List) msg; + /* XXX S can't get length of OFMessage in loxigen's openflowj?? + int size = 0; + for (OFMessage ofm : msglist) { + size += ofm.getLengthU(); + }*/ + + ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + + for (OFMessage ofm : msglist) { + if (ofm != null) { + ofm.writeTo(buf); + } + } + return buf; + } + +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java new file mode 100644 index 00000000..b97c3362 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java @@ -0,0 +1,633 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.impl; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Modified; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onosproject.cfg.ComponentConfigService; +import org.onosproject.net.driver.DefaultDriverProviderService; +import org.onosproject.net.driver.DriverService; +import org.onosproject.openflow.controller.DefaultOpenFlowPacketContext; +import org.onosproject.openflow.controller.Dpid; +import org.onosproject.openflow.controller.OpenFlowController; +import org.onosproject.openflow.controller.OpenFlowEventListener; +import org.onosproject.openflow.controller.OpenFlowPacketContext; +import org.onosproject.openflow.controller.OpenFlowSwitch; +import org.onosproject.openflow.controller.OpenFlowSwitchListener; +import org.onosproject.openflow.controller.PacketListener; +import org.onosproject.openflow.controller.RoleState; +import org.onosproject.openflow.controller.driver.OpenFlowAgent; +import org.osgi.service.component.ComponentContext; +import org.projectfloodlight.openflow.protocol.OFCalientFlowStatsEntry; +import org.projectfloodlight.openflow.protocol.OFCalientFlowStatsReply; +import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus; +import org.projectfloodlight.openflow.protocol.OFExperimenter; +import org.projectfloodlight.openflow.protocol.OFFactories; +import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; +import org.projectfloodlight.openflow.protocol.OFFlowStatsReply; +import org.projectfloodlight.openflow.protocol.OFTableStatsEntry; +import org.projectfloodlight.openflow.protocol.OFTableStatsReply; +import org.projectfloodlight.openflow.protocol.OFGroupDescStatsEntry; +import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFGroupStatsEntry; +import org.projectfloodlight.openflow.protocol.OFGroupStatsReply; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFPacketIn; +import org.projectfloodlight.openflow.protocol.OFPortDesc; +import org.projectfloodlight.openflow.protocol.OFPortStatsEntry; +import org.projectfloodlight.openflow.protocol.OFPortStatsReply; +import org.projectfloodlight.openflow.protocol.OFPortStatus; +import org.projectfloodlight.openflow.protocol.OFStatsReply; +import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags; +import org.projectfloodlight.openflow.protocol.action.OFActionOutput; +import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import static org.onlab.util.Tools.groupedThreads; + +@Component(immediate = true) +@Service +public class OpenFlowControllerImpl implements OpenFlowController { + private static final String DEFAULT_OFPORT = "6633,6653"; + private static final int DEFAULT_WORKER_THREADS = 16; + + private static final Logger log = + LoggerFactory.getLogger(OpenFlowControllerImpl.class); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DriverService driverService; + + // References exists merely for sequencing purpose to assure drivers are loaded + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DefaultDriverProviderService defaultDriverProviderService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ComponentConfigService cfgService; + + @Property(name = "openflowPorts", value = DEFAULT_OFPORT, + label = "Port numbers (comma separated) used by OpenFlow protocol; default is 6633,6653") + private String openflowPorts = DEFAULT_OFPORT; + + @Property(name = "workerThreads", intValue = DEFAULT_WORKER_THREADS, + label = "Number of controller worker threads; default is 16") + private int workerThreads = DEFAULT_WORKER_THREADS; + + protected ExecutorService executorMsgs = + Executors.newFixedThreadPool(32, groupedThreads("onos/of", "event-stats-%d")); + + private final ExecutorService executorBarrier = + Executors.newFixedThreadPool(4, groupedThreads("onos/of", "event-barrier-%d")); + + protected ConcurrentHashMap connectedSwitches = + new ConcurrentHashMap<>(); + protected ConcurrentHashMap activeMasterSwitches = + new ConcurrentHashMap<>(); + protected ConcurrentHashMap activeEqualSwitches = + new ConcurrentHashMap<>(); + + protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent(); + protected Set ofSwitchListener = new CopyOnWriteArraySet<>(); + + protected Multimap ofPacketListener = + ArrayListMultimap.create(); + + protected Set ofEventListener = new CopyOnWriteArraySet<>(); + + protected Multimap fullFlowStats = + ArrayListMultimap.create(); + + protected Multimap fullTableStats = + ArrayListMultimap.create(); + + protected Multimap fullGroupStats = + ArrayListMultimap.create(); + + protected Multimap fullGroupDescStats = + ArrayListMultimap.create(); + + protected Multimap fullPortStats = + ArrayListMultimap.create(); + + private final Controller ctrl = new Controller(); + + @Activate + public void activate(ComponentContext context) { + cfgService.registerProperties(getClass()); + ctrl.setConfigParams(context.getProperties()); + ctrl.start(agent, driverService); + } + + @Deactivate + public void deactivate() { + cfgService.unregisterProperties(getClass(), false); + ctrl.stop(); + } + + @Modified + public void modified(ComponentContext context) { + ctrl.stop(); + ctrl.setConfigParams(context.getProperties()); + ctrl.start(agent, driverService); + } + + @Override + public Iterable getSwitches() { + return connectedSwitches.values(); + } + + @Override + public Iterable getMasterSwitches() { + return activeMasterSwitches.values(); + } + + @Override + public Iterable getEqualSwitches() { + return activeEqualSwitches.values(); + } + + @Override + public OpenFlowSwitch getSwitch(Dpid dpid) { + return connectedSwitches.get(dpid); + } + + @Override + public OpenFlowSwitch getMasterSwitch(Dpid dpid) { + return activeMasterSwitches.get(dpid); + } + + @Override + public OpenFlowSwitch getEqualSwitch(Dpid dpid) { + return activeEqualSwitches.get(dpid); + } + + @Override + public void addListener(OpenFlowSwitchListener listener) { + if (!ofSwitchListener.contains(listener)) { + this.ofSwitchListener.add(listener); + } + } + + @Override + public void removeListener(OpenFlowSwitchListener listener) { + this.ofSwitchListener.remove(listener); + } + + @Override + public void addPacketListener(int priority, PacketListener listener) { + ofPacketListener.put(priority, listener); + } + + @Override + public void removePacketListener(PacketListener listener) { + ofPacketListener.values().remove(listener); + } + + @Override + public void addEventListener(OpenFlowEventListener listener) { + ofEventListener.add(listener); + } + + @Override + public void removeEventListener(OpenFlowEventListener listener) { + ofEventListener.remove(listener); + } + + @Override + public void write(Dpid dpid, OFMessage msg) { + this.getSwitch(dpid).sendMsg(msg); + } + + @Override + public void processPacket(Dpid dpid, OFMessage msg) { + Collection flowStats; + Collection tableStats; + Collection groupStats; + Collection groupDescStats; + Collection portStats; + + switch (msg.getType()) { + case PORT_STATUS: + for (OpenFlowSwitchListener l : ofSwitchListener) { + l.portChanged(dpid, (OFPortStatus) msg); + } + break; + case FEATURES_REPLY: + for (OpenFlowSwitchListener l : ofSwitchListener) { + l.switchChanged(dpid); + } + break; + case PACKET_IN: + OpenFlowPacketContext pktCtx = DefaultOpenFlowPacketContext + .packetContextFromPacketIn(this.getSwitch(dpid), + (OFPacketIn) msg); + for (PacketListener p : ofPacketListener.values()) { + p.handlePacket(pktCtx); + } + break; + // TODO: Consider using separate threadpool for sensitive messages. + // ie. Back to back error could cause us to starve. + case FLOW_REMOVED: + case ERROR: + executorMsgs.submit(new OFMessageHandler(dpid, msg)); + break; + case STATS_REPLY: + OFStatsReply reply = (OFStatsReply) msg; + switch (reply.getStatsType()) { + case PORT_DESC: + for (OpenFlowSwitchListener l : ofSwitchListener) { + l.switchChanged(dpid); + } + break; + case FLOW: + flowStats = publishFlowStats(dpid, (OFFlowStatsReply) reply); + if (flowStats != null) { + OFFlowStatsReply.Builder rep = + OFFactories.getFactory(msg.getVersion()).buildFlowStatsReply(); + rep.setEntries(Lists.newLinkedList(flowStats)); + rep.setXid(reply.getXid()); + executorMsgs.submit(new OFMessageHandler(dpid, rep.build())); + } + break; + case TABLE: + tableStats = publishTableStats(dpid, (OFTableStatsReply) reply); + if (tableStats != null) { + OFTableStatsReply.Builder rep = + OFFactories.getFactory(msg.getVersion()).buildTableStatsReply(); + rep.setEntries(Lists.newLinkedList(tableStats)); + executorMsgs.submit(new OFMessageHandler(dpid, rep.build())); + } + break; + case GROUP: + groupStats = publishGroupStats(dpid, (OFGroupStatsReply) reply); + if (groupStats != null) { + OFGroupStatsReply.Builder rep = + OFFactories.getFactory(msg.getVersion()).buildGroupStatsReply(); + rep.setEntries(Lists.newLinkedList(groupStats)); + rep.setXid(reply.getXid()); + executorMsgs.submit(new OFMessageHandler(dpid, rep.build())); + } + break; + case GROUP_DESC: + groupDescStats = publishGroupDescStats(dpid, + (OFGroupDescStatsReply) reply); + if (groupDescStats != null) { + OFGroupDescStatsReply.Builder rep = + OFFactories.getFactory(msg.getVersion()).buildGroupDescStatsReply(); + rep.setEntries(Lists.newLinkedList(groupDescStats)); + rep.setXid(reply.getXid()); + executorMsgs.submit(new OFMessageHandler(dpid, rep.build())); + } + break; + case PORT: + executorMsgs.submit(new OFMessageHandler(dpid, reply)); + break; + case METER: + executorMsgs.submit(new OFMessageHandler(dpid, reply)); + break; + case EXPERIMENTER: + if (reply instanceof OFCalientFlowStatsReply) { + // Convert Calient flow statistics to regular flow stats + // TODO: parse remaining fields such as power levels etc. when we have proper monitoring API + OFFlowStatsReply.Builder fsr = getSwitch(dpid).factory().buildFlowStatsReply(); + List entries = new LinkedList<>(); + for (OFCalientFlowStatsEntry entry : ((OFCalientFlowStatsReply) msg).getEntries()) { + + // Single instruction, i.e., output to port + OFActionOutput action = OFFactories + .getFactory(msg.getVersion()) + .actions() + .buildOutput() + .setPort(entry.getOutPort()) + .build(); + OFInstruction instruction = OFFactories + .getFactory(msg.getVersion()) + .instructions() + .applyActions(Collections.singletonList(action)); + OFFlowStatsEntry fs = getSwitch(dpid).factory().buildFlowStatsEntry() + .setMatch(entry.getMatch()) + .setTableId(entry.getTableId()) + .setDurationSec(entry.getDurationSec()) + .setDurationNsec(entry.getDurationNsec()) + .setPriority(entry.getPriority()) + .setIdleTimeout(entry.getIdleTimeout()) + .setHardTimeout(entry.getHardTimeout()) + .setFlags(entry.getFlags()) + .setCookie(entry.getCookie()) + .setInstructions(Collections.singletonList(instruction)) + .build(); + entries.add(fs); + } + fsr.setEntries(entries); + + flowStats = publishFlowStats(dpid, fsr.build()); + if (flowStats != null) { + OFFlowStatsReply.Builder rep = + OFFactories.getFactory(msg.getVersion()).buildFlowStatsReply(); + rep.setEntries(Lists.newLinkedList(flowStats)); + executorMsgs.submit(new OFMessageHandler(dpid, rep.build())); + } + } else { + executorMsgs.submit(new OFMessageHandler(dpid, reply)); + } + break; + default: + log.warn("Discarding unknown stats reply type {}", reply.getStatsType()); + break; + } + break; + case BARRIER_REPLY: + executorBarrier.submit(new OFMessageHandler(dpid, msg)); + break; + case EXPERIMENTER: + long experimenter = ((OFExperimenter) msg).getExperimenter(); + if (experimenter == 0x748771) { + // LINC-OE port stats + OFCircuitPortStatus circuitPortStatus = (OFCircuitPortStatus) msg; + OFPortStatus.Builder portStatus = this.getSwitch(dpid).factory().buildPortStatus(); + OFPortDesc.Builder portDesc = this.getSwitch(dpid).factory().buildPortDesc(); + portDesc.setPortNo(circuitPortStatus.getPortNo()) + .setHwAddr(circuitPortStatus.getHwAddr()) + .setName(circuitPortStatus.getName()) + .setConfig(circuitPortStatus.getConfig()) + .setState(circuitPortStatus.getState()); + portStatus.setReason(circuitPortStatus.getReason()).setDesc(portDesc.build()); + for (OpenFlowSwitchListener l : ofSwitchListener) { + l.portChanged(dpid, portStatus.build()); + } + } else { + log.warn("Handling experimenter type {} not yet implemented", + ((OFExperimenter) msg).getExperimenter(), msg); + } + break; + default: + log.warn("Handling message type {} not yet implemented {}", + msg.getType(), msg); + } + } + + private synchronized Collection publishFlowStats(Dpid dpid, + OFFlowStatsReply reply) { + //TODO: Get rid of synchronized + fullFlowStats.putAll(dpid, reply.getEntries()); + if (!reply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { + return fullFlowStats.removeAll(dpid); + } + return null; + } + + private synchronized Collection publishTableStats(Dpid dpid, + OFTableStatsReply reply) { + //TODO: Get rid of synchronized + fullTableStats.putAll(dpid, reply.getEntries()); + if (!reply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { + return fullTableStats.removeAll(dpid); + } + return null; + } + + private synchronized Collection publishGroupStats(Dpid dpid, + OFGroupStatsReply reply) { + //TODO: Get rid of synchronized + fullGroupStats.putAll(dpid, reply.getEntries()); + if (!reply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { + return fullGroupStats.removeAll(dpid); + } + return null; + } + + private synchronized Collection publishGroupDescStats(Dpid dpid, + OFGroupDescStatsReply reply) { + //TODO: Get rid of synchronized + fullGroupDescStats.putAll(dpid, reply.getEntries()); + if (!reply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { + return fullGroupDescStats.removeAll(dpid); + } + return null; + } + + private synchronized Collection publishPortStats(Dpid dpid, + OFPortStatsReply reply) { + fullPortStats.putAll(dpid, reply.getEntries()); + if (!reply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { + return fullPortStats.removeAll(dpid); + } + return null; + } + + @Override + public void setRole(Dpid dpid, RoleState role) { + final OpenFlowSwitch sw = getSwitch(dpid); + if (sw == null) { + log.debug("Switch not connected. Ignoring setRole({}, {})", dpid, role); + return; + } + sw.setRole(role); + } + + /** + * Implementation of an OpenFlow Agent which is responsible for + * keeping track of connected switches and the state in which + * they are. + */ + public class OpenFlowSwitchAgent implements OpenFlowAgent { + + private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class); + private final Lock switchLock = new ReentrantLock(); + + @Override + public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) { + + if (connectedSwitches.get(dpid) != null) { + log.error("Trying to add connectedSwitch but found a previous " + + "value for dpid: {}", dpid); + return false; + } else { + log.info("Added switch {}", dpid); + connectedSwitches.put(dpid, sw); + for (OpenFlowSwitchListener l : ofSwitchListener) { + l.switchAdded(dpid); + } + return true; + } + } + + @Override + public boolean validActivation(Dpid dpid) { + if (connectedSwitches.get(dpid) == null) { + log.error("Trying to activate switch but is not in " + + "connected switches: dpid {}. Aborting ..", + dpid); + return false; + } + if (activeMasterSwitches.get(dpid) != null || + activeEqualSwitches.get(dpid) != null) { + log.error("Trying to activate switch but it is already " + + "activated: dpid {}. Found in activeMaster: {} " + + "Found in activeEqual: {}. Aborting ..", + dpid, + (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y', + (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'); + return false; + } + return true; + } + + + @Override + public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw) { + switchLock.lock(); + try { + if (!validActivation(dpid)) { + return false; + } + activeMasterSwitches.put(dpid, sw); + return true; + } finally { + switchLock.unlock(); + } + } + + @Override + public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw) { + switchLock.lock(); + try { + if (!validActivation(dpid)) { + return false; + } + activeEqualSwitches.put(dpid, sw); + log.info("Added Activated EQUAL Switch {}", dpid); + return true; + } finally { + switchLock.unlock(); + } + } + + @Override + public void transitionToMasterSwitch(Dpid dpid) { + switchLock.lock(); + try { + if (activeMasterSwitches.containsKey(dpid)) { + return; + } + OpenFlowSwitch sw = activeEqualSwitches.remove(dpid); + if (sw == null) { + sw = getSwitch(dpid); + if (sw == null) { + log.error("Transition to master called on sw {}, but switch " + + "was not found in controller-cache", dpid); + return; + } + } + log.info("Transitioned switch {} to MASTER", dpid); + activeMasterSwitches.put(dpid, sw); + } finally { + switchLock.unlock(); + } + } + + + @Override + public void transitionToEqualSwitch(Dpid dpid) { + switchLock.lock(); + try { + if (activeEqualSwitches.containsKey(dpid)) { + return; + } + OpenFlowSwitch sw = activeMasterSwitches.remove(dpid); + if (sw == null) { + sw = getSwitch(dpid); + if (sw == null) { + log.error("Transition to equal called on sw {}, but switch " + + "was not found in controller-cache", dpid); + return; + } + } + log.info("Transitioned switch {} to EQUAL", dpid); + activeEqualSwitches.put(dpid, sw); + } finally { + switchLock.unlock(); + } + + } + + @Override + public void removeConnectedSwitch(Dpid dpid) { + connectedSwitches.remove(dpid); + OpenFlowSwitch sw = activeMasterSwitches.remove(dpid); + if (sw == null) { + log.debug("sw was null for {}", dpid); + sw = activeEqualSwitches.remove(dpid); + } + for (OpenFlowSwitchListener l : ofSwitchListener) { + l.switchRemoved(dpid); + } + } + + @Override + public void processMessage(Dpid dpid, OFMessage m) { + processPacket(dpid, m); + } + + @Override + public void returnRoleReply(Dpid dpid, RoleState requested, RoleState response) { + for (OpenFlowSwitchListener l : ofSwitchListener) { + l.receivedRoleReply(dpid, requested, response); + } + } + } + + protected final class OFMessageHandler implements Runnable { + + protected final OFMessage msg; + protected final Dpid dpid; + + public OFMessageHandler(Dpid dpid, OFMessage msg) { + this.msg = msg; + this.dpid = dpid; + } + + @Override + public void run() { + for (OpenFlowEventListener listener : ofEventListener) { + listener.handleMessage(dpid, msg); + } + } + + } + +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenflowPipelineFactory.java b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenflowPipelineFactory.java new file mode 100644 index 00000000..1467520d --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenflowPipelineFactory.java @@ -0,0 +1,93 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.openflow.controller.impl; + +import java.util.concurrent.ThreadPoolExecutor; + +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.handler.execution.ExecutionHandler; +import org.jboss.netty.handler.timeout.IdleStateHandler; +import org.jboss.netty.handler.timeout.ReadTimeoutHandler; +import org.jboss.netty.util.ExternalResourceReleasable; +import org.jboss.netty.util.HashedWheelTimer; +import org.jboss.netty.util.Timer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.SSLEngine; + +/** + * Creates a ChannelPipeline for a server-side openflow channel. + */ +public class OpenflowPipelineFactory + implements ChannelPipelineFactory, ExternalResourceReleasable { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final SSLEngine sslEngine; + protected Controller controller; + protected ThreadPoolExecutor pipelineExecutor; + protected Timer timer; + protected IdleStateHandler idleHandler; + protected ReadTimeoutHandler readTimeoutHandler; + + public OpenflowPipelineFactory(Controller controller, + ThreadPoolExecutor pipelineExecutor, + SSLEngine sslEngine) { + super(); + this.controller = controller; + this.pipelineExecutor = pipelineExecutor; + this.timer = new HashedWheelTimer(); + this.idleHandler = new IdleStateHandler(timer, 20, 25, 0); + this.readTimeoutHandler = new ReadTimeoutHandler(timer, 30); + this.sslEngine = sslEngine; + } + + @Override + public ChannelPipeline getPipeline() throws Exception { + OFChannelHandler handler = new OFChannelHandler(controller); + + ChannelPipeline pipeline = Channels.pipeline(); + if (sslEngine != null) { + log.info("OpenFlow SSL enabled."); + pipeline.addLast("ssl", + new org.jboss.netty.handler.ssl.SslHandler(sslEngine)); + } else { + log.info("OpenFlow SSL disabled"); + } + pipeline.addLast("ofmessagedecoder", new OFMessageDecoder()); + pipeline.addLast("ofmessageencoder", new OFMessageEncoder()); + pipeline.addLast("idle", idleHandler); + pipeline.addLast("timeout", readTimeoutHandler); + // XXX S ONOS: was 15 increased it to fix Issue #296 + pipeline.addLast("handshaketimeout", + new HandshakeTimeoutHandler(handler, timer, 60)); + if (pipelineExecutor != null) { + pipeline.addLast("pipelineExecutor", + new ExecutionHandler(pipelineExecutor)); + } + pipeline.addLast("handler", handler); + return pipeline; + } + + @Override + public void releaseExternalResources() { + timer.stop(); + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java new file mode 100644 index 00000000..bd4875cf --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java @@ -0,0 +1,406 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.impl; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import org.onosproject.openflow.controller.RoleState; +import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver; +import org.onosproject.openflow.controller.driver.RoleHandler; +import org.onosproject.openflow.controller.driver.RoleRecvStatus; +import org.onosproject.openflow.controller.driver.RoleReplyInfo; +import org.onosproject.openflow.controller.driver.SwitchStateException; +import org.projectfloodlight.openflow.protocol.OFControllerRole; +import org.projectfloodlight.openflow.protocol.OFErrorMsg; +import org.projectfloodlight.openflow.protocol.OFErrorType; +import org.projectfloodlight.openflow.protocol.OFExperimenter; +import org.projectfloodlight.openflow.protocol.OFFactories; +import org.projectfloodlight.openflow.protocol.OFNiciraControllerRole; +import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleReply; +import org.projectfloodlight.openflow.protocol.OFRoleReply; +import org.projectfloodlight.openflow.protocol.OFRoleRequest; +import org.projectfloodlight.openflow.protocol.OFVersion; +import org.projectfloodlight.openflow.protocol.errormsg.OFBadRequestErrorMsg; +import org.projectfloodlight.openflow.protocol.errormsg.OFRoleRequestFailedErrorMsg; +import org.projectfloodlight.openflow.types.U64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + + +/** + * A utility class to handle role requests and replies for this channel. + * After a role request is submitted the role changer keeps track of the + * pending request, collects the reply (if any) and times out the request + * if necessary. + */ +class RoleManager implements RoleHandler { + protected static final long NICIRA_EXPERIMENTER = 0x2320; + + private static Logger log = LoggerFactory.getLogger(RoleManager.class); + + // The time until cached XID is evicted. Arbitrary for now. + private final int pendingXidTimeoutSeconds = 60; + + // The cache for pending expected RoleReplies keyed on expected XID + private Cache pendingReplies = + CacheBuilder.newBuilder() + .expireAfterWrite(pendingXidTimeoutSeconds, TimeUnit.SECONDS) + .build(); + + // the expectation set by the caller for the returned role + private RoleRecvStatus expectation; + private final OpenFlowSwitchDriver sw; + + + public RoleManager(OpenFlowSwitchDriver sw) { + this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE; + this.sw = sw; + } + + /** + * Send NX role request message to the switch requesting the specified + * role. + * + * @param role role to request + */ + private int sendNxRoleRequest(RoleState role) throws IOException { + // Convert the role enum to the appropriate role to send + OFNiciraControllerRole roleToSend = OFNiciraControllerRole.ROLE_OTHER; + switch (role) { + case MASTER: + roleToSend = OFNiciraControllerRole.ROLE_MASTER; + break; + case SLAVE: + case EQUAL: + default: + // ensuring that the only two roles sent to 1.0 switches with + // Nicira role support, are MASTER and SLAVE + roleToSend = OFNiciraControllerRole.ROLE_OTHER; + log.debug("Sending Nx Role.SLAVE to switch {}.", sw); + } + int xid = sw.getNextTransactionId(); + OFExperimenter roleRequest = OFFactories.getFactory(OFVersion.OF_10) + .buildNiciraControllerRoleRequest() + .setXid(xid) + .setRole(roleToSend) + .build(); + sw.sendRoleRequest(roleRequest); + return xid; + } + + private int sendOF13RoleRequest(RoleState role) throws IOException { + // Convert the role enum to the appropriate role to send + OFControllerRole roleToSend = OFControllerRole.ROLE_NOCHANGE; + switch (role) { + case EQUAL: + roleToSend = OFControllerRole.ROLE_EQUAL; + break; + case MASTER: + roleToSend = OFControllerRole.ROLE_MASTER; + break; + case SLAVE: + roleToSend = OFControllerRole.ROLE_SLAVE; + break; + default: + log.warn("Sending default role.noChange to switch {}." + + " Should only be used for queries.", sw); + } + + int xid = sw.getNextTransactionId(); + OFRoleRequest rrm = OFFactories.getFactory(OFVersion.OF_13) + .buildRoleRequest() + .setRole(roleToSend) + .setXid(xid) + //FIXME fix below when we actually use generation ids + .setGenerationId(U64.ZERO) + .build(); + + sw.sendRoleRequest(rrm); + return xid; + } + + @Override + public synchronized boolean sendRoleRequest(RoleState role, RoleRecvStatus exp) + throws IOException { + this.expectation = exp; + + if (sw.factory().getVersion() == OFVersion.OF_10) { + Boolean supportsNxRole = sw.supportNxRole(); + if (!supportsNxRole) { + log.debug("Switch driver indicates no support for Nicira " + + "role request messages. Not sending ..."); + handleUnsentRoleMessage(role, + expectation); + return false; + } + // OF1.0 switch with support for NX_ROLE_REQUEST vendor extn. + // make Role.EQUAL become Role.SLAVE + RoleState roleToSend = (role == RoleState.EQUAL) ? RoleState.SLAVE : role; + pendingReplies.put(sendNxRoleRequest(roleToSend), role); + } else { + // OF1.3 switch, use OFPT_ROLE_REQUEST message + pendingReplies.put(sendOF13RoleRequest(role), role); + } + return true; + } + + private void handleUnsentRoleMessage(RoleState role, + RoleRecvStatus exp) throws IOException { + // typically this is triggered for a switch where role messages + // are not supported - we confirm that the role being set is + // master + if (exp != RoleRecvStatus.MATCHED_SET_ROLE) { + + log.error("Expected MASTER role from registry for switch " + + "which has no support for role-messages." + + "Received {}. It is possible that this switch " + + "is connected to other controllers, in which " + + "case it should support role messages - not " + + "moving forward.", role); + + } + + } + + + @Override + public synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri) + throws SwitchStateException { + int xid = (int) rri.getXid(); + RoleState receivedRole = rri.getRole(); + RoleState expectedRole = pendingReplies.getIfPresent(xid); + + if (expectedRole == null) { + RoleState currentRole = (sw != null) ? sw.getRole() : null; + if (currentRole != null) { + if (currentRole == rri.getRole()) { + // Don't disconnect if the role reply we received is + // for the same role we are already in. + // FIXME: but we do from the caller anyways. + log.debug("Received unexpected RoleReply from " + + "Switch: {}. " + + "Role in reply is same as current role of this " + + "controller for this sw. Ignoring ...", + sw.getStringId()); + return RoleRecvStatus.OTHER_EXPECTATION; + } else { + String msg = String.format("Switch: [%s], " + + "received unexpected RoleReply[%s]. " + + "No roles are pending, and this controller's " + + "current role:[%s] does not match reply. " + + "Disconnecting switch ... ", + sw.getStringId(), + rri, currentRole); + throw new SwitchStateException(msg); + } + } + log.debug("Received unexpected RoleReply {} from " + + "Switch: {}. " + + "This controller has no current role for this sw. " + + "Ignoring ...", + rri, + sw == null ? "(null)" : sw.getStringId()); + return RoleRecvStatus.OTHER_EXPECTATION; + } + + // XXX Should check generation id meaningfully and other cases of expectations + //if (pendingXid != xid) { + // log.info("Received older role reply from " + + // "switch {} ({}). Ignoring. " + + // "Waiting for {}, xid={}", + // new Object[] {sw.getStringId(), rri, + // pendingRole, pendingXid }); + // return RoleRecvStatus.OLD_REPLY; + //} + sw.returnRoleReply(expectedRole, receivedRole); + + if (expectedRole == receivedRole) { + log.debug("Received role reply message from {} that matched " + + "expected role-reply {} with expectations {}", + sw.getStringId(), receivedRole, expectation); + + // Done with this RoleReply; Invalidate + pendingReplies.invalidate(xid); + if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE || + expectation == RoleRecvStatus.MATCHED_SET_ROLE) { + return expectation; + } else { + return RoleRecvStatus.OTHER_EXPECTATION; + } + } + + pendingReplies.invalidate(xid); + // if xids match but role's don't, perhaps its a query (OF1.3) + if (expectation == RoleRecvStatus.REPLY_QUERY) { + return expectation; + } + + return RoleRecvStatus.OTHER_EXPECTATION; + } + + /** + * Called if we receive an error message. If the xid matches the + * pending request we handle it otherwise we ignore it. + * + * Note: since we only keep the last pending request we might get + * error messages for earlier role requests that we won't be able + * to handle + */ + @Override + public synchronized RoleRecvStatus deliverError(OFErrorMsg error) + throws SwitchStateException { + RoleState errorRole = pendingReplies.getIfPresent(error.getXid()); + if (errorRole == null) { + if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) { + log.debug("Received an error msg from sw {} for a role request," + + " but not for pending request in role-changer; " + + " ignoring error {} ...", + sw.getStringId(), error); + } else { + log.debug("Received an error msg from sw {}, but no pending " + + "requests in role-changer; not handling ...", + sw.getStringId()); + } + return RoleRecvStatus.OTHER_EXPECTATION; + } + // it is an error related to a currently pending role request message + if (error.getErrType() == OFErrorType.BAD_REQUEST) { + log.error("Received a error msg {} from sw {} for " + + "pending role request {}. Switch driver indicates " + + "role-messaging is supported. Possible issues in " + + "switch driver configuration?", + ((OFBadRequestErrorMsg) error).toString(), + sw.getStringId(), + errorRole); + return RoleRecvStatus.UNSUPPORTED; + } + + if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) { + OFRoleRequestFailedErrorMsg rrerr = + (OFRoleRequestFailedErrorMsg) error; + switch (rrerr.getCode()) { + case BAD_ROLE: + // switch says that current-role-req has bad role? + // for now we disconnect + // fall-thru + case STALE: + // switch says that current-role-req has stale gen-id? + // for now we disconnect + // fall-thru + case UNSUP: + // switch says that current-role-req has role that + // cannot be supported? for now we disconnect + String msgx = String.format("Switch: [%s], " + + "received Error to for pending role request [%s]. " + + "Error:[%s]. Disconnecting switch ... ", + sw.getStringId(), + errorRole, rrerr); + throw new SwitchStateException(msgx); + default: + break; + } + } + + // This error message was for a role request message but we dont know + // how to handle errors for nicira role request messages + return RoleRecvStatus.OTHER_EXPECTATION; + } + + /** + * Extract the role from an OFVendor message. + * + * Extract the role from an OFVendor message if the message is a + * Nicira role reply. Otherwise return null. + * + * @param experimenterMsg message + * @return The role in the message if the message is a Nicira role + * reply, null otherwise. + * @throws SwitchStateException If the message is a Nicira role reply + * but the numeric role value is unknown. + */ + @Override + public RoleState extractNiciraRoleReply(OFExperimenter experimenterMsg) + throws SwitchStateException { + int vendor = (int) experimenterMsg.getExperimenter(); + if (vendor != 0x2320) { + return null; + } + OFNiciraControllerRoleReply nrr = + (OFNiciraControllerRoleReply) experimenterMsg; + + RoleState role = null; + OFNiciraControllerRole ncr = nrr.getRole(); + switch (ncr) { + case ROLE_MASTER: + role = RoleState.MASTER; + break; + case ROLE_OTHER: + role = RoleState.EQUAL; + break; + case ROLE_SLAVE: + role = RoleState.SLAVE; + break; + default: //handled below + } + + if (role == null) { + String msg = String.format("Switch: [%s], " + + "received NX_ROLE_REPLY with invalid role " + + "value %s", + sw.getStringId(), + nrr.getRole()); + throw new SwitchStateException(msg); + } + return role; + } + + /** + * Extract the role information from an OF1.3 Role Reply Message. + * + * @param rrmsg the role message + * @return RoleReplyInfo object + * @throws SwitchStateException if the role information could not be extracted. + */ + @Override + public RoleReplyInfo extractOFRoleReply(OFRoleReply rrmsg) + throws SwitchStateException { + OFControllerRole cr = rrmsg.getRole(); + RoleState role = null; + switch (cr) { + case ROLE_EQUAL: + role = RoleState.EQUAL; + break; + case ROLE_MASTER: + role = RoleState.MASTER; + break; + case ROLE_SLAVE: + role = RoleState.SLAVE; + break; + case ROLE_NOCHANGE: // switch should send current role + default: + String msg = String.format("Unknown controller role %s " + + "received from switch %s", cr, sw); + throw new SwitchStateException(msg); + } + + return new RoleReplyInfo(role, rrmsg.getGenerationId(), rrmsg.getXid()); + } + +} + diff --git a/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/package-info.java b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/package-info.java new file mode 100644 index 00000000..a5d9f274 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Implementation of the OpenFlow controller IO subsystem. + */ +package org.onosproject.openflow.controller.impl; diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelAdapter.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelAdapter.java new file mode 100644 index 00000000..75260a1d --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelAdapter.java @@ -0,0 +1,159 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import java.net.SocketAddress; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelConfig; +import org.jboss.netty.channel.ChannelFactory; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelPipeline; + +/** + * Adapter for testing against a netty channel. + */ +public class ChannelAdapter implements Channel { + @Override + public Integer getId() { + return null; + } + + @Override + public ChannelFactory getFactory() { + return null; + } + + @Override + public Channel getParent() { + return null; + } + + @Override + public ChannelConfig getConfig() { + return null; + } + + @Override + public ChannelPipeline getPipeline() { + return null; + } + + @Override + public boolean isOpen() { + return false; + } + + @Override + public boolean isBound() { + return false; + } + + @Override + public boolean isConnected() { + return false; + } + + @Override + public SocketAddress getLocalAddress() { + return null; + } + + @Override + public SocketAddress getRemoteAddress() { + return null; + } + + @Override + public ChannelFuture write(Object o) { + return null; + } + + @Override + public ChannelFuture write(Object o, SocketAddress socketAddress) { + return null; + } + + @Override + public ChannelFuture bind(SocketAddress socketAddress) { + return null; + } + + @Override + public ChannelFuture connect(SocketAddress socketAddress) { + return null; + } + + @Override + public ChannelFuture disconnect() { + return null; + } + + @Override + public ChannelFuture unbind() { + return null; + } + + @Override + public ChannelFuture close() { + return null; + } + + @Override + public ChannelFuture getCloseFuture() { + return null; + } + + @Override + public int getInterestOps() { + return 0; + } + + @Override + public boolean isReadable() { + return false; + } + + @Override + public boolean isWritable() { + return false; + } + + @Override + public ChannelFuture setInterestOps(int i) { + return null; + } + + @Override + public ChannelFuture setReadable(boolean b) { + return null; + } + + @Override + public Object getAttachment() { + return null; + } + + @Override + public void setAttachment(Object o) { + + } + + @Override + public int compareTo(Channel o) { + return 0; + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelHandlerContextAdapter.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelHandlerContextAdapter.java new file mode 100644 index 00000000..5b6c2a36 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ChannelHandlerContextAdapter.java @@ -0,0 +1,77 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.ChannelHandler; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelPipeline; + +/** + * Adapter for testing against a netty channel handler context. + */ +public class ChannelHandlerContextAdapter implements ChannelHandlerContext { + @Override + public Channel getChannel() { + return null; + } + + @Override + public ChannelPipeline getPipeline() { + return null; + } + + @Override + public String getName() { + return null; + } + + @Override + public ChannelHandler getHandler() { + return null; + } + + @Override + public boolean canHandleUpstream() { + return false; + } + + @Override + public boolean canHandleDownstream() { + return false; + } + + @Override + public void sendUpstream(ChannelEvent channelEvent) { + + } + + @Override + public void sendDownstream(ChannelEvent channelEvent) { + + } + + @Override + public Object getAttachment() { + return null; + } + + @Override + public void setAttachment(Object o) { + + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/DriverAdapter.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/DriverAdapter.java new file mode 100644 index 00000000..57becf94 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/DriverAdapter.java @@ -0,0 +1,104 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import java.util.Map; +import java.util.Set; + +import org.onosproject.net.driver.Behaviour; +import org.onosproject.net.driver.Driver; +import org.onosproject.net.driver.DriverData; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver; + +/** + * Created by ray on 11/4/15. + */ +public class DriverAdapter implements Driver { + @Override + public String name() { + return null; + } + + @Override + public Driver parent() { + return null; + } + + @Override + public String manufacturer() { + return null; + } + + @Override + public String hwVersion() { + return null; + } + + @Override + public String swVersion() { + return null; + } + + @Override + public Set> behaviours() { + return null; + } + + @Override + public Class implementation(Class behaviour) { + return null; + } + + @Override + public boolean hasBehaviour(Class behaviourClass) { + return true; + } + + @Override + public T createBehaviour(DriverData data, Class behaviourClass) { + return null; + } + + @SuppressWarnings("unchecked") + @Override + public T createBehaviour(DriverHandler handler, Class behaviourClass) { + if (behaviourClass == OpenFlowSwitchDriver.class) { + return (T) new OpenflowSwitchDriverAdapter(); + } + return null; + } + + @Override + public Map properties() { + return null; + } + + @Override + public Driver merge(Driver other) { + return null; + } + + @Override + public Set keys() { + return null; + } + + @Override + public String value(String key) { + return null; + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/DriverServiceAdapter.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/DriverServiceAdapter.java new file mode 100644 index 00000000..25596ada --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/DriverServiceAdapter.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import java.util.Set; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.driver.Behaviour; +import org.onosproject.net.driver.Driver; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.net.driver.DriverService; + +/** + * Created by ray on 11/4/15. + */ +public class DriverServiceAdapter implements DriverService { + @Override + public Set getDrivers() { + return null; + } + + @Override + public Set getDrivers(Class withBehaviour) { + return null; + } + + @Override + public Driver getDriver(String mfr, String hw, String sw) { + return null; + } + + @Override + public Driver getDriver(DeviceId deviceId) { + return null; + } + + @Override + public DriverHandler createHandler(DeviceId deviceId, String... credentials) { + return null; + } + + @Override + public Driver getDriver(String driverName) { + return null; + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ExecutorServiceAdapter.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ExecutorServiceAdapter.java new file mode 100644 index 00000000..54c9c94b --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/ExecutorServiceAdapter.java @@ -0,0 +1,99 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Test harness adapter for the ExecutorService. + */ +public class ExecutorServiceAdapter implements ExecutorService { + @Override + public void shutdown() { + + } + + @Override + public List shutdownNow() { + return null; + } + + @Override + public boolean isShutdown() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) + throws InterruptedException { + return false; + } + + @Override + public Future submit(Callable task) { + return null; + } + + @Override + public Future submit(Runnable task, T result) { + return null; + } + + @Override + public Future submit(Runnable task) { + return null; + } + + @Override + public List> invokeAll(Collection> tasks) + throws InterruptedException { + return null; + } + + @Override + public List> invokeAll(Collection> tasks, long timeout, TimeUnit unit) + throws InterruptedException { + return null; + } + + @Override + public T invokeAny(Collection> tasks) throws InterruptedException, ExecutionException { + return null; + } + + @Override + public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return null; + } + + @Override + public void execute(Runnable command) { + + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfFeaturesReply.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfFeaturesReply.java new file mode 100644 index 00000000..e280d56e --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfFeaturesReply.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import java.util.List; +import java.util.Set; + +import org.projectfloodlight.openflow.protocol.OFActionType; +import org.projectfloodlight.openflow.protocol.OFCapabilities; +import org.projectfloodlight.openflow.protocol.OFFeaturesReply; +import org.projectfloodlight.openflow.protocol.OFPortDesc; +import org.projectfloodlight.openflow.protocol.OFType; +import org.projectfloodlight.openflow.types.DatapathId; +import org.projectfloodlight.openflow.types.OFAuxId; + +/** + * Mock of the Open FLow features reply message. + */ +public class MockOfFeaturesReply extends OfMessageAdapter implements OFFeaturesReply { + public MockOfFeaturesReply() { + super(OFType.FEATURES_REPLY); + } + + @Override + public DatapathId getDatapathId() { + return null; + } + + @Override + public long getNBuffers() { + return 0; + } + + @Override + public short getNTables() { + return 0; + } + + @Override + public Set getCapabilities() { + return null; + } + + @Override + public long getReserved() { + return 0; + } + + @Override + public List getPorts() { + return null; + } + + @Override + public Set getActions() { + return null; + } + + @Override + public OFAuxId getAuxiliaryId() { + return null; + } + + @Override + public OFFeaturesReply.Builder createBuilder() { + return null; + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfPacketIn.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfPacketIn.java new file mode 100644 index 00000000..8e2069b0 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfPacketIn.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import org.projectfloodlight.openflow.protocol.OFPacketIn; +import org.projectfloodlight.openflow.protocol.OFPacketInReason; +import org.projectfloodlight.openflow.protocol.OFType; +import org.projectfloodlight.openflow.protocol.match.Match; +import org.projectfloodlight.openflow.types.OFBufferId; +import org.projectfloodlight.openflow.types.OFPort; +import org.projectfloodlight.openflow.types.TableId; +import org.projectfloodlight.openflow.types.U64; + +/** + * Mock of the Open Flow packet in message. + */ +public class MockOfPacketIn extends OfMessageAdapter implements OFPacketIn { + public MockOfPacketIn() { + super(OFType.PACKET_IN); + } + + @Override + public OFBufferId getBufferId() { + return null; + } + + @Override + public int getTotalLen() { + return 0; + } + + @Override + public OFPacketInReason getReason() { + return null; + } + + @Override + public TableId getTableId() { + return null; + } + + @Override + public Match getMatch() { + return null; + } + + @Override + public byte[] getData() { + return new byte[0]; + } + + @Override + public OFPort getInPort() { + return null; + } + + @Override + public OFPort getInPhyPort() { + return null; + } + + @Override + public U64 getCookie() { + return null; + } + + @Override + public OFPacketIn.Builder createBuilder() { + return null; + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfPortStatus.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfPortStatus.java new file mode 100644 index 00000000..2e26542f --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/MockOfPortStatus.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import org.projectfloodlight.openflow.protocol.OFPortDesc; +import org.projectfloodlight.openflow.protocol.OFPortReason; +import org.projectfloodlight.openflow.protocol.OFPortStatus; +import org.projectfloodlight.openflow.protocol.OFType; + +/** + * Mocked open flow port status message. + */ +public class MockOfPortStatus extends OfMessageAdapter implements OFPortStatus { + public MockOfPortStatus() { + super(OFType.PORT_STATUS); + } + + @Override + public OFPortReason getReason() { + return null; + } + + @Override + public OFPortDesc getDesc() { + return null; + } + + @Override + public OFPortStatus.Builder createBuilder() { + return null; + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OFDescStatsReplyAdapter.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OFDescStatsReplyAdapter.java new file mode 100644 index 00000000..1e866413 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OFDescStatsReplyAdapter.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import java.util.Set; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags; +import org.projectfloodlight.openflow.protocol.OFStatsType; +import org.projectfloodlight.openflow.protocol.OFType; +import org.projectfloodlight.openflow.protocol.OFVersion; + +import com.google.common.hash.PrimitiveSink; + +/** + * Created by ray on 11/4/15. + */ +public class OFDescStatsReplyAdapter implements OFDescStatsReply { + @Override + public OFVersion getVersion() { + return null; + } + + @Override + public OFType getType() { + return null; + } + + @Override + public long getXid() { + return 0; + } + + @Override + public OFStatsType getStatsType() { + return null; + } + + @Override + public Set getFlags() { + return null; + } + + @Override + public String getMfrDesc() { + return null; + } + + @Override + public String getHwDesc() { + return null; + } + + @Override + public String getSwDesc() { + return null; + } + + @Override + public String getSerialNum() { + return null; + } + + @Override + public String getDpDesc() { + return null; + } + + @Override + public void writeTo(ChannelBuffer channelBuffer) { + + } + + @Override + public Builder createBuilder() { + return null; + } + + @Override + public void putTo(PrimitiveSink sink) { + + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OfMessageAdapter.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OfMessageAdapter.java new file mode 100644 index 00000000..b7446eb9 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OfMessageAdapter.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFType; +import org.projectfloodlight.openflow.protocol.OFVersion; + +import com.google.common.hash.PrimitiveSink; + +/** + * Adapter for testing against an OpenFlow message. + */ +public class OfMessageAdapter implements OFMessage { + OFType type; + + private OfMessageAdapter() {} + + public OfMessageAdapter(OFType type) { + this.type = type; + } + + @Override + public OFType getType() { + return type; + } + + @Override + public OFVersion getVersion() { + return null; + } + + @Override + public long getXid() { + return 0; + } + + @Override + public void writeTo(ChannelBuffer channelBuffer) { } + + @Override + public Builder createBuilder() { + return null; + } + + @Override + public void putTo(PrimitiveSink sink) { } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenFlowSwitchListenerAdapter.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenFlowSwitchListenerAdapter.java new file mode 100644 index 00000000..b018f42a --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenFlowSwitchListenerAdapter.java @@ -0,0 +1,77 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.onosproject.openflow.controller.Dpid; +import org.onosproject.openflow.controller.OpenFlowSwitchListener; +import org.onosproject.openflow.controller.RoleState; +import org.projectfloodlight.openflow.protocol.OFPortStatus; + +/** + * Test harness for a switch listener. + */ +public class OpenFlowSwitchListenerAdapter implements OpenFlowSwitchListener { + final List removedDpids = new ArrayList<>(); + final List addedDpids = new ArrayList<>(); + final List changedDpids = new ArrayList<>(); + final Map portChangedDpids = new HashMap<>(); + + @Override + public void switchAdded(Dpid dpid) { + addedDpids.add(dpid); + } + + @Override + public void switchRemoved(Dpid dpid) { + removedDpids.add(dpid); + } + + @Override + public void switchChanged(Dpid dpid) { + changedDpids.add(dpid); + } + + @Override + public void portChanged(Dpid dpid, OFPortStatus status) { + portChangedDpids.put(dpid, status); + } + + @Override + public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response) { + // Stub + } + + public List removedDpids() { + return removedDpids; + } + + public List addedDpids() { + return addedDpids; + } + + public List changedDpids() { + return changedDpids; + } + + public Map portChangedDpids() { + return portChangedDpids; + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java new file mode 100644 index 00000000..9b899a67 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java @@ -0,0 +1,302 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow; + +import java.util.List; + +import org.jboss.netty.channel.Channel; +import org.onosproject.net.Device; +import org.onosproject.net.driver.DriverData; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.openflow.controller.Dpid; +import org.onosproject.openflow.controller.RoleState; +import org.onosproject.openflow.controller.driver.OpenFlowAgent; +import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver; +import org.onosproject.openflow.controller.driver.RoleHandler; +import org.onosproject.openflow.controller.driver.SwitchStateException; +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFErrorMsg; +import org.projectfloodlight.openflow.protocol.OFFactories; +import org.projectfloodlight.openflow.protocol.OFFactory; +import org.projectfloodlight.openflow.protocol.OFFeaturesReply; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFPortDesc; +import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFVersion; + +/** + * Testing adapter for the OpenFlow switch driver class. + */ +public class OpenflowSwitchDriverAdapter implements OpenFlowSwitchDriver { + + RoleState role = RoleState.MASTER; + + @Override + public void setAgent(OpenFlowAgent agent) { + + } + + @Override + public void setRoleHandler(RoleHandler roleHandler) { + + } + + @Override + public void reassertRole() { + + } + + @Override + public boolean handleRoleError(OFErrorMsg error) { + return false; + } + + @Override + public void handleNiciraRole(OFMessage m) throws SwitchStateException { + + } + + @Override + public void handleRole(OFMessage m) throws SwitchStateException { + + } + + @Override + public boolean connectSwitch() { + return false; + } + + @Override + public boolean activateMasterSwitch() { + return false; + } + + @Override + public boolean activateEqualSwitch() { + return false; + } + + @Override + public void transitionToEqualSwitch() { + + } + + @Override + public void transitionToMasterSwitch() { + + } + + @Override + public void removeConnectedSwitch() { + + } + + @Override + public void setPortDescReply(OFPortDescStatsReply portDescReply) { + + } + + @Override + public void setPortDescReplies(List portDescReplies) { + + } + + @Override + public void setFeaturesReply(OFFeaturesReply featuresReply) { + + } + + @Override + public void setSwitchDescription(OFDescStatsReply desc) { + + } + + @Override + public int getNextTransactionId() { + return 0; + } + + @Override + public void setOFVersion(OFVersion ofV) { + + } + + @Override + public void setTableFull(boolean full) { + + } + + @Override + public void setChannel(Channel channel) { + + } + + @Override + public void setConnected(boolean connected) { + + } + + @Override + public void init(Dpid dpid, OFDescStatsReply desc, OFVersion ofv) { + + } + + @Override + public Boolean supportNxRole() { + return true; + } + + @Override + public void startDriverHandshake() { + + } + + @Override + public boolean isDriverHandshakeComplete() { + return false; + } + + @Override + public void processDriverHandshakeMessage(OFMessage m) { + + } + + @Override + public void sendRoleRequest(OFMessage message) { + + } + + @Override + public void sendHandshakeMessage(OFMessage message) { + + } + + @Override + public DriverHandler handler() { + return null; + } + + @Override + public void setHandler(DriverHandler handler) { + + } + + @Override + public DriverData data() { + return null; + } + + @Override + public void setData(DriverData data) { + + } + + @Override + public void sendMsg(OFMessage msg) { + + } + + @Override + public void sendMsg(List msgs) { + + } + + @Override + public void handleMessage(OFMessage fromSwitch) { + + } + + @Override + public void setRole(RoleState role) { + this.role = role; + } + + @Override + public RoleState getRole() { + return role; + } + + @Override + public List getPorts() { + return null; + } + + @Override + public OFFactory factory() { + // return what-ever triggers requestPending = true + return OFFactories.getFactory(OFVersion.OF_10); + } + + @Override + public String getStringId() { + return "100"; + } + + @Override + public long getId() { + return 0; + } + + @Override + public String manufacturerDescription() { + return null; + } + + @Override + public String datapathDescription() { + return null; + } + + @Override + public String hardwareDescription() { + return null; + } + + @Override + public String softwareDescription() { + return null; + } + + @Override + public String serialNumber() { + return null; + } + + @Override + public boolean isConnected() { + return false; + } + + @Override + public void disconnectSwitch() { + + } + + @Override + public void returnRoleReply(RoleState requested, RoleState response) { + + } + + @Override + public Device.Type deviceType() { + return Device.Type.SWITCH; + } + + @Override + public String channelId() { + return null; + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/ControllerTest.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/ControllerTest.java new file mode 100644 index 00000000..dddea328 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/ControllerTest.java @@ -0,0 +1,219 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.impl; + +import java.io.File; +import java.io.IOException; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.Map; +import java.util.stream.IntStream; + +import org.junit.Before; +import org.junit.Test; +import org.onlab.junit.TestTools; +import org.onlab.util.ItemNotFoundException; +import org.onosproject.net.DeviceId; +import org.onosproject.net.driver.Driver; +import org.onosproject.openflow.DriverAdapter; +import org.onosproject.openflow.DriverServiceAdapter; +import org.onosproject.openflow.OFDescStatsReplyAdapter; +import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver; +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.Files; + +import static com.google.common.io.ByteStreams.toByteArray; +import static com.google.common.io.Files.write; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.lessThan; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +/** + * Unit tests for the OpenFlow controller class. + */ +public class ControllerTest { + + Controller controller; + protected static final Logger log = LoggerFactory.getLogger(ControllerTest.class); + + static final File TEST_DIR = Files.createTempDir(); + + /* + * Writes the necessary file for the tests in the temporary directory + */ + static File stageTestResource(String name) throws IOException { + File file = new File(TEST_DIR, name); + byte[] bytes = toByteArray(ControllerTest.class.getResourceAsStream(name)); + write(bytes, file); + return file; + } + + class MockDriverService extends DriverServiceAdapter { + static final int NO_SUCH_DRIVER_ID = 1; + static final int ITEM_NOT_FOUND_DRIVER_ID = 2; + static final int DRIVER_EXISTS_ID = 3; + + static final String BASE_DRIVER_NAME = "of:000000000000000"; + + static final String NO_SUCH_DRIVER = BASE_DRIVER_NAME + + NO_SUCH_DRIVER_ID; + static final String ITEM_NOT_FOUND_DRIVER = BASE_DRIVER_NAME + + ITEM_NOT_FOUND_DRIVER_ID; + static final String DRIVER_EXISTS = BASE_DRIVER_NAME + + DRIVER_EXISTS_ID; + + @Override + public Driver getDriver(DeviceId deviceId) { + switch (deviceId.toString()) { + case NO_SUCH_DRIVER: + return null; + case ITEM_NOT_FOUND_DRIVER: + throw new ItemNotFoundException(); + case DRIVER_EXISTS: + return new DriverAdapter(); + default: + throw new AssertionError(); + } + } + } + + /** + * Creates and initializes a new controller. + */ + @Before + public void setUp() { + controller = new Controller(); + Dictionary properties = new Hashtable<>(); + properties.put("openflowPorts", + Integer.toString(TestTools.findAvailablePort(0))); + controller.setConfigParams(properties); + } + + /** + * Tests fetching a driver that does not exist. + */ + @Test + public void switchInstanceNotFoundTest() { + controller.start(null, new MockDriverService()); + OpenFlowSwitchDriver driver = + controller.getOFSwitchInstance(MockDriverService.NO_SUCH_DRIVER_ID, + null, + null); + assertThat(driver, nullValue()); + controller.stop(); + } + + /** + * Tests fetching a driver that throws an ItemNotFoundException. + */ + @Test + public void switchItemNotFoundTest() { + controller.start(null, new MockDriverService()); + OFDescStatsReply stats = + new OFDescStatsReplyAdapter(); + OpenFlowSwitchDriver driver = + controller.getOFSwitchInstance(MockDriverService.ITEM_NOT_FOUND_DRIVER_ID, + stats, + null); + assertThat(driver, nullValue()); + controller.stop(); + } + + /** + * Tests fetching a driver that throws an ItemNotFoundException. + */ + @Test + public void driverExistsTest() { + controller.start(null, new MockDriverService()); + OFDescStatsReply stats = + new OFDescStatsReplyAdapter(); + OpenFlowSwitchDriver driver = + controller.getOFSwitchInstance(MockDriverService.DRIVER_EXISTS_ID, + stats, + null); + assertThat(driver, notNullValue()); + controller.stop(); + } + + /** + * Tests configuring the controller. + */ + @Test + public void testConfiguration() { + Dictionary properties = new Hashtable<>(); + properties.put("openflowPorts", "1,2,3,4,5"); + properties.put("workerThreads", "5"); + + controller.setConfigParams(properties); + IntStream.rangeClosed(1, 5) + .forEach(i -> assertThat(controller.openFlowPorts, hasItem(i))); + assertThat(controller.workerThreads, is(5)); + } + + /** + * Tests the SSL/TLS methods in the controller. + */ + @Test + public void testSsl() throws IOException { + File keystore = stageTestResource("ControllerTestKeystore.jks"); + String keystoreName = keystore.getAbsolutePath(); + + System.setProperty("enableOFTLS", Boolean.toString(Boolean.TRUE)); + System.setProperty("javax.net.ssl.keyStore", keystoreName); + System.setProperty("javax.net.ssl.trustStore", keystoreName); + System.setProperty("javax.net.ssl.keyStorePassword", "password"); + System.setProperty("javax.net.ssl.trustStorePassword", "password"); + Dictionary properties = new Hashtable<>(); + properties.put("openflowPorts", + Integer.toString(TestTools.findAvailablePort(0))); + properties.put("workerThreads", "0"); + + controller.setConfigParams(properties); + controller.start(null, new MockDriverService()); + + assertThat(controller.serverSslEngine, notNullValue()); + + controller.stop(); + boolean removed = keystore.delete(); + if (!removed) { + log.warn("Could not remove temporary file"); + } + } + + /** + * Tests controll utility health methods. + */ + @Test + public void testHealth() { + Map memory = controller.getMemory(); + assertThat(memory.size(), is(2)); + assertThat(memory.get("total"), is(not(0))); + assertThat(memory.get("free"), is(not(0))); + + long startTime = controller.getSystemStartTime(); + assertThat(startTime, lessThan(System.currentTimeMillis())); + + long upTime = controller.getSystemUptime(); + assertThat(upTime, lessThan(30L * 1000)); + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageDecoderTest.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageDecoderTest.java new file mode 100644 index 00000000..ed1db238 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageDecoderTest.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.impl; + + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.junit.Test; +import org.onosproject.openflow.ChannelAdapter; +import org.onosproject.openflow.ChannelHandlerContextAdapter; +import org.projectfloodlight.openflow.protocol.OFHello; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +/** + * Tests for the OpenFlow message decoder. + */ +public class OFMessageDecoderTest { + + static class ConnectedChannel extends ChannelAdapter { + @Override + public boolean isConnected() { + return true; + } + } + + private ChannelBuffer getHelloMessageBuffer() { + // OFHello, OF version 1, xid of 0, total of 8 bytes + byte[] messageData = {0x1, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0}; + ChannelBuffer channelBuffer = ChannelBuffers.dynamicBuffer(); + channelBuffer.writeBytes(messageData); + return channelBuffer; + } + + /** + * Tests decoding a message on a closed channel. + * + * @throws Exception when an exception is thrown from the decoder + */ + @Test + public void testDecodeNoChannel() throws Exception { + OFMessageDecoder decoder = new OFMessageDecoder(); + ChannelBuffer channelBuffer = getHelloMessageBuffer(); + Object message = + decoder.decode(new ChannelHandlerContextAdapter(), + new ChannelAdapter(), + channelBuffer); + assertThat(message, nullValue()); + } + + /** + * Tests decoding a message. + * + * @throws Exception when an exception is thrown from the decoder + */ + @Test + public void testDecode() throws Exception { + OFMessageDecoder decoder = new OFMessageDecoder(); + ChannelBuffer channelBuffer = getHelloMessageBuffer(); + Object message = + decoder.decode(new ChannelHandlerContextAdapter(), + new ConnectedChannel(), + channelBuffer); + assertThat(message, notNullValue()); + assertThat(message, instanceOf(OFHello.class)); + } + +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageEncoderTest.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageEncoderTest.java new file mode 100644 index 00000000..d09e5661 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OFMessageEncoderTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.impl; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.junit.Test; +import org.onosproject.openflow.OfMessageAdapter; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFType; + +import com.google.common.collect.ImmutableList; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +/** + * Tests for the OpenFlow message encoder. + */ +public class OFMessageEncoderTest { + + static class MockOfMessage extends OfMessageAdapter { + static int nextId = 1; + final int id; + + MockOfMessage() { + super(OFType.ERROR); + id = nextId++; + } + + @Override + public void writeTo(ChannelBuffer channelBuffer) { + String message = "message" + Integer.toString(id) + " "; + channelBuffer.writeBytes(message.getBytes(StandardCharsets.UTF_8)); + } + } + + /** + * Tests that encoding a non-list returns the object specified. + * + * @throws Exception on exception in the encoder + */ + @Test + public void testNoList() throws Exception { + OFMessageEncoder encoder = new OFMessageEncoder(); + MockOfMessage message = new MockOfMessage(); + OFMessage returnedMessage = + (OFMessage) encoder.encode(null, null, message); + assertThat(message, is(returnedMessage)); + } + + /** + * Tests that encoding a list returns the proper encoded payload. + * + * @throws Exception on exception in the encoder + */ + @Test + public void testList() throws Exception { + OFMessageEncoder encoder = new OFMessageEncoder(); + MockOfMessage message1 = new MockOfMessage(); + MockOfMessage message2 = new MockOfMessage(); + MockOfMessage message3 = new MockOfMessage(); + List messages = ImmutableList.of(message1, message2, message3); + ChannelBuffer returnedChannel = + (ChannelBuffer) encoder.encode(null, null, messages); + assertThat(returnedChannel, notNullValue()); + byte[] channelBytes = returnedChannel.array(); + String expectedListMessage = "message1 message2 message3 "; + String listMessage = + (new String(channelBytes, StandardCharsets.UTF_8)) + .substring(0, expectedListMessage.length()); + assertThat(listMessage, is(expectedListMessage)); + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplPacketsTest.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplPacketsTest.java new file mode 100644 index 00000000..13086ca7 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplPacketsTest.java @@ -0,0 +1,167 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.impl; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Future; + +import org.junit.Before; +import org.junit.Test; +import org.onosproject.openflow.ExecutorServiceAdapter; +import org.onosproject.openflow.MockOfFeaturesReply; +import org.onosproject.openflow.MockOfPacketIn; +import org.onosproject.openflow.MockOfPortStatus; +import org.onosproject.openflow.OfMessageAdapter; +import org.onosproject.openflow.OpenFlowSwitchListenerAdapter; +import org.onosproject.openflow.OpenflowSwitchDriverAdapter; +import org.onosproject.openflow.controller.Dpid; +import org.onosproject.openflow.controller.OpenFlowPacketContext; +import org.onosproject.openflow.controller.OpenFlowSwitch; +import org.onosproject.openflow.controller.PacketListener; +import org.projectfloodlight.openflow.protocol.OFMessage; +import org.projectfloodlight.openflow.protocol.OFType; + +import static junit.framework.TestCase.fail; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; + +/** + * Tests for packet processing in the open flow controller impl class. + */ +public class OpenFlowControllerImplPacketsTest { + OpenFlowControllerImpl controller; + OpenFlowControllerImpl.OpenFlowSwitchAgent agent; + Dpid dpid1; + OpenFlowSwitch switch1; + OpenFlowSwitchListenerAdapter switchListener; + TestPacketListener packetListener; + TestExecutorService executorService; + + /** + * Mock packet listener that accumulates packets. + */ + class TestPacketListener implements PacketListener { + List contexts = new ArrayList<>(); + + @Override + public void handlePacket(OpenFlowPacketContext pktCtx) { + contexts.add(pktCtx); + } + + List contexts() { + return contexts; + } + } + + + /** + * Mock executor service that tracks submits. + */ + static class TestExecutorService extends ExecutorServiceAdapter { + private List submittedMessages = new ArrayList<>(); + + List submittedMessages() { + return submittedMessages; + } + + @Override + public Future submit(Runnable task) { + OpenFlowControllerImpl.OFMessageHandler handler = + (OpenFlowControllerImpl.OFMessageHandler) task; + submittedMessages.add(handler.msg); + return null; + } + } + + /** + * Sets up switches to use as data, mocks and launches a controller instance. + */ + @Before + public void setUp() { + try { + switch1 = new OpenflowSwitchDriverAdapter(); + dpid1 = Dpid.dpid(new URI("of:0000000000000111")); + } catch (URISyntaxException ex) { + // Does not happen + fail(); + } + + controller = new OpenFlowControllerImpl(); + agent = controller.agent; + switchListener = new OpenFlowSwitchListenerAdapter(); + controller.addListener(switchListener); + + packetListener = new TestPacketListener(); + controller.addPacketListener(100, packetListener); + + executorService = new TestExecutorService(); + controller.executorMsgs = executorService; + } + + /** + * Tests a port status operation. + */ + @Test + public void testPortStatus() { + OFMessage portStatusPacket = new MockOfPortStatus(); + controller.processPacket(dpid1, portStatusPacket); + assertThat(switchListener.portChangedDpids().size(), is(1)); + assertThat(switchListener.portChangedDpids().containsKey(dpid1), + is(true)); + assertThat(switchListener.portChangedDpids().get(dpid1), + equalTo(portStatusPacket)); + } + + /** + * Tests a features reply operation. + */ + @Test + public void testFeaturesReply() { + OFMessage ofFeaturesReplyPacket = new MockOfFeaturesReply(); + controller.processPacket(dpid1, ofFeaturesReplyPacket); + assertThat(switchListener.changedDpids(), hasSize(1)); + assertThat(switchListener.changedDpids().get(0), + equalTo(dpid1)); + } + + /** + * Tests a packet in operation. + */ + @Test + public void testPacketIn() { + agent.addConnectedSwitch(dpid1, switch1); + OFMessage packetInPacket = new MockOfPacketIn(); + controller.processPacket(dpid1, packetInPacket); + assertThat(packetListener.contexts(), hasSize(1)); + } + + /** + * Tests an error operation. + */ + @Test + public void testError() { + agent.addConnectedSwitch(dpid1, switch1); + OfMessageAdapter errorPacket = new OfMessageAdapter(OFType.ERROR); + controller.processPacket(dpid1, errorPacket); + assertThat(executorService.submittedMessages(), hasSize(1)); + assertThat(executorService.submittedMessages().get(0), is(errorPacket)); + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplTest.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplTest.java new file mode 100644 index 00000000..e079c590 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplTest.java @@ -0,0 +1,283 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.impl; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.List; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.junit.TestTools; +import org.onosproject.cfg.ComponentConfigService; +import org.onosproject.openflow.OpenflowSwitchDriverAdapter; +import org.onosproject.openflow.controller.Dpid; +import org.onosproject.openflow.controller.OpenFlowSwitch; +import org.onosproject.openflow.controller.OpenFlowSwitchListener; +import org.onosproject.openflow.controller.RoleState; +import org.osgi.service.component.ComponentContext; +import org.projectfloodlight.openflow.protocol.OFPortStatus; + +import com.google.common.collect.ImmutableSet; + +import static junit.framework.TestCase.fail; +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.replay; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; + +/** + * Unit tests for the open flow controller implementation test. + */ +public class OpenFlowControllerImplTest { + + OpenFlowSwitch switch1; + Dpid dpid1; + OpenFlowSwitch switch2; + Dpid dpid2; + OpenFlowSwitch switch3; + Dpid dpid3; + + OpenFlowControllerImpl controller; + OpenFlowControllerImpl.OpenFlowSwitchAgent agent; + TestSwitchListener switchListener; + + /** + * Test harness for a switch listener. + */ + static class TestSwitchListener implements OpenFlowSwitchListener { + final List removedDpids = new ArrayList<>(); + final List addedDpids = new ArrayList<>(); + final List changedDpids = new ArrayList<>(); + + @Override + public void switchAdded(Dpid dpid) { + addedDpids.add(dpid); + } + + @Override + public void switchRemoved(Dpid dpid) { + removedDpids.add(dpid); + } + + @Override + public void switchChanged(Dpid dpid) { + changedDpids.add(dpid); + } + + @Override + public void portChanged(Dpid dpid, OFPortStatus status) { + // Stub + } + + @Override + public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response) { + // Stub + } + } + + + /** + * Sets up switches to use as data, mocks and launches a controller instance. + */ + @Before + public void setUp() { + try { + switch1 = new OpenflowSwitchDriverAdapter(); + dpid1 = Dpid.dpid(new URI("of:0000000000000111")); + switch2 = new OpenflowSwitchDriverAdapter(); + dpid2 = Dpid.dpid(new URI("of:0000000000000222")); + switch3 = new OpenflowSwitchDriverAdapter(); + dpid3 = Dpid.dpid(new URI("of:0000000000000333")); + } catch (URISyntaxException ex) { + // Does not happen + fail(); + } + + controller = new OpenFlowControllerImpl(); + agent = controller.agent; + + switchListener = new TestSwitchListener(); + controller.addListener(switchListener); + + ComponentConfigService mockConfigService = + EasyMock.createMock(ComponentConfigService.class); + expect(mockConfigService.getProperties(anyObject())).andReturn(ImmutableSet.of()); + mockConfigService.registerProperties(controller.getClass()); + expectLastCall(); + mockConfigService.unregisterProperties(controller.getClass(), false); + expectLastCall(); + expect(mockConfigService.getProperties(anyObject())).andReturn(ImmutableSet.of()); + controller.cfgService = mockConfigService; + replay(mockConfigService); + + ComponentContext mockContext = EasyMock.createMock(ComponentContext.class); + Dictionary properties = new Hashtable<>(); + properties.put("openflowPorts", + Integer.toString(TestTools.findAvailablePort(0))); + expect(mockContext.getProperties()).andReturn(properties); + replay(mockContext); + controller.activate(mockContext); + } + + @After + public void tearDown() { + controller.removeListener(switchListener); + controller.deactivate(); + } + + /** + * Converts an Iterable of some type into a stream of that type. + * + * @param items Iterable of objects + * @param type of the items in the iterable + * @return stream of objects of type T + */ + private Stream makeIntoStream(Iterable items) { + return StreamSupport.stream( + Spliterators.spliteratorUnknownSize( + items.iterator(), Spliterator.ORDERED), false); + } + + + /** + * Tests adding and removing connected switches. + */ + @Test + public void testAddRemoveConnectedSwitch() { + + // test adding connected switches + boolean addSwitch1 = agent.addConnectedSwitch(dpid1, switch1); + assertThat(addSwitch1, is(true)); + boolean addSwitch2 = agent.addConnectedSwitch(dpid2, switch2); + assertThat(addSwitch2, is(true)); + boolean addSwitch3 = agent.addConnectedSwitch(dpid3, switch3); + assertThat(addSwitch3, is(true)); + + // Make sure the listener add callbacks fired + assertThat(switchListener.addedDpids, hasSize(3)); + assertThat(switchListener.addedDpids, hasItems(dpid1, dpid2, dpid3)); + + // Test adding a switch twice - it should fail + boolean addBadSwitch1 = agent.addConnectedSwitch(dpid1, switch1); + assertThat(addBadSwitch1, is(false)); + + assertThat(controller.connectedSwitches.size(), is(3)); + + // test querying the switch list + Stream fetchedSwitches = + makeIntoStream(controller.getSwitches()); + long switchCount = fetchedSwitches.count(); + assertThat(switchCount, is(3L)); + + // test querying the individual switch + OpenFlowSwitch queriedSwitch = controller.getSwitch(dpid1); + assertThat(queriedSwitch, is(switch1)); + + // Remove a switch + agent.removeConnectedSwitch(dpid3); + Stream fetchedSwitchesAfterRemove = + makeIntoStream(controller.getSwitches()); + long switchCountAfterRemove = fetchedSwitchesAfterRemove.count(); + assertThat(switchCountAfterRemove, is(2L)); + + // Make sure the listener delete callbacks fired + assertThat(switchListener.removedDpids, hasSize(1)); + assertThat(switchListener.removedDpids, hasItems(dpid3)); + + // test querying the removed switch + OpenFlowSwitch queriedSwitchAfterRemove = controller.getSwitch(dpid3); + assertThat(queriedSwitchAfterRemove, nullValue()); + } + + /** + * Tests adding master switches. + */ + @Test + public void testMasterSwitch() { + agent.addConnectedSwitch(dpid1, switch1); + agent.transitionToMasterSwitch(dpid1); + + Stream fetchedMasterSwitches = + makeIntoStream(controller.getMasterSwitches()); + assertThat(fetchedMasterSwitches.count(), is(1L)); + Stream fetchedActivatedSwitches = + makeIntoStream(controller.getEqualSwitches()); + assertThat(fetchedActivatedSwitches.count(), is(0L)); + OpenFlowSwitch fetchedSwitch1 = controller.getMasterSwitch(dpid1); + assertThat(fetchedSwitch1, is(switch1)); + + agent.addConnectedSwitch(dpid2, switch2); + boolean addSwitch2 = agent.addActivatedMasterSwitch(dpid2, switch2); + assertThat(addSwitch2, is(true)); + OpenFlowSwitch fetchedSwitch2 = controller.getMasterSwitch(dpid2); + assertThat(fetchedSwitch2, is(switch2)); + } + + /** + * Tests adding equal switches. + */ + @Test + public void testEqualSwitch() { + agent.addConnectedSwitch(dpid1, switch1); + agent.transitionToEqualSwitch(dpid1); + + Stream fetchedEqualSwitches = + makeIntoStream(controller.getEqualSwitches()); + assertThat(fetchedEqualSwitches.count(), is(1L)); + Stream fetchedActivatedSwitches = + makeIntoStream(controller.getMasterSwitches()); + assertThat(fetchedActivatedSwitches.count(), is(0L)); + OpenFlowSwitch fetchedSwitch1 = controller.getEqualSwitch(dpid1); + assertThat(fetchedSwitch1, is(switch1)); + + agent.addConnectedSwitch(dpid2, switch2); + boolean addSwitch2 = agent.addActivatedEqualSwitch(dpid2, switch2); + assertThat(addSwitch2, is(true)); + OpenFlowSwitch fetchedSwitch2 = controller.getEqualSwitch(dpid2); + assertThat(fetchedSwitch2, is(switch2)); + } + + /** + * Tests changing switch role. + */ + @Test + public void testRoleSetting() { + agent.addConnectedSwitch(dpid2, switch2); + + // check that state can be changed for a connected switch + assertThat(switch2.getRole(), is(RoleState.MASTER)); + controller.setRole(dpid2, RoleState.EQUAL); + assertThat(switch2.getRole(), is(RoleState.EQUAL)); + + // check that changing state on an unconnected switch does not crash + controller.setRole(dpid3, RoleState.SLAVE); + } +} diff --git a/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java new file mode 100644 index 00000000..4b594383 --- /dev/null +++ b/framework/src/onos/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java @@ -0,0 +1,130 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.controller.impl; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onosproject.openflow.OpenflowSwitchDriverAdapter; +import org.onosproject.openflow.controller.RoleState; +import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver; +import org.onosproject.openflow.controller.driver.RoleRecvStatus; +import org.onosproject.openflow.controller.driver.RoleReplyInfo; +import org.onosproject.openflow.controller.driver.SwitchStateException; +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.projectfloodlight.openflow.protocol.OFFeaturesReply; +import org.projectfloodlight.openflow.types.U64; + +import static org.junit.Assert.assertEquals; +import static org.onosproject.openflow.controller.RoleState.MASTER; +import static org.onosproject.openflow.controller.RoleState.SLAVE; +import static org.onosproject.openflow.controller.driver.RoleRecvStatus.MATCHED_CURRENT_ROLE; +import static org.onosproject.openflow.controller.driver.RoleRecvStatus.OTHER_EXPECTATION; + +public class RoleManagerTest { + + private static final U64 GID = U64.of(10L); + private static final long XID = 1L; + + private OpenFlowSwitchDriver sw; + private RoleManager manager; + + @Before + public void setUp() { + sw = new TestSwitchDriver(); + manager = new RoleManager(sw); + } + + @After + public void tearDown() { + manager = null; + sw = null; + } + + @Test + public void deliverRoleReply() { + RoleRecvStatus status; + + RoleReplyInfo asserted = new RoleReplyInfo(MASTER, GID, XID); + RoleReplyInfo unasserted = new RoleReplyInfo(SLAVE, GID, XID); + + try { + //call without sendRoleReq() for requestPending = false + //first, sw.role == null + status = manager.deliverRoleReply(asserted); + assertEquals("expectation wrong", OTHER_EXPECTATION, status); + + sw.setRole(MASTER); + assertEquals("expectation wrong", OTHER_EXPECTATION, status); + sw.setRole(SLAVE); + + //match to pendingRole = MASTER, requestPending = true + manager.sendRoleRequest(MASTER, MATCHED_CURRENT_ROLE); + status = manager.deliverRoleReply(asserted); + assertEquals("expectation wrong", MATCHED_CURRENT_ROLE, status); + + //requestPending never gets reset -- this might be a bug. + status = manager.deliverRoleReply(unasserted); + assertEquals("expectation wrong", OTHER_EXPECTATION, status); + assertEquals("pending role mismatch", MASTER, ((TestSwitchDriver) sw).failed); + + } catch (IOException | SwitchStateException e) { + assertEquals("unexpected error thrown", + SwitchStateException.class, e.getClass()); + } + } + + private class TestSwitchDriver extends OpenflowSwitchDriverAdapter { + + RoleState failed = null; + RoleState current = null; + + @Override + public void setRole(RoleState role) { + current = role; + } + + @Override + public RoleState getRole() { + return current; + } + + @Override + public void setFeaturesReply(OFFeaturesReply featuresReply) { + } + + @Override + public void setSwitchDescription(OFDescStatsReply desc) { + } + + @Override + public int getNextTransactionId() { + return (int) XID; + } + + @Override + public void returnRoleReply(RoleState requested, RoleState response) { + failed = requested; + } + + @Override + public String channelId() { + return "1.2.3.4:1"; + } + } +} diff --git a/framework/src/onos/protocols/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplSpringOpenTTPDellOSR.java b/framework/src/onos/protocols/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplSpringOpenTTPDellOSR.java new file mode 100644 index 00000000..783a37e6 --- /dev/null +++ b/framework/src/onos/protocols/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplSpringOpenTTPDellOSR.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.openflow.drivers; + +import org.onosproject.openflow.controller.Dpid; +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; +import org.projectfloodlight.openflow.types.TableId; + +/** + * OFDescriptionStatistics Vendor (Manufacturer Desc.): Dell Make (Hardware + * Desc.) : OpenFlow 1.3 Reference Userspace Switch Model (Datapath Desc.) : + * None Software : Serial : None. + */ +//TODO: Knock-off this class as we don't need any switch/app specific +//drivers in the south bound layers. +public class OFSwitchImplSpringOpenTTPDellOSR extends OFSwitchImplSpringOpenTTP { + + /* Table IDs to be used for Dell Open Segment Routers*/ + private static final int DELL_TABLE_VLAN = 17; + private static final int DELL_TABLE_TMAC = 18; + private static final int DELL_TABLE_IPV4_UNICAST = 30; + private static final int DELL_TABLE_MPLS = 25; + private static final int DELL_TABLE_ACL = 40; + + public OFSwitchImplSpringOpenTTPDellOSR(Dpid dpid, OFDescStatsReply desc) { + super(dpid, desc); + vlanTableId = DELL_TABLE_VLAN; + tmacTableId = DELL_TABLE_TMAC; + ipv4UnicastTableId = DELL_TABLE_IPV4_UNICAST; + mplsTableId = DELL_TABLE_MPLS; + aclTableId = DELL_TABLE_ACL; + } + + @Override + public TableType getTableType(TableId tid) { + switch (tid.getValue()) { + case DELL_TABLE_IPV4_UNICAST: + return TableType.IP; + case DELL_TABLE_MPLS: + return TableType.MPLS; + case DELL_TABLE_ACL: + return TableType.ACL; + case DELL_TABLE_VLAN: + return TableType.VLAN; + case DELL_TABLE_TMAC: + return TableType.ETHER; + default: + log.error("Table type for Table id {} is not supported in the driver", tid); + return TableType.NONE; + } + } +} \ No newline at end of file diff --git a/framework/src/onos/protocols/openflow/pom.xml b/framework/src/onos/protocols/openflow/pom.xml new file mode 100644 index 00000000..5a136a19 --- /dev/null +++ b/framework/src/onos/protocols/openflow/pom.xml @@ -0,0 +1,86 @@ + + + + 4.0.0 + + + org.onosproject + onos-protocols + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-of + pom + + ONOS OpenFlow Protocol subsystem + + + api + ctl + + + + + org.onosproject + onlab-misc + + + org.onosproject + onlab-junit + + + junit + junit + 4.11 + test + + + org.hamcrest + hamcrest-core + 1.3 + test + + + org.hamcrest + hamcrest-library + 1.3 + test + + + org.easymock + easymock + test + + + org.osgi + org.osgi.core + + + + + + + org.apache.felix + maven-bundle-plugin + + + + + diff --git a/framework/src/onos/ovsdb/api/pom.xml b/framework/src/onos/protocols/ovsdb/api/pom.xml similarity index 100% rename from framework/src/onos/ovsdb/api/pom.xml rename to framework/src/onos/protocols/ovsdb/api/pom.xml diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/DefaultEventSubject.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/DefaultEventSubject.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/DefaultEventSubject.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/DefaultEventSubject.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/EventSubject.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/EventSubject.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/EventSubject.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/EventSubject.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridge.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridge.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridge.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridge.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridgeName.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridgeName.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridgeName.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbBridgeName.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java similarity index 99% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java index cfd844d3..a35fa6cf 100644 --- a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java +++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java @@ -49,6 +49,7 @@ public interface OvsdbClientService extends OvsdbRPC { * @param srcIp source IP address * @param dstIp destination IP address */ + @Deprecated void createTunnel(IpAddress srcIp, IpAddress dstIp); /** diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbConstant.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbController.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbDatapathId.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbDatapathId.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbDatapathId.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbDatapathId.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEvent.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEvent.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEvent.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEvent.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventListener.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventListener.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventListener.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventListener.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventSubject.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventSubject.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventSubject.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbEventSubject.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbIfaceId.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbIfaceId.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbIfaceId.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbIfaceId.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeId.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeId.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeId.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeId.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeListener.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeListener.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeListener.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeListener.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPort.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPort.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPort.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPort.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortName.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortName.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortName.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortName.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortNumber.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortNumber.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortNumber.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortNumber.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortType.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortType.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortType.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbPortType.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbRowStore.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbStore.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTableStore.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnel.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnel.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnel.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnel.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnelName.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnelName.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnelName.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbTunnelName.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java similarity index 99% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java index c6038632..8a661ab9 100644 --- a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java +++ b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java @@ -43,6 +43,7 @@ import org.onosproject.ovsdb.controller.OvsdbRowStore; import org.onosproject.ovsdb.controller.OvsdbStore; import org.onosproject.ovsdb.controller.OvsdbTableStore; import org.onosproject.ovsdb.controller.OvsdbTunnel; +import org.onosproject.ovsdb.rfc.exception.BridgeCreateException; import org.onosproject.ovsdb.rfc.jsonrpc.Callback; import org.onosproject.ovsdb.rfc.message.OperationResult; import org.onosproject.ovsdb.rfc.message.TableUpdates; @@ -479,6 +480,9 @@ public class DefaultOvsdbClient insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid, port.getRow()); } + } else { + String message = BridgeCreateException.createMessage(ovsUuid); + throw new BridgeCreateException(message); } } else { @@ -545,6 +549,9 @@ public class DefaultOvsdbClient insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid, port.getRow()); } + } else { + String message = BridgeCreateException.createMessage(ovsUuid); + throw new BridgeCreateException(message); } } else { diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbAgent.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbAgent.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbAgent.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbAgent.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/OvsdbProviderService.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/package-info.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/package-info.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/package-info.java diff --git a/framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/package-info.java b/framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/package-info.java rename to framework/src/onos/protocols/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/package-info.java diff --git a/framework/src/onos/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbClientServiceAdapter.java b/framework/src/onos/protocols/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbClientServiceAdapter.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbClientServiceAdapter.java rename to framework/src/onos/protocols/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbClientServiceAdapter.java diff --git a/framework/src/onos/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbControllerAdapter.java b/framework/src/onos/protocols/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbControllerAdapter.java similarity index 100% rename from framework/src/onos/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbControllerAdapter.java rename to framework/src/onos/protocols/ovsdb/api/src/test/java/org/onosproject/ovsdb/controller/driver/OvsdbControllerAdapter.java diff --git a/framework/src/onos/ovsdb/ctl/pom.xml b/framework/src/onos/protocols/ovsdb/ctl/pom.xml similarity index 100% rename from framework/src/onos/ovsdb/ctl/pom.xml rename to framework/src/onos/protocols/ovsdb/ctl/pom.xml diff --git a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/ChannelConnectionListener.java b/framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/ChannelConnectionListener.java similarity index 100% rename from framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/ChannelConnectionListener.java rename to framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/ChannelConnectionListener.java diff --git a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java b/framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java similarity index 100% rename from framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java rename to framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/Controller.java diff --git a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/MessageDecoder.java b/framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/MessageDecoder.java similarity index 100% rename from framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/MessageDecoder.java rename to framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/MessageDecoder.java diff --git a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java b/framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java similarity index 100% rename from framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java rename to framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java diff --git a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbJsonRpcHandler.java b/framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbJsonRpcHandler.java similarity index 100% rename from framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbJsonRpcHandler.java rename to framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbJsonRpcHandler.java diff --git a/framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/package-info.java b/framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/package-info.java rename to framework/src/onos/protocols/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/package-info.java diff --git a/framework/src/onos/ovsdb/pom.xml b/framework/src/onos/protocols/ovsdb/pom.xml similarity index 100% rename from framework/src/onos/ovsdb/pom.xml rename to framework/src/onos/protocols/ovsdb/pom.xml diff --git a/framework/src/onos/ovsdb/rfc/pom.xml b/framework/src/onos/protocols/ovsdb/rfc/pom.xml similarity index 100% rename from framework/src/onos/ovsdb/rfc/pom.xml rename to framework/src/onos/protocols/ovsdb/rfc/pom.xml diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/AbnormalJsonNodeException.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/AbnormalJsonNodeException.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/AbnormalJsonNodeException.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/AbnormalJsonNodeException.java diff --git a/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/BridgeCreateException.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/BridgeCreateException.java new file mode 100644 index 00000000..986b50a3 --- /dev/null +++ b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/BridgeCreateException.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.ovsdb.rfc.exception; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * This exception is thrown when Bridge creation fails. + */ +public class BridgeCreateException extends RuntimeException { + private static final long serialVersionUID = 1377521646616825676L; + + /** + * Constructs a BridgeCreateException object. + * @param message error message + */ + public BridgeCreateException(String message) { + super(message); + } + + /** + * Constructs a BridgeCreateException object. + * @param message error message + * @param cause Throwable + */ + public BridgeCreateException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Create error message. + * @param ovsUuid ovs uuid name + * @return message + */ + public static String createMessage(String ovsUuid) { + String message = toStringHelper("BridgeCreateException") + .addValue("Create new bridge failed for " + ovsUuid).toString(); + return message; + } +} diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/ColumnSchemaNotFoundException.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/ColumnSchemaNotFoundException.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/ColumnSchemaNotFoundException.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/ColumnSchemaNotFoundException.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/TableSchemaNotFoundException.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/TableSchemaNotFoundException.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/TableSchemaNotFoundException.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/TableSchemaNotFoundException.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/UnsupportedException.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/UnsupportedException.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/UnsupportedException.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/UnsupportedException.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/VersionMismatchException.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/VersionMismatchException.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/VersionMismatchException.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/VersionMismatchException.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/exception/package-info.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/Callback.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/Callback.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/Callback.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/Callback.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonReadContext.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonReadContext.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonReadContext.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonReadContext.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcRequest.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcRequest.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcRequest.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcRequest.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcResponse.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcResponse.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcResponse.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/JsonRpcResponse.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/OvsdbRPC.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/OvsdbRPC.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/OvsdbRPC.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/OvsdbRPC.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/jsonrpc/package-info.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/MonitorRequest.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/MonitorRequest.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/MonitorRequest.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/MonitorRequest.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/MonitorSelect.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/MonitorSelect.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/MonitorSelect.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/MonitorSelect.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/OperationResult.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/OperationResult.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/OperationResult.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/OperationResult.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/RowUpdate.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/RowUpdate.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/RowUpdate.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/RowUpdate.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/TableUpdate.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/TableUpdate.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/TableUpdate.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/TableUpdate.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/TableUpdates.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/TableUpdates.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/TableUpdates.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/TableUpdates.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/UpdateNotification.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/UpdateNotification.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/UpdateNotification.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/UpdateNotification.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/package-info.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Column.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Column.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Column.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Column.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Condition.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Condition.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Condition.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Condition.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Mutation.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Mutation.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Mutation.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Mutation.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/OvsdbMap.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/OvsdbMap.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/OvsdbMap.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/OvsdbMap.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/OvsdbSet.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/OvsdbSet.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/OvsdbSet.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/OvsdbSet.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/RefTableRow.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/RefTableRow.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/RefTableRow.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/RefTableRow.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Row.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Row.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Row.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Row.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/UUID.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/UUID.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/UUID.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/UUID.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/ConditionSerializer.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/ConditionSerializer.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/ConditionSerializer.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/ConditionSerializer.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/MutationSerializer.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/MutationSerializer.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/MutationSerializer.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/MutationSerializer.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/OvsdbMapSerializer.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/OvsdbMapSerializer.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/OvsdbMapSerializer.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/OvsdbMapSerializer.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/OvsdbSetSerializer.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/OvsdbSetSerializer.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/OvsdbSetSerializer.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/OvsdbSetSerializer.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDConverter.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDConverter.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDConverter.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDConverter.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDSerializer.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDSerializer.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDSerializer.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDSerializer.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UpdateNotificationConverter.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UpdateNotificationConverter.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UpdateNotificationConverter.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UpdateNotificationConverter.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/package-info.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/package-info.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Abort.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Abort.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Abort.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Abort.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Assert.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Assert.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Assert.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Assert.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Comment.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Comment.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Comment.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Comment.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Commit.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Commit.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Commit.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Commit.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Delete.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Delete.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Delete.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Delete.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Insert.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Insert.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Insert.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Insert.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Mutate.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Mutate.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Mutate.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Mutate.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Operation.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Operation.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Operation.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Operation.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Select.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Select.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Select.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Select.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Update.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Update.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Update.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Update.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/package-info.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/ColumnSchema.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/ColumnSchema.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/ColumnSchema.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/ColumnSchema.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/DatabaseSchema.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/DatabaseSchema.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/DatabaseSchema.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/DatabaseSchema.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/TableSchema.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/TableSchema.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/TableSchema.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/TableSchema.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/package-info.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/AtomicColumnType.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/AtomicColumnType.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/AtomicColumnType.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/AtomicColumnType.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseType.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseType.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseType.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseType.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseTypeFactory.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseTypeFactory.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseTypeFactory.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseTypeFactory.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BooleanBaseType.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BooleanBaseType.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BooleanBaseType.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BooleanBaseType.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnType.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnType.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnType.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnType.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnTypeFactory.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnTypeFactory.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnTypeFactory.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnTypeFactory.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/IntegerBaseType.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/IntegerBaseType.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/IntegerBaseType.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/IntegerBaseType.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/KeyValuedColumnType.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/KeyValuedColumnType.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/KeyValuedColumnType.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/KeyValuedColumnType.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/RealBaseType.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/RealBaseType.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/RealBaseType.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/RealBaseType.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/StringBaseType.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/StringBaseType.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/StringBaseType.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/StringBaseType.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/UuidBaseType.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/UuidBaseType.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/UuidBaseType.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/UuidBaseType.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/package-info.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Bridge.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Bridge.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Bridge.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Bridge.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Controller.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Controller.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Controller.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Controller.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/FlowSampleCollectorSet.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/FlowSampleCollectorSet.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/FlowSampleCollectorSet.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/FlowSampleCollectorSet.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/FlowTable.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/FlowTable.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/FlowTable.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/FlowTable.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Ipfix.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Ipfix.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Ipfix.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Ipfix.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Manager.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Manager.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Manager.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Manager.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Mirror.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Mirror.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Mirror.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Mirror.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Netflow.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Netflow.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Netflow.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Netflow.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OpenVSwitch.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OpenVSwitch.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OpenVSwitch.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OpenVSwitch.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Port.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Port.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Port.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Port.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Qos.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Qos.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Qos.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Qos.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Queue.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Queue.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Queue.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Queue.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Sflow.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Sflow.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Sflow.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Sflow.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Ssl.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Ssl.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Ssl.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Ssl.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/TableGenerator.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/TableGenerator.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/TableGenerator.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/TableGenerator.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/package-info.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/ColumnDescription.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/ColumnDescription.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/ColumnDescription.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/ColumnDescription.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/TableDescription.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/TableDescription.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/TableDescription.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/TableDescription.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/package-info.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ConditionUtil.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ConditionUtil.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ConditionUtil.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ConditionUtil.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcWriterUtil.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcWriterUtil.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcWriterUtil.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcWriterUtil.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ObjectMapperUtil.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ObjectMapperUtil.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ObjectMapperUtil.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ObjectMapperUtil.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/StringEncoderUtil.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/StringEncoderUtil.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/StringEncoderUtil.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/StringEncoderUtil.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/TransValueUtil.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/TransValueUtil.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/TransValueUtil.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/TransValueUtil.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/VersionUtil.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/VersionUtil.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/VersionUtil.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/VersionUtil.java diff --git a/framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/package-info.java b/framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/package-info.java similarity index 100% rename from framework/src/onos/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/package-info.java rename to framework/src/onos/protocols/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/package-info.java diff --git a/framework/src/onos/protocols/pcep/api/pom.xml b/framework/src/onos/protocols/pcep/api/pom.xml new file mode 100644 index 00000000..4588ad6f --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/pom.xml @@ -0,0 +1,99 @@ + + + + 4.0.0 + + + org.onosproject + onos-pcep-controller + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-pcep-controller-api + bundle + + ONOS Pcep client controller subsystem API + + + + org.onosproject + onos-app-pcep-api + + + org.onosproject + onos-pcepio + + + io.netty + netty + + + org.onosproject + onos-api + + + org.onosproject + onlab-misc + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + + + io.netty:netty + com.google.guava:guava + org.slf4j:slfj-api + ch.qos.logback:logback-core + ch.qos.logback:logback-classic + com.google.code.findbugs:annotations + + + + + + package + + shade + + + + + + org.apache.felix + maven-bundle-plugin + + + + org.onosproject.pcep.*,org.onosproject.pcepio.* + + + + + + + + diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PccId.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PccId.java new file mode 100755 index 00000000..3ff622bf --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PccId.java @@ -0,0 +1,120 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller; + +import static com.google.common.base.Preconditions.checkArgument; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Objects; + +import org.onlab.packet.IpAddress; + +/** + * The class representing a network client pc ip. + * This class is immutable. + */ +public final class PccId { + + private static final String SCHEME = "pcep"; + private static final long UNKNOWN = 0; + private final IpAddress ipAddress; + + /** + * Private constructor. + */ + private PccId(IpAddress ipAddress) { + this.ipAddress = ipAddress; + } + + /** + * Create a PccId from ip address. + * + * @param ipAddress IP address + * @return ipAddress + */ + public static PccId pccId(IpAddress ipAddress) { + return new PccId(ipAddress); + } + + /** + * Returns the ip address. + * + * @return ipAddress + */ + public IpAddress ipAddress() { + return ipAddress; + } + + /** + * Convert the PccId value to a ':' separated hexadecimal string. + * + * @return the PccId value as a ':' separated hexadecimal string. + */ + @Override + public String toString() { + return ipAddress.toString(); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof PccId)) { + return false; + } + + PccId otherPccid = (PccId) other; + return Objects.equals(ipAddress, otherPccid.ipAddress); + } + + @Override + public int hashCode() { + return Objects.hash(ipAddress); + } + + /** + * Returns PccId created from the given client URI. + * + * @param uri device URI + * @return pccid + */ + public static PccId pccid(URI uri) { + checkArgument(uri.getScheme().equals(SCHEME), "Unsupported URI scheme"); + return new PccId(IpAddress.valueOf(uri.getSchemeSpecificPart())); + } + + /** + * Produces client URI from the given DPID. + * + * @param pccid client pccid + * @return client URI + */ + public static URI uri(PccId pccid) { + return uri(pccid.ipAddress()); + } + + /** + * Produces client URI from the given ip address. + * + * @param ipAddress ip of client + * @return client URI + */ + public static URI uri(IpAddress ipAddress) { + try { + return new URI(SCHEME, ipAddress.toString(), null); + } catch (URISyntaxException e) { + return null; + } + } +} diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java new file mode 100755 index 00000000..95e7789f --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java @@ -0,0 +1,110 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller; + +import java.util.List; + +import org.onosproject.pcepio.protocol.PcepFactory; +import org.onosproject.pcepio.protocol.PcepMessage; + +/** + * Represents to provider facing side of a path computation client(pcc). + */ +public interface PcepClient { + + /** + * Writes the message to the driver. + * + * @param msg the message to write + */ + void sendMessage(PcepMessage msg); + + /** + * Writes the PcepMessage list to the driver. + * + * @param msgs the messages to be written + */ + void sendMessage(List msgs); + + /** + * Handle a message from the pcc. + * + * @param fromClient the message to handle + */ + void handleMessage(PcepMessage fromClient); + + /** + * Provides the factory for this PCEP version. + * + * @return PCEP version specific factory. + */ + PcepFactory factory(); + + /** + * Gets a string version of the ID for this pcc. + * + * @return string version of the ID + */ + String getStringId(); + + /** + * Gets the ipAddress of the client. + * + * @return the client pccId in IPAddress format + */ + PccId getPccId(); + + /** + * Checks if the pcc is still connected. + * + * @return true if client is connected, false otherwise + */ + boolean isConnected(); + + /** + * Disconnects the pcc by closing the TCP connection. Results in a call + * to the channel handler's channelDisconnected method for cleanup. + */ + void disconnectClient(); + + /** + * Indicates if this pcc is optical. + * + * @return true if optical + */ + boolean isOptical(); + + /** + * Identifies the channel used to communicate with the pcc. + * + * @return string representation of the connection to the client + */ + String channelId(); + + /** + * To set the status of state synchronization. + * + * @param value to set the synchronization status + */ + void setIsSyncComplete(boolean value); + + /** + * Indicates the state synchronization status of this pcc. + * + * @return true/false if the synchronization is completed/not completed + */ + boolean isSyncComplete(); +} diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientController.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientController.java new file mode 100644 index 00000000..37453eac --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientController.java @@ -0,0 +1,93 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller; + +import java.util.Collection; + +import org.onosproject.pcepio.protocol.PcepMessage; + +/** + * Abstraction of an Pcep client controller. Serves as a one stop + * shop for obtaining Pcep devices and (un)register listeners + * on pcep events + */ +public interface PcepClientController { + + /** + * Returns list of pcc clients connected to this Pcep controller. + * + * @return list of PcepClient elements + */ + Collection getClients(); + + /** + * Returns the actual pcc client for the given ip address. + * + * @param pccId the id of the pcc client to fetch + * @return the interface to this pcc client + */ + PcepClient getClient(PccId pccId); + + /** + * Register a listener for meta events that occur to pcep + * devices. + * + * @param listener the listener to notify + */ + void addListener(PcepClientListener listener); + + /** + * Unregister a listener. + * + * @param listener the listener to unregister + */ + void removeListener(PcepClientListener listener); + + /** + * Register a listener for OF msg events. + * + * @param listener the listener to notify + */ + void addEventListener(PcepEventListener listener); + + /** + * Unregister a listener. + * + * @param listener the listener to unregister + */ + void removeEventListener(PcepEventListener listener); + + /** + * Send a message to a particular pcc client. + * + * @param pccId the id of the client to send message. + * @param msg the message to send + */ + void writeMessage(PccId pccId, PcepMessage msg); + + /** + * Process a message and notify the appropriate listeners. + * + * @param pccId id of the client the message arrived on + * @param msg the message to process. + */ + void processClientMessage(PccId pccId, PcepMessage msg); + + /** + * Close all connected PCC clients. + */ + void closeConnectedClients(); +} diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientListener.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientListener.java new file mode 100755 index 00000000..e7e0a736 --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientListener.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller; + +/** + * Allows for providers interested in PCC client events to be notified. + */ +public interface PcepClientListener { + + /** + * Notify that the PCC was connected. + * + * @param pccId the id of the client that connected + */ + void clientConnected(PccId pccId); + + /** + * Notify that the PCC was disconnected. + * + * @param pccId the id of the client that disconnected. + */ + void clientDisconnected(PccId pccId); +} diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepEventListener.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepEventListener.java new file mode 100644 index 00000000..f7de215a --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepEventListener.java @@ -0,0 +1,31 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller; + +import org.onosproject.pcepio.protocol.PcepMessage; +/** + * Notifies providers about PCEP message events. + */ +public interface PcepEventListener { + + /** + * Handles the message event. + * + * @param pccId id of the pcc + * @param msg the message + */ + void handleMessage(PccId pccId, PcepMessage msg); +} diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepPacketStats.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepPacketStats.java new file mode 100644 index 00000000..d00cd5a8 --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepPacketStats.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller; + +/** + * The representation for PCEP packet statistics. + */ +public interface PcepPacketStats { + + /** + * Returns the count for no of packets sent out. + * + * @return int value of no of packets sent + */ + int outPacketCount(); + + /** + * Returns the count for no of packets received. + * + * @return int value of no of packets sent + */ + int inPacketCount(); + + /** + * Returns the count for no of wrong packets received. + * + * @return int value of no of wrong packets received + */ + int wrongPacketCount(); + + /** + * Returns the time value. + * + * @return long value of time + */ + long getTime(); +} diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepAgent.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepAgent.java new file mode 100755 index 00000000..4810417c --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepAgent.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller.driver; + +import org.onosproject.pcep.controller.PccId; +import org.onosproject.pcep.controller.PcepClient; +import org.onosproject.pcepio.protocol.PcepMessage; + +/** + * Responsible for keeping track of the current set Pcep clients + * connected to the system. + * + */ +public interface PcepAgent { + + /** + * Add a pcc client that has just connected to the system. + * + * @param pccId the id of pcc client to add + * @param pc the actual pce client object. + * @return true if added, false otherwise. + */ + boolean addConnectedClient(PccId pccId, PcepClient pc); + + /** + * Checks if the activation for this pcc client is valid. + * + * @param pccId the id of pcc client to check + * @return true if valid, false otherwise + */ + boolean validActivation(PccId pccId); + + /** + * Clear all state in controller client maps for a pcc client that has + * disconnected from the local controller. Also release control for + * that pccIds client from the global repository. Notify client listeners. + * + * @param pccIds the id of pcc client to remove. + */ + void removeConnectedClient(PccId pccIds); + + /** + * Process a message coming from a pcc client. + * + * @param pccId the id of pcc client the message was received. + * @param m the message to process + */ + void processPcepMessage(PccId pccId, PcepMessage m); + +} diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepClientDriver.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepClientDriver.java new file mode 100755 index 00000000..f728de54 --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepClientDriver.java @@ -0,0 +1,110 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller.driver; + +import org.jboss.netty.channel.Channel; +import org.onosproject.pcep.controller.PccId; +import org.onosproject.pcep.controller.PcepClient; +import org.onosproject.pcep.controller.PcepPacketStats; +import org.onosproject.pcepio.protocol.PcepVersion; + + +/** + * Represents the driver side of an Path computation client(pcc). + * + */ +public interface PcepClientDriver extends PcepClient { + + /** + * Sets the Pcep agent to be used. This method + * can only be called once. + * + * @param agent the agent to set. + */ + void setAgent(PcepAgent agent); + + /** + * Announce to the Pcep agent that this pcc client has connected. + * + * @return true if successful, false if duplicate switch. + */ + boolean connectClient(); + + /** + * Remove this pcc client from the Pcep agent. + */ + void removeConnectedClient(); + + /** + * Sets the PCEP version for this pcc. + * + * @param pcepVersion the version to set. + */ + void setPcVersion(PcepVersion pcepVersion); + + /** + * Sets the associated Netty channel for this pcc. + * + * @param channel the Netty channel + */ + void setChannel(Channel channel); + + + /** + * Sets the keep alive time for this pcc. + * + * @param keepAliveTime the keep alive time to set. + */ + void setPcKeepAliveTime(byte keepAliveTime); + + /** + * Sets the dead time for this pcc. + * + * @param deadTime the dead timer value to set. + */ + void setPcDeadTime(byte deadTime); + + /** + * Sets the session id for this pcc. + * + * @param sessionId the session id value to set. + */ + void setPcSessionId(byte sessionId); + + /** + * Sets whether the pcc is connected. + * + * @param connected whether the pcc is connected + */ + void setConnected(boolean connected); + + /** + * Initializes the behavior. + * + * @param pccId id of pcc + * @param pcepVersion Pcep version + * @param pktStats Pcep Packet Stats + */ + void init(PccId pccId, PcepVersion pcepVersion, PcepPacketStats pktStats); + + /** + * Checks whether the handshake is complete. + * + * @return true is finished, false if not. + */ + boolean isHandshakeComplete(); + +} diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepClientDriverFactory.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepClientDriverFactory.java new file mode 100755 index 00000000..6ce75bca --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepClientDriverFactory.java @@ -0,0 +1,38 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller.driver; + +import org.onlab.packet.IpAddress; +import org.onosproject.pcepio.protocol.PcepVersion; + +/** + * Pcc Client factory which returns concrete pcc client objects for the + * physical pcc client in use. + * + */ +public interface PcepClientDriverFactory { + + + /** + * Constructs the real Pcep Client representation. + * + * @param pccIpAddress the ip address for this pcc client. + * @param pcepVersion the Pcep version in use + * @return the Pcep client representation. + */ + PcepClientDriver getPcepClientImpl(IpAddress pccIpAddress, + PcepVersion pcepVersion); +} diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/package-info.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/package-info.java new file mode 100644 index 00000000..9d105ff2 --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * PCEP client controller driver API. + */ +package org.onosproject.pcep.controller.driver; diff --git a/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/package-info.java b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/package-info.java new file mode 100644 index 00000000..a0cb2482 --- /dev/null +++ b/framework/src/onos/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * PCEP client controller API. + */ +package org.onosproject.pcep.controller; diff --git a/framework/src/onos/protocols/pcep/ctl/pom.xml b/framework/src/onos/protocols/pcep/ctl/pom.xml new file mode 100644 index 00000000..f0ed5c2f --- /dev/null +++ b/framework/src/onos/protocols/pcep/ctl/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + + org.onosproject + onos-pcep-controller + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-pcep-controller-impl + bundle + + ONOS PCEP client controller subsystem API implementation + + + + org.onosproject + onos-pcep-controller-api + + + io.netty + netty + + + org.apache.felix + org.apache.felix.scr.annotations + + + org.osgi + org.osgi.compendium + + + org.onosproject + onlab-misc + + + + + + + org.apache.felix + maven-scr-plugin + + + + + diff --git a/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/Controller.java b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/Controller.java new file mode 100644 index 00000000..9c27810c --- /dev/null +++ b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/Controller.java @@ -0,0 +1,188 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller.impl; + +import static org.onlab.util.Tools.groupedThreads; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Executors; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.group.ChannelGroup; +import org.jboss.netty.channel.group.DefaultChannelGroup; +import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; +import org.onosproject.pcep.controller.PccId; +import org.onosproject.pcep.controller.PcepPacketStats; +import org.onosproject.pcep.controller.driver.PcepAgent; +import org.onosproject.pcep.controller.driver.PcepClientDriver; +import org.onosproject.pcepio.protocol.PcepFactories; +import org.onosproject.pcepio.protocol.PcepFactory; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The main controller class. Handles all setup and network listeners - + * Distributed ownership control of pcc through IControllerRegistryService + */ +public class Controller { + + private static final Logger log = LoggerFactory.getLogger(Controller.class); + + private static final PcepFactory FACTORY1 = PcepFactories.getFactory(PcepVersion.PCEP_1); + + private ChannelGroup cg; + + // Configuration options + private int pcepPort = 4189; + private int workerThreads = 10; + + // Start time of the controller + private long systemStartTime; + + private PcepAgent agent; + + private NioServerSocketChannelFactory execFactory; + + // Perf. related configuration + private static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024; + + /** + * Returns factory version for processing pcep messages. + * + * @return instance of factory version + */ + public PcepFactory getPcepMessageFactory1() { + return FACTORY1; + } + + /** + * To get system start time. + * + * @return system start time in milliseconds + */ + public long getSystemStartTime() { + return (this.systemStartTime); + } + + /** + * Tell controller that we're ready to accept pcc connections. + */ + public void run() { + try { + final ServerBootstrap bootstrap = createServerBootStrap(); + + bootstrap.setOption("reuseAddr", true); + bootstrap.setOption("child.keepAlive", true); + bootstrap.setOption("child.tcpNoDelay", true); + bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE); + + ChannelPipelineFactory pfact = new PcepPipelineFactory(this); + + bootstrap.setPipelineFactory(pfact); + InetSocketAddress sa = new InetSocketAddress(pcepPort); + cg = new DefaultChannelGroup(); + cg.add(bootstrap.bind(sa)); + log.info("Listening for PCC connection on {}", sa); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Creates server boot strap. + * + * @return ServerBootStrap + */ + private ServerBootstrap createServerBootStrap() { + if (workerThreads == 0) { + execFactory = new NioServerSocketChannelFactory( + Executors.newCachedThreadPool(groupedThreads("onos/pcep", "boss-%d")), + Executors.newCachedThreadPool(groupedThreads("onos/pcep", "worker-%d"))); + return new ServerBootstrap(execFactory); + } else { + execFactory = new NioServerSocketChannelFactory( + Executors.newCachedThreadPool(groupedThreads("onos/pcep", "boss-%d")), + Executors.newCachedThreadPool(groupedThreads("onos/pcep", "worker-%d")), workerThreads); + return new ServerBootstrap(execFactory); + } + } + + /** + * Initialize internal data structures. + */ + public void init() { + // These data structures are initialized here because other + // module's startUp() might be called before ours + this.systemStartTime = System.currentTimeMillis(); + } + + public Map getMemory() { + Map m = new HashMap<>(); + Runtime runtime = Runtime.getRuntime(); + m.put("total", runtime.totalMemory()); + m.put("free", runtime.freeMemory()); + return m; + } + + public Long getUptime() { + RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean(); + return rb.getUptime(); + } + + /** + * Creates instance of Pcep client. + * + * @param pccId pcc identifier + * @param sessionID session id + * @param pv pcep version + * @param pktStats pcep packet statistics + * @return instance of PcepClient + */ + protected PcepClientDriver getPcepClientInstance(PccId pccId, int sessionID, PcepVersion pv, + PcepPacketStats pktStats) { + PcepClientDriver pcepClientDriver = new PcepClientImpl(); + pcepClientDriver.init(pccId, pv, pktStats); + pcepClientDriver.setAgent(agent); + return pcepClientDriver; + } + + /** + * Starts the pcep controller. + * + * @param ag Pcep agent + */ + public void start(PcepAgent ag) { + log.info("Started"); + this.agent = ag; + this.init(); + this.run(); + } + + /** + * Stops the pcep controller. + */ + public void stop() { + log.info("Stopped"); + execFactory.shutdown(); + cg.close(); + } +} diff --git a/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java new file mode 100644 index 00000000..bc8721d7 --- /dev/null +++ b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java @@ -0,0 +1,652 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcep.controller.impl; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.channels.ClosedChannelException; +import java.util.Collections; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.concurrent.RejectedExecutionException; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.ExceptionEvent; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.timeout.IdleState; +import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; +import org.jboss.netty.handler.timeout.IdleStateEvent; +import org.jboss.netty.handler.timeout.IdleStateHandler; +import org.jboss.netty.handler.timeout.ReadTimeoutException; +import org.onlab.packet.IpAddress; +import org.onosproject.pcep.controller.PccId; +import org.onosproject.pcep.controller.driver.PcepClientDriver; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepError; +import org.onosproject.pcepio.protocol.PcepErrorInfo; +import org.onosproject.pcepio.protocol.PcepErrorMsg; +import org.onosproject.pcepio.protocol.PcepErrorObject; +import org.onosproject.pcepio.protocol.PcepFactory; +import org.onosproject.pcepio.protocol.PcepMessage; +import org.onosproject.pcepio.protocol.PcepOpenMsg; +import org.onosproject.pcepio.protocol.PcepOpenObject; +import org.onosproject.pcepio.protocol.PcepType; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.onosproject.pcepio.types.ErrorObjListWithOpen; +import org.onosproject.pcepio.types.PceccCapabilityTlv; +import org.onosproject.pcepio.types.StatefulPceCapabilityTlv; +import org.onosproject.pcepio.types.PcepErrorDetailInfo; +import org.onosproject.pcepio.types.PcepValueType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Channel handler deals with the pcc client connection and dispatches + * messages from client to the appropriate locations. + */ +class PcepChannelHandler extends IdleStateAwareChannelHandler { + static final byte DEADTIMER_MAXIMUM_VALUE = (byte) 0xFF; + static final byte KEEPALIVE_MULTIPLE_FOR_DEADTIMER = 4; + private static final Logger log = LoggerFactory.getLogger(PcepChannelHandler.class); + private final Controller controller; + private PcepClientDriver pc; + private PccId thispccId; + private Channel channel; + private byte sessionId = 0; + private byte keepAliveTime; + private byte deadTime; + private PcepPacketStatsImpl pcepPacketStats; + static final int MAX_WRONG_COUNT_PACKET = 5; + static final int BYTE_MASK = 0xFF; + + // State needs to be volatile because the HandshakeTimeoutHandler + // needs to check if the handshake is complete + private volatile ChannelState state; + + // When a pcc client with a ip addresss is found (i.e we already have a + // connected client with the same ip), the new client is immediately + // disconnected. At that point netty callsback channelDisconnected() which + // proceeds to cleaup client state - we need to ensure that it does not cleanup + // client state for the older (still connected) client + private volatile Boolean duplicatePccIdFound; + + //Indicates the pcep version used by this pcc client + protected PcepVersion pcepVersion; + protected PcepFactory factory1; + + /** + * Create a new unconnected PcepChannelHandler. + * @param controller parent controller + */ + PcepChannelHandler(Controller controller) { + this.controller = controller; + this.state = ChannelState.INIT; + factory1 = controller.getPcepMessageFactory1(); + duplicatePccIdFound = Boolean.FALSE; + pcepPacketStats = new PcepPacketStatsImpl(); + } + + /** + * To disconnect a PCC. + */ + public void disconnectClient() { + pc.disconnectClient(); + } + + //************************* + // Channel State Machine + //************************* + + /** + * The state machine for handling the client/channel state. All state + * transitions should happen from within the state machine (and not from other + * parts of the code) + */ + enum ChannelState { + /** + * Initial state before channel is connected. + */ + INIT(false) { + + }, + /** + * Once the session is established, wait for open message. + */ + OPENWAIT(false) { + @Override + void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException { + + log.debug("Message received in OPEN WAIT State"); + + //check for open message + if (m.getType() != PcepType.OPEN) { + // When the message type is not open message increment the wrong packet statistics + h.processUnknownMsg(); + log.debug("message is not OPEN message"); + } else { + + h.pcepPacketStats.addInPacket(); + PcepOpenMsg pOpenmsg = (PcepOpenMsg) m; + // do Capability validation. + if (h.capabilityValidation(pOpenmsg)) { + log.debug("Sending handshake OPEN message"); + h.sessionId = pOpenmsg.getPcepOpenObject().getSessionId(); + h.pcepVersion = pOpenmsg.getPcepOpenObject().getVersion(); + + //setting keepalive and deadTimer + byte yKeepalive = pOpenmsg.getPcepOpenObject().getKeepAliveTime(); + byte yDeadTimer = pOpenmsg.getPcepOpenObject().getDeadTime(); + h.keepAliveTime = yKeepalive; + if (yKeepalive < yDeadTimer) { + h.deadTime = yDeadTimer; + } else { + if (DEADTIMER_MAXIMUM_VALUE > (yKeepalive * KEEPALIVE_MULTIPLE_FOR_DEADTIMER)) { + h.deadTime = (byte) (yKeepalive * KEEPALIVE_MULTIPLE_FOR_DEADTIMER); + } else { + h.deadTime = DEADTIMER_MAXIMUM_VALUE; + } + } + h.sendHandshakeOpenMessage(); + h.pcepPacketStats.addOutPacket(); + h.setState(KEEPWAIT); + } else { + log.debug("Capability validation failed. Sending PCEP-ERROR message to PCC."); + // Send PCEP-ERROR message. + PcepErrorMsg errMsg = h.getErrorMsg(PcepErrorDetailInfo.ERROR_TYPE_2, + PcepErrorDetailInfo.ERROR_VALUE_2); + h.channel.write(Collections.singletonList(errMsg)); + } + } + } + }, + /** + * Once the open messages are exchanged, wait for keep alive message. + */ + KEEPWAIT(false) { + @Override + void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException { + log.debug("message received in KEEPWAIT state"); + //check for keep alive message + if (m.getType() != PcepType.KEEP_ALIVE) { + // When the message type is not keep alive message increment the wrong packet statistics + h.processUnknownMsg(); + log.debug("message is not KEEPALIVE message"); + } else { + // Set the client connected status + h.pcepPacketStats.addInPacket(); + final SocketAddress address = h.channel.getRemoteAddress(); + if (!(address instanceof InetSocketAddress)) { + throw new IOException("Invalid client connection. Pcc is indentifed based on IP"); + } + log.debug("sending keep alive message in KEEPWAIT state"); + + final InetSocketAddress inetAddress = (InetSocketAddress) address; + h.thispccId = PccId.pccId(IpAddress.valueOf(inetAddress.getAddress())); + h.pc = h.controller.getPcepClientInstance(h.thispccId, h.sessionId, h.pcepVersion, + h.pcepPacketStats); + // set the status of pcc as connected + h.pc.setConnected(true); + h.pc.setChannel(h.channel); + + // set any other specific parameters to the pcc + h.pc.setPcVersion(h.pcepVersion); + h.pc.setPcSessionId(h.sessionId); + h.pc.setPcKeepAliveTime(h.keepAliveTime); + h.pc.setPcDeadTime(h.deadTime); + int keepAliveTimer = h.keepAliveTime & BYTE_MASK; + int deadTimer = h.deadTime & BYTE_MASK; + if (0 == h.keepAliveTime) { + h.deadTime = 0; + } + // handle keep alive and dead time + if (keepAliveTimer != PcepPipelineFactory.DEFAULT_KEEP_ALIVE_TIME + || deadTimer != PcepPipelineFactory.DEFAULT_DEAD_TIME) { + + h.channel.getPipeline().replace("idle", "idle", + new IdleStateHandler(PcepPipelineFactory.TIMER, deadTimer, keepAliveTimer, 0)); + } + log.debug("Dead timer : " + deadTimer); + log.debug("Keep alive time : " + keepAliveTimer); + + //set the state handshake completion. + h.sendKeepAliveMessage(); + h.pcepPacketStats.addOutPacket(); + h.setHandshakeComplete(true); + + if (!h.pc.connectClient()) { + disconnectDuplicate(h); + } else { + h.setState(ESTABLISHED); + } + } + } + }, + /** + * Once the keep alive messages are exchanged, the state is established. + */ + ESTABLISHED(true) { + @Override + void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException { + + //h.channel.getPipeline().remove("waittimeout"); + log.debug("Message received in established state " + m.getType()); + //dispatch the message + h.dispatchMessage(m); + } + }; + private boolean handshakeComplete; + + ChannelState(boolean handshakeComplete) { + this.handshakeComplete = handshakeComplete; + } + + void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException { + // do nothing + } + + /** + * Is this a state in which the handshake has completed. + * + * @return true if the handshake is complete + */ + public boolean isHandshakeComplete() { + return this.handshakeComplete; + } + + protected void disconnectDuplicate(PcepChannelHandler h) { + log.error("Duplicated Pcc IP or incompleted cleanup - " + "disconnecting channel {}", + h.getClientInfoString()); + h.duplicatePccIdFound = Boolean.TRUE; + h.channel.disconnect(); + } + + /** + * Sets handshake complete status. + * + * @param handshakeComplete status of handshake + */ + public void setHandshakeComplete(boolean handshakeComplete) { + this.handshakeComplete = handshakeComplete; + } + + } + + @Override + public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { + channel = e.getChannel(); + log.info("PCC connected from {}", channel.getRemoteAddress()); + + // Wait for open message from pcc client + setState(ChannelState.OPENWAIT); + } + + @Override + public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { + log.info("Pcc disconnected callback for pc:{}. Cleaning up ...", getClientInfoString()); + if (thispccId != null) { + if (!duplicatePccIdFound) { + // if the disconnected client (on this ChannelHandler) + // was not one with a duplicate-dpid, it is safe to remove all + // state for it at the controller. Notice that if the disconnected + // client was a duplicate-ip, calling the method below would clear + // all state for the original client (with the same ip), + // which we obviously don't want. + log.debug("{}:removal called", getClientInfoString()); + if (pc != null) { + pc.removeConnectedClient(); + } + } else { + // A duplicate was disconnected on this ChannelHandler, + // this is the same client reconnecting, but the original state was + // not cleaned up - XXX check liveness of original ChannelHandler + log.debug("{}:duplicate found", getClientInfoString()); + duplicatePccIdFound = Boolean.FALSE; + } + } else { + log.warn("no pccip in channelHandler registered for " + "disconnected client {}", getClientInfoString()); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { + PcepErrorMsg errMsg; + log.info("exceptionCaught: " + e.toString()); + + if (e.getCause() instanceof ReadTimeoutException) { + if (ChannelState.OPENWAIT == state) { + // When ReadTimeout timer is expired in OPENWAIT state, it is considered + // OpenWait timer. + errMsg = getErrorMsg(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_2); + log.debug("Sending PCEP-ERROR message to PCC."); + channel.write(Collections.singletonList(errMsg)); + channel.close(); + state = ChannelState.INIT; + return; + } else if (ChannelState.KEEPWAIT == state) { + // When ReadTimeout timer is expired in KEEPWAIT state, is is considered + // KeepWait timer. + errMsg = getErrorMsg(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_7); + log.debug("Sending PCEP-ERROR message to PCC."); + channel.write(Collections.singletonList(errMsg)); + channel.close(); + state = ChannelState.INIT; + return; + } + } else if (e.getCause() instanceof ClosedChannelException) { + log.debug("Channel for pc {} already closed", getClientInfoString()); + } else if (e.getCause() instanceof IOException) { + log.error("Disconnecting client {} due to IO Error: {}", getClientInfoString(), e.getCause().getMessage()); + if (log.isDebugEnabled()) { + // still print stack trace if debug is enabled + log.debug("StackTrace for previous Exception: ", e.getCause()); + } + channel.close(); + } else if (e.getCause() instanceof PcepParseException) { + PcepParseException errMsgParse = (PcepParseException) e.getCause(); + byte errorType = errMsgParse.getErrorType(); + byte errorValue = errMsgParse.getErrorValue(); + + if ((errorType == (byte) 0x0) && (errorValue == (byte) 0x0)) { + processUnknownMsg(); + } else { + errMsg = getErrorMsg(errorType, errorValue); + log.debug("Sending PCEP-ERROR message to PCC."); + channel.write(Collections.singletonList(errMsg)); + } + } else if (e.getCause() instanceof RejectedExecutionException) { + log.warn("Could not process message: queue full"); + } else { + log.error("Error while processing message from client " + getClientInfoString() + "state " + this.state); + channel.close(); + } + } + + @Override + public String toString() { + return getClientInfoString(); + } + + @Override + public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception { + if (!isHandshakeComplete()) { + return; + } + + if (e.getState() == IdleState.READER_IDLE) { + // When no message is received on channel for read timeout, then close + // the channel + log.info("Disconnecting client {} due to read timeout", getClientInfoString()); + ctx.getChannel().close(); + } else if (e.getState() == IdleState.WRITER_IDLE) { + // Send keep alive message + log.debug("Sending keep alive message due to IdleState timeout " + pc.toString()); + pc.sendMessage(Collections.singletonList(pc.factory().buildKeepaliveMsg().build())); + } + } + + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { + if (e.getMessage() instanceof List) { + @SuppressWarnings("unchecked") + List msglist = (List) e.getMessage(); + for (PcepMessage pm : msglist) { + // Do the actual packet processing + state.processPcepMessage(this, pm); + } + } else { + state.processPcepMessage(this, (PcepMessage) e.getMessage()); + } + } + + /** + * To set the handshake status. + * + * @param handshakeComplete value is handshake status + */ + public void setHandshakeComplete(boolean handshakeComplete) { + this.state.setHandshakeComplete(handshakeComplete); + } + + /** + * Is this a state in which the handshake has completed. + * + * @return true if the handshake is complete + */ + public boolean isHandshakeComplete() { + return this.state.isHandshakeComplete(); + } + + /** + * To handle the pcep message. + * + * @param m pcep message + */ + private void dispatchMessage(PcepMessage m) { + pc.handleMessage(m); + } + + /** + * Return a string describing this client based on the already available + * information (ip address and/or remote socket). + * + * @return display string + */ + private String getClientInfoString() { + if (pc != null) { + return pc.toString(); + } + String channelString; + if (channel == null || channel.getRemoteAddress() == null) { + channelString = "?"; + } else { + channelString = channel.getRemoteAddress().toString(); + } + String pccIpString; + // TODO : implement functionality to get pcc id string + pccIpString = "?"; + return String.format("[%s PCCIP[%s]]", channelString, pccIpString); + } + + /** + * Update the channels state. Only called from the state machine. + * + * @param state + */ + private void setState(ChannelState state) { + this.state = state; + } + + /** + * Send handshake open message. + * + * @throws IOException,PcepParseException + */ + private void sendHandshakeOpenMessage() throws IOException, PcepParseException { + PcepOpenObject pcepOpenobj = factory1.buildOpenObject() + .setSessionId(sessionId) + .setKeepAliveTime(keepAliveTime) + .setDeadTime(deadTime) + .build(); + PcepMessage msg = factory1.buildOpenMsg() + .setPcepOpenObj(pcepOpenobj) + .build(); + log.debug("Sending OPEN message to {}", channel.getRemoteAddress()); + channel.write(Collections.singletonList(msg)); + } + + /** + * Capability Validation. + * + * @param pOpenmsg pcep open message + * @return success or failure + */ + private boolean capabilityValidation(PcepOpenMsg pOpenmsg) { + LinkedList tlvList = pOpenmsg.getPcepOpenObject().getOptionalTlv(); + boolean bFoundPceccCapability = false; + boolean bFoundStatefulPceCapability = false; + boolean bFoundPcInstantiationCapability = false; + + ListIterator listIterator = tlvList.listIterator(); + while (listIterator.hasNext()) { + PcepValueType tlv = listIterator.next(); + + switch (tlv.getType()) { + case PceccCapabilityTlv.TYPE: + bFoundPceccCapability = true; + break; + case StatefulPceCapabilityTlv.TYPE: + bFoundStatefulPceCapability = true; + StatefulPceCapabilityTlv stetefulPcCapTlv = (StatefulPceCapabilityTlv) tlv; + if (stetefulPcCapTlv.getIFlag()) { + bFoundPcInstantiationCapability = true; + } + break; + default: + continue; + } + } + + return (bFoundPceccCapability && bFoundStatefulPceCapability && bFoundPcInstantiationCapability); + } + + /** + * Send keep alive message. + * + * @throws IOException when channel is disconnected + * @throws PcepParseException while building keep alive message + */ + private void sendKeepAliveMessage() throws IOException, PcepParseException { + PcepMessage msg = factory1.buildKeepaliveMsg().build(); + log.debug("Sending KEEPALIVE message to {}", channel.getRemoteAddress()); + channel.write(Collections.singletonList(msg)); + } + + /** + * Send error message and close channel with pcc. + */ + private void sendErrMsgAndCloseChannel() { + // TODO send error message + channel.close(); + } + + /** + * Send error message when an invalid message is received. + * + * @throws PcepParseException while building error message + */ + private void sendErrMsgForInvalidMsg() throws PcepParseException { + byte errorType = 0x02; + byte errorValue = 0x00; + PcepErrorMsg errMsg = getErrorMsg(errorType, errorValue); + channel.write(Collections.singletonList(errMsg)); + } + + /** + * Builds pcep error message based on error value and error type. + * + * @param errorType pcep error type + * @param errorValue pcep error value + * @return pcep error message + * @throws PcepParseException while bulding error message + */ + public PcepErrorMsg getErrorMsg(byte errorType, byte errorValue) throws PcepParseException { + LinkedList llerrObj = new LinkedList<>(); + PcepErrorMsg errMsg; + + PcepErrorObject errObj = factory1.buildPcepErrorObject() + .setErrorValue(errorValue) + .setErrorType(errorType) + .build(); + + llerrObj.add(errObj); + + if (state == ChannelState.OPENWAIT) { + //If Error caught in Openmessage + PcepOpenObject openObj = null; + ErrorObjListWithOpen errorObjListWithOpen = null; + + if (0 != sessionId) { + openObj = factory1.buildOpenObject().setSessionId(sessionId).build(); + errorObjListWithOpen = new ErrorObjListWithOpen(llerrObj, openObj); + } else { + errorObjListWithOpen = new ErrorObjListWithOpen(llerrObj, null); + } + + errMsg = factory1.buildPcepErrorMsg() + .setErrorObjListWithOpen(errorObjListWithOpen) + .build(); + } else { + + //If Error caught in other than Openmessage + LinkedList llPcepErr = new LinkedList<>(); + + PcepError pcepErr = factory1.buildPcepError() + .setErrorObjList(llerrObj) + .build(); + + llPcepErr.add(pcepErr); + + PcepErrorInfo errInfo = factory1.buildPcepErrorInfo() + .setPcepErrorList(llPcepErr) + .build(); + + errMsg = factory1.buildPcepErrorMsg() + .setPcepErrorInfo(errInfo) + .build(); + } + return errMsg; + } + + /** + * Process unknown pcep message received. + * + * @throws PcepParseException while building pcep error message + */ + public void processUnknownMsg() throws PcepParseException { + Date now = null; + if (pcepPacketStats.wrongPacketCount() == 0) { + now = new Date(); + pcepPacketStats.setTime(now.getTime()); + pcepPacketStats.addWrongPacket(); + sendErrMsgForInvalidMsg(); + } + + if (pcepPacketStats.wrongPacketCount() > 1) { + Date lastest = new Date(); + pcepPacketStats.addWrongPacket(); + //converting to seconds + if (((lastest.getTime() - pcepPacketStats.getTime()) / 1000) > 60) { + now = lastest; + pcepPacketStats.setTime(now.getTime()); + pcepPacketStats.resetWrongPacket(); + pcepPacketStats.addWrongPacket(); + } else if (((int) (lastest.getTime() - now.getTime()) / 1000) < 60) { + if (MAX_WRONG_COUNT_PACKET <= pcepPacketStats.wrongPacketCount()) { + //reset once wrong packet count reaches MAX_WRONG_COUNT_PACKET + pcepPacketStats.resetWrongPacket(); + // max wrong packets received send error message and close the session + sendErrMsgAndCloseChannel(); + } + } + } + } +} diff --git a/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java new file mode 100644 index 00000000..00c8c694 --- /dev/null +++ b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java @@ -0,0 +1,222 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller.impl; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Service; +import org.onosproject.pcep.controller.PccId; +import org.onosproject.pcep.controller.PcepClient; +import org.onosproject.pcep.controller.PcepClientController; +import org.onosproject.pcep.controller.PcepClientListener; +import org.onosproject.pcep.controller.PcepEventListener; +import org.onosproject.pcep.controller.driver.PcepAgent; +import org.onosproject.pcepio.protocol.PcepMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Sets; + +/** + * Implementation of PCEP client controller. + */ +@Component(immediate = true) +@Service +public class PcepClientControllerImpl implements PcepClientController { + + private static final Logger log = LoggerFactory.getLogger(PcepClientControllerImpl.class); + + protected ConcurrentHashMap connectedClients = + new ConcurrentHashMap<>(); + + protected PcepClientAgent agent = new PcepClientAgent(); + protected Set pcepClientListener = new HashSet<>(); + + protected Set pcepEventListener = Sets.newHashSet(); + + private final Controller ctrl = new Controller(); + + @Activate + public void activate() { + ctrl.start(agent); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + // Close all connected clients + closeConnectedClients(); + ctrl.stop(); + log.info("Stopped"); + } + + @Override + public Collection getClients() { + return connectedClients.values(); + } + + @Override + public PcepClient getClient(PccId pccId) { + return connectedClients.get(pccId); + } + + @Override + public void addListener(PcepClientListener listener) { + if (!pcepClientListener.contains(listener)) { + this.pcepClientListener.add(listener); + } + } + + @Override + public void removeListener(PcepClientListener listener) { + this.pcepClientListener.remove(listener); + } + + @Override + public void addEventListener(PcepEventListener listener) { + pcepEventListener.add(listener); + } + + @Override + public void removeEventListener(PcepEventListener listener) { + pcepEventListener.remove(listener); + } + + @Override + public void writeMessage(PccId pccId, PcepMessage msg) { + this.getClient(pccId).sendMessage(msg); + } + + @Override + public void processClientMessage(PccId pccId, PcepMessage msg) { + PcepClient pc = getClient(pccId); + + switch (msg.getType()) { + case NONE: + break; + case OPEN: + break; + case KEEP_ALIVE: + break; + case PATH_COMPUTATION_REQUEST: + break; + case PATH_COMPUTATION_REPLY: + break; + case NOTIFICATION: + break; + case ERROR: + break; + case CLOSE: + log.info("Sending Close Message to {" + pccId.toString() + "}"); + pc.sendMessage(Collections.singletonList(pc.factory().buildCloseMsg().build())); + //now disconnect client + pc.disconnectClient(); + break; + case REPORT: + for (PcepEventListener l : pcepEventListener) { + l.handleMessage(pccId, msg); + } + break; + case UPDATE: + for (PcepEventListener l : pcepEventListener) { + l.handleMessage(pccId, msg); + } + break; + case INITIATE: + for (PcepEventListener l : pcepEventListener) { + l.handleMessage(pccId, msg); + } + break; + case LABEL_UPDATE: + break; + case MAX: + break; + case END: + break; + default: + break; + } + } + + @Override + public void closeConnectedClients() { + PcepClient pc; + for (PccId id : connectedClients.keySet()) { + pc = getClient(id); + pc.disconnectClient(); + } + } + + /** + * Implementation of an Pcep Agent which is responsible for + * keeping track of connected clients and the state in which + * they are. + */ + public class PcepClientAgent implements PcepAgent { + + private final Logger log = LoggerFactory.getLogger(PcepClientAgent.class); + + @Override + public boolean addConnectedClient(PccId pccId, PcepClient pc) { + + if (connectedClients.get(pccId) != null) { + log.error("Trying to add connectedClient but found a previous " + + "value for pcc ip: {}", pccId.toString()); + return false; + } else { + log.debug("Added Client {}", pccId.toString()); + connectedClients.put(pccId, pc); + for (PcepClientListener l : pcepClientListener) { + l.clientConnected(pccId); + } + return true; + } + } + + @Override + public boolean validActivation(PccId pccId) { + if (connectedClients.get(pccId) == null) { + log.error("Trying to activate client but is not in " + + "connected client: pccIp {}. Aborting ..", pccId.toString()); + return false; + } + + return true; + } + + @Override + public void removeConnectedClient(PccId pccId) { + + connectedClients.remove(pccId); + for (PcepClientListener l : pcepClientListener) { + log.warn("removal for {}", pccId.toString()); + l.clientDisconnected(pccId); + } + } + + @Override + public void processPcepMessage(PccId pccId, PcepMessage m) { + processClientMessage(pccId, m); + } + } +} diff --git a/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java new file mode 100644 index 00000000..a10ff5c8 --- /dev/null +++ b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java @@ -0,0 +1,220 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcep.controller.impl; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.RejectedExecutionException; + +import org.jboss.netty.channel.Channel; +import org.onlab.packet.IpAddress; +import org.onosproject.pcep.controller.PccId; +import org.onosproject.pcep.controller.PcepPacketStats; +import org.onosproject.pcep.controller.driver.PcepAgent; +import org.onosproject.pcep.controller.driver.PcepClientDriver; +import org.onosproject.pcepio.protocol.PcepFactories; +import org.onosproject.pcepio.protocol.PcepFactory; +import org.onosproject.pcepio.protocol.PcepMessage; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * An abstract representation of an OpenFlow switch. Can be extended by others + * to serve as a base for their vendor specific representation of a switch. + */ +public class PcepClientImpl implements PcepClientDriver { + + protected final Logger log = LoggerFactory.getLogger(PcepClientImpl.class); + + private static final String SHUTDOWN_MSG = "Worker has already been shutdown"; + + private Channel channel; + protected String channelId; + + private boolean connected; + protected boolean startDriverHandshakeCalled = false; + protected boolean isHandShakeComplete = false; + protected boolean isSyncComplete = false; + private PccId pccId; + private PcepAgent agent; + + private PcepVersion pcepVersion; + private byte keepAliveTime; + private byte deadTime; + private byte sessionId; + private PcepPacketStatsImpl pktStats; + + @Override + public void init(PccId pccId, PcepVersion pcepVersion, PcepPacketStats pktStats) { + this.pccId = pccId; + this.pcepVersion = pcepVersion; + this.pktStats = (PcepPacketStatsImpl) pktStats; + } + + @Override + public final void disconnectClient() { + this.channel.close(); + } + + @Override + public final void sendMessage(PcepMessage m) { + log.debug("Sending message to {}", channel.getRemoteAddress()); + try { + channel.write(Collections.singletonList(m)); + this.pktStats.addOutPacket(); + } catch (RejectedExecutionException e) { + log.warn(e.getMessage()); + if (!e.getMessage().contains(SHUTDOWN_MSG)) { + throw e; + } + } + } + + @Override + public final void sendMessage(List msgs) { + try { + channel.write(msgs); + this.pktStats.addOutPacket(msgs.size()); + } catch (RejectedExecutionException e) { + log.warn(e.getMessage()); + if (!e.getMessage().contains(SHUTDOWN_MSG)) { + throw e; + } + } + } + + @Override + public final boolean isConnected() { + return this.connected; + } + + @Override + public final void setConnected(boolean connected) { + this.connected = connected; + }; + + @Override + public final void setChannel(Channel channel) { + this.channel = channel; + final SocketAddress address = channel.getRemoteAddress(); + if (address instanceof InetSocketAddress) { + final InetSocketAddress inetAddress = (InetSocketAddress) address; + final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress()); + if (ipAddress.isIp4()) { + channelId = ipAddress.toString() + ':' + inetAddress.getPort(); + } else { + channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort(); + } + } + }; + + @Override + public String channelId() { + return channelId; + } + + @Override + public final PccId getPccId() { + return this.pccId; + } + + @Override + public final String getStringId() { + return this.pccId.toString(); + } + + @Override + public final void setPcVersion(PcepVersion pcepVersion) { + this.pcepVersion = pcepVersion; + } + + @Override + public void setPcKeepAliveTime(byte keepAliveTime) { + this.keepAliveTime = keepAliveTime; + } + + @Override + public void setPcDeadTime(byte deadTime) { + this.deadTime = deadTime; + } + + @Override + public void setPcSessionId(byte sessionId) { + this.sessionId = sessionId; + } + + @Override + public void setIsSyncComplete(boolean value) { + this.isSyncComplete = value; + } + + @Override + public boolean isSyncComplete() { + return isSyncComplete; + } + + @Override + public final void handleMessage(PcepMessage m) { + this.pktStats.addInPacket(); + this.agent.processPcepMessage(pccId, m); + } + + @Override + public final boolean connectClient() { + return this.agent.addConnectedClient(pccId, this); + } + + @Override + public final void removeConnectedClient() { + this.agent.removeConnectedClient(pccId); + } + + @Override + public PcepFactory factory() { + return PcepFactories.getFactory(pcepVersion); + } + + @Override + public boolean isHandshakeComplete() { + return isHandShakeComplete; + } + + @Override + public final void setAgent(PcepAgent ag) { + if (this.agent == null) { + this.agent = ag; + } + } + + @Override + public boolean isOptical() { + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("channel", channelId()) + .add("pccId", getPccId()) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepMessageDecoder.java b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepMessageDecoder.java new file mode 100644 index 00000000..b1065891 --- /dev/null +++ b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepMessageDecoder.java @@ -0,0 +1,68 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller.impl; + +import java.util.LinkedList; +import java.util.List; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.onosproject.pcepio.protocol.PcepFactories; +import org.onosproject.pcepio.protocol.PcepMessage; +import org.onosproject.pcepio.protocol.PcepMessageReader; +import org.onosproject.pcepio.util.HexDump; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Decode an pcep message from a Channel, for use in a netty pipeline. + */ +public class PcepMessageDecoder extends FrameDecoder { + + protected static final Logger log = LoggerFactory.getLogger(PcepMessageDecoder.class); + + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, + ChannelBuffer buffer) throws Exception { + log.debug("Message received."); + if (!channel.isConnected()) { + log.info("Channel is not connected."); + // In testing, I see decode being called AFTER decode last. + // This check avoids that from reading corrupted frames + return null; + } + + HexDump.pcepHexDump(buffer); + + // Note that a single call to decode results in reading a single + // PcepMessage from the channel buffer, which is passed on to, and processed + // by, the controller (in PcepChannelHandler). + // This is different from earlier behavior (with the original pcepIO), + // where we parsed all the messages in the buffer, before passing on + // a list of the parsed messages to the controller. + // The performance *may or may not* not be as good as before. + PcepMessageReader reader = PcepFactories.getGenericReader(); + List msgList = new LinkedList<>(); + + while (buffer.readableBytes() > 0) { + PcepMessage message = reader.readFrom(buffer); + msgList.add(message); + } + return msgList; + } +} diff --git a/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepMessageEncoder.java b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepMessageEncoder.java new file mode 100644 index 00000000..ae97221e --- /dev/null +++ b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepMessageEncoder.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller.impl; + +import java.util.List; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; +import org.onosproject.pcepio.protocol.PcepMessage; +import org.onosproject.pcepio.util.HexDump; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Encode an pcep message for output into a ChannelBuffer, for use in a + * netty pipeline. + */ +public class PcepMessageEncoder extends OneToOneEncoder { + protected static final Logger log = LoggerFactory.getLogger(PcepMessageEncoder.class); + + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { + log.debug("Sending message"); + if (!(msg instanceof List)) { + log.debug("Invalid msg."); + return msg; + } + + @SuppressWarnings("unchecked") + List msglist = (List) msg; + + ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); + + for (PcepMessage pm : msglist) { + pm.writeTo(buf); + } + + HexDump.pcepHexDump(buf); + + return buf; + } +} diff --git a/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepPacketStatsImpl.java b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepPacketStatsImpl.java new file mode 100644 index 00000000..f2bc51eb --- /dev/null +++ b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepPacketStatsImpl.java @@ -0,0 +1,105 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcep.controller.impl; + +import org.onosproject.pcep.controller.PcepPacketStats; + +/** + * The implementation for PCEP packet statistics. + */ +public class PcepPacketStatsImpl implements PcepPacketStats { + + private int inPacketCount; + private int outPacketCount; + private int wrongPacketCount; + private long time; + + /** + * Default constructor. + */ + public PcepPacketStatsImpl() { + this.inPacketCount = 0; + this.outPacketCount = 0; + this.wrongPacketCount = 0; + this.time = 0; + } + + @Override + public int outPacketCount() { + return outPacketCount; + } + + @Override + public int inPacketCount() { + return inPacketCount; + } + + @Override + public int wrongPacketCount() { + return wrongPacketCount; + } + + /** + * Increments the received packet counter. + */ + public void addInPacket() { + this.inPacketCount++; + } + + /** + * Increments the sent packet counter. + */ + public void addOutPacket() { + this.outPacketCount++; + } + + /** + * Increments the sent packet counter by specified value. + * + * @param value of no of packets sent + */ + public void addOutPacket(int value) { + this.outPacketCount = this.outPacketCount + value; + } + + /** + * Increments the wrong packet counter. + */ + public void addWrongPacket() { + this.wrongPacketCount++; + } + + /** + * Resets wrong packet count. + */ + public void resetWrongPacket() { + this.wrongPacketCount = 0; + } + + @Override + public long getTime() { + return this.time; + } + + /** + * Sets the time value. + * + * @param time long value of time + */ + public void setTime(long time) { + this.time = time; + } +} diff --git a/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepPipelineFactory.java b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepPipelineFactory.java new file mode 100644 index 00000000..f32b87a8 --- /dev/null +++ b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepPipelineFactory.java @@ -0,0 +1,66 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcep.controller.impl; + +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.handler.timeout.IdleStateHandler; +import org.jboss.netty.handler.timeout.ReadTimeoutHandler; +import org.jboss.netty.util.ExternalResourceReleasable; +import org.jboss.netty.util.HashedWheelTimer; +import org.jboss.netty.util.Timer; + +/** + * Creates a ChannelPipeline for a server-side pcep channel. + */ +public class PcepPipelineFactory + implements ChannelPipelineFactory, ExternalResourceReleasable { + + protected Controller controller; + static final Timer TIMER = new HashedWheelTimer(); + protected IdleStateHandler idleHandler; + protected ReadTimeoutHandler readTimeoutHandler; + static final int DEFAULT_KEEP_ALIVE_TIME = 30; + static final int DEFAULT_DEAD_TIME = 120; + static final int DEFAULT_WAIT_TIME = 60; + + public PcepPipelineFactory(Controller controller) { + super(); + this.controller = controller; + this.idleHandler = new IdleStateHandler(TIMER, DEFAULT_DEAD_TIME, DEFAULT_KEEP_ALIVE_TIME, 0); + this.readTimeoutHandler = new ReadTimeoutHandler(TIMER, DEFAULT_WAIT_TIME); + } + + @Override + public ChannelPipeline getPipeline() throws Exception { + PcepChannelHandler handler = new PcepChannelHandler(controller); + + ChannelPipeline pipeline = Channels.pipeline(); + pipeline.addLast("pcepmessagedecoder", new PcepMessageDecoder()); + pipeline.addLast("pcepmessageencoder", new PcepMessageEncoder()); + pipeline.addLast("idle", idleHandler); + pipeline.addLast("waittimeout", readTimeoutHandler); + pipeline.addLast("handler", handler); + return pipeline; + } + + @Override + public void releaseExternalResources() { + TIMER.stop(); + } +} diff --git a/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/package-info.java b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/package-info.java new file mode 100644 index 00000000..d86eefc3 --- /dev/null +++ b/framework/src/onos/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Implementation of the PCEP client controller subsystem. + */ +package org.onosproject.pcep.controller.impl; diff --git a/framework/src/onos/protocols/pcep/pcepio/pom.xml b/framework/src/onos/protocols/pcep/pcepio/pom.xml new file mode 100755 index 00000000..d121a83e --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/pom.xml @@ -0,0 +1,77 @@ + + + + 4.0.0 + + + org.onosproject + onos-pcep-controller + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-pcepio + bundle + + ONOS Pcepio Protocol subsystem + + + + + org.onosproject + onos-api + + + org.onosproject + onlab-osgi + + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-annotations + + + + org.osgi + org.osgi.core + + + org.apache.karaf.shell + org.apache.karaf.shell.console + + + org.apache.felix + org.apache.felix.scr.annotations + + + + + + + org.apache.felix + maven-bundle-plugin + + + + + diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/PcepParseException.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/PcepParseException.java new file mode 100755 index 00000000..85bc33fb --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/PcepParseException.java @@ -0,0 +1,92 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.exceptions; + +/** + * Custom Exception for PCEP IO. + */ +public class PcepParseException extends Exception { + + private static final long serialVersionUID = 7960991379951448423L; + private byte errType = 0; + private byte errValue = 0; + + /** + * Default constructor to create a new exception. + */ + public PcepParseException() { + super(); + } + + /** + * Constructor to create exception from message and cause. + * + * @param message the detail of exception in string + * @param cause underlying cause of the error + */ + public PcepParseException(final String message, final Throwable cause) { + super(message, cause); + } + + /** + * Constructor to create exception from message. + * + * @param message the detail of exception in string + */ + public PcepParseException(final String message) { + super(message); + } + + /** + * Constructor to create exception from error type and error value. + * + * @param errType error type of pcep + * @param errValue error value of pcep + */ + public PcepParseException(final byte errType, final byte errValue) { + super(); + this.errType = errType; + this.errValue = errValue; + } + + /** + * Constructor to create exception from cause. + * + * @param cause underlying cause of the error + */ + public PcepParseException(final Throwable cause) { + super(cause); + } + + /** + * Returns error type for this exception. + * + * @return ErrorType + */ + public byte getErrorType() { + return this.errType; + } + + /** + * Returns error value for this exception. + * + * @return ErrorValue + */ + public byte getErrorValue() { + return this.errValue; + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/PcepTunnelAttributeException.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/PcepTunnelAttributeException.java new file mode 100755 index 00000000..25bdf5b6 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/PcepTunnelAttributeException.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.exceptions; + +/** + * Custom exception for Tunnel Attributes. + */ +public class PcepTunnelAttributeException extends Exception { + + private static final long serialVersionUID = 7860981378961458434L; + + /** + * Default constructor to create a new exception. + */ + public PcepTunnelAttributeException() { + super(); + } + + /** + * Constructor to create exception from message and cause. + * + * @param message the detail of exception in string + * @param cause underlying cause of the error + */ + public PcepTunnelAttributeException(final String message, final Throwable cause) { + super(message, cause); + } + + /** + * Constructor to create exception from message. + * + * @param message the detail of exception in string + */ + public PcepTunnelAttributeException(final String message) { + super(message); + } + + /** + * Constructor to create exception from cause. + * + * @param cause underlying cause of the error + */ + public PcepTunnelAttributeException(final Throwable cause) { + super(cause); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/package-info.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/package-info.java new file mode 100644 index 00000000..44d09f0d --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/exceptions/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * PCEP custom exceptions. + */ +package org.onosproject.pcepio.exceptions; diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcInitiatedLspRequest.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcInitiatedLspRequest.java new file mode 100755 index 00000000..6a2fdc88 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcInitiatedLspRequest.java @@ -0,0 +1,185 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity Provides PcInitiatedLspRequest for PCEP Initiate message. + * Reference : PCE initiated tunnel setup draft-ietf-pce-pce-initiated-lsp-03. + */ +public interface PcInitiatedLspRequest { + + /** + * Returns object of PcepSrpObject. + * + * @return srpObject PCEP SRP object + */ + PcepSrpObject getSrpObject(); + + /** + * Returns object of PcepLspObject. + * + * @return lspObject PCEP LSP object + */ + PcepLspObject getLspObject(); + + /** + * Returns object of PcepEndPointsObject. + * + * @return endPointsObject PCEP EndPoints object + */ + PcepEndPointsObject getEndPointsObject(); + + /** + * Returns object of PcepEroObject. + * + * @return eroObject PCEP ERO object + */ + PcepEroObject getEroObject(); + + /** + * Returns object of PcepAttribute. + * + * @return pcepAttribute PCEP Attributes + */ + PcepAttribute getPcepAttribute(); + + /** + * Sets PcepSrpObject. + * + * @param srpobj PCEP SRP object + */ + void setSrpObject(PcepSrpObject srpobj); + + /** + * Sets PcepLspObject. + * + * @param lspObject PCEP LSP object + */ + void setLspObject(PcepLspObject lspObject); + + /** + * Sets PcepEndPointsObject. + * + * @param endPointsObject PCEP EndPoints object + */ + void setEndPointsObject(PcepEndPointsObject endPointsObject); + + /** + * Sets PcepEroObject. + * + * @param eroObject PCEP ERO object + */ + void setEroObject(PcepEroObject eroObject); + + /** + * Sets PcepAttribute. + * + * @param pcepAttribute PCEP Attributes + */ + void setPcepAttribute(PcepAttribute pcepAttribute); + + /** + * Builder interface with get and set functions to build PcInitiatedLspRequest. + */ + interface Builder { + + /** + * Builds PcInitiatedLspRequest. + * + * @return PcInitiatedLspRequest + * @throws PcepParseException when mandatory object is not set + */ + PcInitiatedLspRequest build() throws PcepParseException; + + /** + * Returns object of PcepSrpObject. + * + * @return srpObject + */ + PcepSrpObject getSrpObject(); + + /** + * Returns object of PcepLspObject. + * + * @return lspObject + */ + PcepLspObject getLspObject(); + + /** + * Returns object of PcepEndPointsObject. + * + * @return endPointsObject + */ + PcepEndPointsObject getEndPointsObject(); + + /** + * Returns object of PcepEroObject. + * + * @return eroObject + */ + PcepEroObject getEroObject(); + + /** + * Returns object of PcepAttribute. + * + * @return pcepAttribute + */ + PcepAttribute getPcepAttribute(); + + /** + * Sets PcepSrpObject. + * + * @param srpobj PCEP SRP Object + * @return builder by setting PcepSrpObject + */ + Builder setSrpObject(PcepSrpObject srpobj); + + /** + * Sets PcepLspObject. + * + * @param lspObject PCEP LSP Object + * @return builder by setting PcepLspObject + */ + Builder setLspObject(PcepLspObject lspObject); + + /** + * Sets PcepEndPointsObject. + * + * @param endPointsObject EndPoints Object + * @return builder by setting PcepEndPointsObject + */ + Builder setEndPointsObject(PcepEndPointsObject endPointsObject); + + /** + * Sets PcepEroObject. + * + * @param eroObject PCEP ERO Object + * @return builder by setting PcepEroObject + */ + Builder setEroObject(PcepEroObject eroObject); + + /** + * Sets PcepAttribute. + * + * @param pcepAttribute PCEP Attributes + * @return builder by setting PcepAttribute + */ + Builder setPcepAttribute(PcepAttribute pcepAttribute); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepAttribute.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepAttribute.java new file mode 100644 index 00000000..122b943f --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepAttribute.java @@ -0,0 +1,166 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity which Provides List of PCEP Attributes. + */ +public interface PcepAttribute { + + /** + * writes lspa , bandwidth , Metriclist and Iro objects to the channel. + * + * @param bb of type channel buffer. + * @return object length index. + * @throws PcepParseException while writing objects to channel buffer + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Returns PcepLspaObject. + * + * @return LspaObject + */ + PcepLspaObject getLspaObject(); + + /** + * Returns PcepBandwidthObject. + * + * @return BandwidthObject + */ + PcepBandwidthObject getBandwidthObject(); + + /** + * Returns PcepIroObject. + * + * @return iroObject + */ + PcepIroObject getIroObject(); + + /** + * Sets the PcepBandwidthObject. + * + * @param bandwidthObject bandwidth object + */ + void setBandwidthObject(PcepBandwidthObject bandwidthObject); + + /** + * Sets the PcepLspaObject. + * + * @param lspaObject lspa object + */ + void setLspaObject(PcepLspaObject lspaObject); + + /** + * Sets the PcepIroObject. + * + * @param iroObject iro object + */ + void setIroObject(PcepIroObject iroObject); + + /** + * Returns PcepMetricObject List. + * + * @return list of metric objects + */ + LinkedList getMetricObjectList(); + + /** + * Sets PcepMetricObject List. + * + * @param llMetricList list of metric objects + */ + void setMetricObjectList(LinkedList llMetricList); + + /** + * Builder interface with get and set functions to build PcepAttribute. + */ + interface Builder { + + /** + * Builds PcepAttribute. + * + * @return PcepAttribute + */ + PcepAttribute build(); + + /** + * Returns PcepLspaObject. + * + * @return LspaObject + */ + PcepLspaObject getLspaObject(); + + /** + * Returns PcepBandwidthObject. + * + * @return BandwidthObject + */ + PcepBandwidthObject getBandwidthObject(); + + /** + * Returns PcepIroObject. + * + * @return iroObject + */ + PcepIroObject getIroObject(); + + /** + * Sets the PcepBandwidthObject. + * + * @param bandwidthObject bandwidth object + * @return Builder object for PcepAttrubute + */ + Builder setBandwidthObject(PcepBandwidthObject bandwidthObject); + + /** + * Sets the PcepLspaObject. + * + * @param lspaObject lspa object + * @return Builder object for PcepAttrubute + */ + Builder setLspaObject(PcepLspaObject lspaObject); + + /** + * Sets the PcepIroObject. + * + * @param iroObject iro object + * @return Builder object for PcepAttrubute + */ + Builder setIroObject(PcepIroObject iroObject); + + /** + * Returns PcepMetricObject List. + * + * @return list of metric objects + */ + LinkedList getMetricObjectList(); + + /** + * Sets PcepMetricObject List. + * + * @param llMetricList list of metric objects + * @return Builder object for PcepAttrubute + */ + Builder setMetricObjectList(LinkedList llMetricList); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java new file mode 100755 index 00000000..58d05821 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java @@ -0,0 +1,109 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; + +/** + * Abstraction of an entity providing PCEP Bandwidth Object. + */ +public interface PcepBandwidthObject { + + /** + * Returns bandwidth value. + * + * @return bandwidth value + */ + int getBandwidth(); + + /** + * Sets bandwidth with specified value. + * + * @param iBandwidth Bandwidth's value + */ + void setBandwidth(int iBandwidth); + + /** + * Writes the BandwidthObject into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException if bandwidth object header fails to write in channel buffer + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build bandwidth object. + */ + interface Builder { + + /** + * Builds BandwidthObject. + * + * @return BandwidthObject + * @throws PcepParseException if build fails while creating PcepBandwidthObject + */ + PcepBandwidthObject build() throws PcepParseException; + + /** + * Returns bandwidth object header. + * + * @return bandwidth object header + */ + PcepObjectHeader getBandwidthObjHeader(); + + /** + * Sets bandwidth object header and returns its builder. + * + * @param obj Bandwidth object header + * @return Builder by setting Bandwidth object header + */ + Builder setBandwidthObjHeader(PcepObjectHeader obj); + + /** + * Returns bandwidth value. + * + * @return bandwidth + */ + int getBandwidth(); + + /** + * Sets bandwidth value and return its builder. + * + * @param iBandwidth bandwidth value + * @return Builder by setting bandwidth + */ + Builder setBandwidth(int iBandwidth); + + /** + * Sets P flag in Bandwidth object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in Bandwidth object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepCloseMsg.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepCloseMsg.java new file mode 100644 index 00000000..00fad800 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepCloseMsg.java @@ -0,0 +1,143 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP Close Message. + */ +public interface PcepCloseMsg extends PcepObject, PcepMessage { + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns reason field in Close message. + * + * @return reason field + */ + byte getReason(); + + /** + * Sets reason field in Close message with specified value. + * + * @param value of Reason field + */ + void setReason(byte value); + + /** + * Returns LinkedList of Optional Tlv in Close Message. + * + * @return list of optional tlv + */ + LinkedList getOptionalTlv(); + + /** + * Sets LinkedList of Optional Tlvs in Close Message. + * + * @param llOptionalTlv LinkedList of type PcepValueType + */ + void setOptionalTlv(LinkedList llOptionalTlv); + + @Override + void writeTo(ChannelBuffer channelBuffer) throws PcepParseException; + + /** + * Builder interface with get and set functions to build Close message. + */ + interface Builder extends PcepMessage.Builder { + + @Override + PcepCloseMsg build(); + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns Close Object header. + * + * @return Close Object header + */ + PcepObjectHeader getCloseObjHeader(); + + /** + * Sets close object header and returns its builder. + * + * @param obj close object header + * @return Builder by setting Close object header + */ + Builder setCloseObjHeader(PcepObjectHeader obj); + + /** + * Returns reason field in Close message. + * + * @return reason field in Close message + */ + byte getReason(); + + /** + * Sets reason field and return its builder. + * + * @param value of Reason field + * @return builder by setting reason field + */ + Builder setReason(byte value); + + /** + * Returns LinkedList of Optional Tlvs. + * + * @return list of optional tlv + */ + LinkedList getOptionalTlv(); + + /** + * Sets LinkedList of Optional Tlvs in Close Message. + * + * @param llOptionalTlv list of optional tlv + * @return Builder by setting Optional Tlvs + */ + Builder setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Sets P flag in Close object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in Close object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepEndPointsObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepEndPointsObject.java new file mode 100755 index 00000000..92d43874 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepEndPointsObject.java @@ -0,0 +1,139 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; + +/** + * Abstraction of an entity providing PCEP End Points Object. + */ +public interface PcepEndPointsObject { + + /** + * Returns Source IpAddress from End Points Object. + * + * @return Source IpAddress from End Points Object + */ + int getSourceIpAddress(); + + /** + * Sets Source IpAddress in End Points Object. + * + * @param sourceIpAddress Source IP Address + */ + void setSourceIpAddress(int sourceIpAddress); + + /** + * Returns Destination IpAddress from End Points Object. + * + * @return Destination IpAddress from End Points Object + */ + int getDestIpAddress(); + + /** + * Sets Destination IpAddress in End Points Object. + * + * @param destIpAddress Destination IP Address + */ + void setDestIpAddress(int destIpAddress); + + /** + * Writes the EndPointsObject into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing EndPointObject into ChannelBuffer + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build EndPoints object. + */ + interface Builder { + + /** + * Builds End Points Object. + * + * @return End Points Object + * @throws PcepParseException while building EndPointObject + */ + PcepEndPointsObject build() throws PcepParseException; + + /** + * Returns End Points Object header. + * + * @return End Points Object header + */ + PcepObjectHeader getEndPointsObjHeader(); + + /** + * Sets End Points Object header and returns its builder. + * + * @param obj End Points Object header + * @return Builder by setting End Points Object header + */ + Builder setEndPointsObjHeader(PcepObjectHeader obj); + + /** + * Returns Source IpAddress from End Points Object. + * + * @return Source IpAddress from End Points Object + */ + int getSourceIpAddress(); + + /** + * Sets Source IpAddress in End Points Object and returns builder. + * + * @param sourceIpAddress Source IP Address + * @return Builder by setting Source IpAddress in End Points Object + */ + Builder setSourceIpAddress(int sourceIpAddress); + + /** + * Returns Destination IpAddress from End Points Object. + * + * @return Destination IpAddress from End Points Object + */ + int getDestIpAddress(); + + /** + * Sets Destination IpAddress in End Points Object. + * + * @param destIpAddress Destination IP Address + * @return Builder by setting Destination IpAddress in End Points Object + */ + Builder setDestIpAddress(int destIpAddress); + + /** + * Sets P flag in Bandwidth object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in Bandwidth object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepEroObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepEroObject.java new file mode 100755 index 00000000..3af6b759 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepEroObject.java @@ -0,0 +1,112 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP ERO Object. + */ +public interface PcepEroObject { + + /** + * Return LinkedList of SubObjects of ERO Object. + * + * @return list of subobjects + */ + LinkedList getSubObjects(); + + /** + * Sets LinkedList of SubObjects in ERO Object. + * + * @param llSubObjects list of subobjects + */ + void setSubObjects(LinkedList llSubObjects); + + /** + * Writes the ERO Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing ERO Object into ChannelBuffer + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build ERO object. + */ + interface Builder { + + /** + * Builds ERO Object. + * + * @return ERO Object + */ + PcepEroObject build(); + + /** + * Returns ERO Object Header. + * + * @return ERO Object Header + */ + PcepObjectHeader getEroObjHeader(); + + /** + * Sets ERO Object header and returns its builder. + * + * @param obj ERO Object header + * @return Builder by setting ERO Object header + */ + Builder setEroObjHeader(PcepObjectHeader obj); + + /** + * Returns LinkedList of SubObjects in ERO Objects. + * + * @return list of subobjects + */ + LinkedList getSubObjects(); + + /** + * Sets LinkedList of SubObjects and returns its builder. + * + * @param llSubObjects list of SubObjects + * @return Builder by setting list of SubObjects + */ + Builder setSubObjects(LinkedList llSubObjects); + + /** + * Sets P flag in ERO object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in ERO object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepError.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepError.java new file mode 100755 index 00000000..b61bfb9f --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepError.java @@ -0,0 +1,136 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity which provides PCEP error for PCEP error message. + */ +public interface PcepError { + + /** + * Returns the PcepRPObject List. + * + * @return list of type PcepRPObject + */ + LinkedList getRPObjList(); + + /** + * Sets the RP Objects lists. + * + * @param llRPObjList list of type PcepRPObject + */ + void setRPObjList(LinkedList llRPObjList); + + /** + * Returns the PcepTEObject List. + * + * @return list of type PcepTEObject + */ + LinkedList getTEObjList(); + + /** + * Sets the TE Objects lists. + * + * @param llTEObjList list of type PcepTEObject + */ + void setTEObjList(LinkedList llTEObjList); + + /** + * Returns the PcepErrorObject. + * + * @return list of type PcepErrorObject + */ + LinkedList getErrorObjList(); + + /** + * Sets the Error Objects lists. + * + * @param llErrorObjList list of type PcepErrorObject + */ + void setErrorObjList(LinkedList llErrorObjList); + + /** + * Writes the byte stream of PCEP error to the channel buffer. + * + * @param bb of type channel buffer + * @return object length index + * @throws PcepParseException while writing Error part into ChannelBuffer + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build PcepError. + */ + interface Builder { + + /** + * Builds PcepError Object. + * + * @return PcepError Object + */ + PcepError build(); + + /** + * Returns the PcepRPObject. + * + * @return list of type PcepRPObject + */ + LinkedList getRPObjList(); + + /** + * Sets RP Object lists and returns its builder. + * + * @param llRPObjList list of type PcepRpObject + * @return builder by setting Linked list of RP Object + */ + Builder setRPObjList(LinkedList llRPObjList); + + /** + * Returns the PcepTEObject. + * + * @return llTEObjList of type PcepTEObject + */ + LinkedList getTEObjList(); + + /** + * Sets TE Object lists and returns its builder. + * + * @param llTEObjList list of type PcepTEObject + * @return builder by setting list of type PcepTEObject + */ + Builder setTEObjList(LinkedList llTEObjList); + + /** + * Returns the PcepErrorObject. + * + * @return list of type PcepErrorObject + */ + LinkedList getErrorObjList(); + + /** + * Sets Error Object lists and returns its builder. + * + * @param llErrorObjList list of type PcepErrorObject + * @return builder by setting list of type PcepErrorObject + */ + Builder setErrorObjList(LinkedList llErrorObjList); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorInfo.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorInfo.java new file mode 100755 index 00000000..0c625a03 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorInfo.java @@ -0,0 +1,93 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity which provides PCEP Error Info. + * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02. + */ +public interface PcepErrorInfo { + + /** + * Returns whether error info list is present or not. + * + * @return true if error info present, false otherwise + */ + boolean isErrorInfoPresent(); + + /** + * Reads from channel buffer for TE and RP objects. + * + * @param bb of channel buffer + * @throws PcepParseException while parsing Error info part. + */ + void read(ChannelBuffer bb) throws PcepParseException; + + /** + * Writes byte stream of PCEP error info to channel buffer. + * + * @param bb of type channel buffer + * @throws PcepParseException while writing Error info part into Channel Buffer. + */ + void write(ChannelBuffer bb) throws PcepParseException; + + /** + * Returns Error Value in PCEP-ERROR Object. + * + * @return list of Error Value in PCEP-ERROR Object + */ + LinkedList getErrorValue(); + + /** + * Returns Error Type in PCEP-ERROR Object. + * + * @return list of Error Type in PCEP-ERROR Object + */ + LinkedList getErrorType(); + + /** + * Builder interface with get and set functions to build ErrorInfo. + */ + interface Builder { + + /** + * Builds ErrorInfo Object. + * + * @return ErrorInfo Object. + */ + PcepErrorInfo build(); + + /** + * Returns list of PcepError. + * + * @return list of PcepError + */ + LinkedList getPcepErrorList(); + + /** + * Sets PcepError lists and returns its builder. + * + * @param llPcepErrorList list of PcepError + * @return builder by setting list of PcepError. + */ + Builder setPcepErrorList(LinkedList llPcepErrorList); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorMsg.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorMsg.java new file mode 100644 index 00000000..ff06885d --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorMsg.java @@ -0,0 +1,109 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.ErrorObjListWithOpen; + +/** + * Abstraction of an entity providing PCEP Error Message. + */ +public interface PcepErrorMsg extends PcepMessage { + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns Object of ErrorObjListWithOpen. + * + * @return Object of ErrorObjListWithOpen + */ + ErrorObjListWithOpen getErrorObjListWithOpen(); + + /** + * Sets errObjListWithOpen object. + * + * @param errObjListWithOpen error object List with open object + */ + void setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen); + + /** + * Returns Object of PcepErrorInfo. + * + * @return Object of PcepErrorInfo + */ + PcepErrorInfo getPcepErrorInfo(); + + /** + * Sets errInfo Object. + * + * @param errInfo error information + */ + void setPcepErrorInfo(PcepErrorInfo errInfo); + + @Override + void writeTo(ChannelBuffer channelBuffer) throws PcepParseException; + + /** + * Builder interface with get and set functions to build PCEP Error message. + */ + interface Builder extends PcepMessage.Builder { + + @Override + PcepErrorMsg build(); + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns Object of ErrorObjListWithOpen. + * + * @return Object of ErrorObjListWithOpen + */ + ErrorObjListWithOpen getErrorObjListWithOpen(); + + /** + * Sets errObjListWithOpen object. + * + * @param errObjListWithOpen error object with open object + * @return builder by setting Object of ErrorObjListWithOpen + */ + Builder setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen); + + /** + * Returns Object of PcepErrorInfo. + * + * @return Object of PcepErrorInfo + */ + PcepErrorInfo getPcepErrorInfo(); + + /** + * Sets errInfo Object. + * + * @param errInfo error information + * @return builder by getting Object of PcepErrorInfo + */ + Builder setPcepErrorInfo(PcepErrorInfo errInfo); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorObject.java new file mode 100644 index 00000000..16374d5b --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepErrorObject.java @@ -0,0 +1,169 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP Error Object. + */ +public interface PcepErrorObject { + + /** + * Returns Error Type in Error Object. + * + * @return Error Type in Error Object + */ + int getErrorType(); + + /** + * Sets Error Type in Error Object. + * + * @param value Error Type + */ + void setErrorType(byte value); + + /** + * Returns Error Value in Error Object. + * + * @return Error Value + */ + byte getErrorValue(); + + /** + * Sets Error Value in Error Object. + * + * @param value Error Value + */ + void setErrorValue(byte value); + + /** + * Returns Optional Tlvs in Error Object. + * + * @return list of Optional Tlvs in Error Object + */ + LinkedList getOptionalTlv(); + + /** + * Sets Optional Tlvs in Error Object. + * + * @param llOptionalTlv list of Optional Tlvs + */ + void setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Writes the Error Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing Error Object into ChannelBuffer + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build Error object. + */ + interface Builder { + + /** + * Builds Error Object. + * + * @return Error Object. + */ + PcepErrorObject build(); + + /** + * Returns Error Object header. + * + * @return Error Object header + */ + PcepObjectHeader getErrorObjHeader(); + + /** + * Sets Error Object header and returns its Builder. + * + * @param obj Error Object header + * @return Builder by setting Error Object header + */ + Builder setErrorObjHeader(PcepObjectHeader obj); + + /** + * Returns Error Type in Error Object. + * + * @return Error Type in Error Object + */ + int getErrorType(); + + /** + * Sets Error Type and returns its builder. + * + * @param value of Error-Type field + * @return builder by setting Error Type field. + */ + Builder setErrorType(byte value); + + /** + * Returns Error Value in Error Object. + * + * @return Error Value + */ + byte getErrorValue(); + + /** + * Sets Error Value and returns its builder. + * + * @param value of Error-Value field + * @return Builder by setting Error Value field. + */ + Builder setErrorValue(byte value); + + /** + * Returns list of Optional Tlvs of Error Object. + * + * @return list of Optional Tlvs of Error Object + */ + LinkedList getOptionalTlv(); + + /** + * Sets Optional Tlvs of Error Object and returns its Builder. + * + * @param llOptionalTlv Optional Tlvs of Error Object + * @return Builder by setting Optional Tlvs. + */ + Builder setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Sets P flag in Error object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in Error object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFactories.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFactories.java new file mode 100644 index 00000000..85416f98 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFactories.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.ver1.PcepFactoryVer1; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Abstraction to provide the version for PCEP. + */ +public final class PcepFactories { + + protected static final Logger log = LoggerFactory.getLogger(PcepFactories.class); + + private static final GenericReader GENERIC_READER = new GenericReader(); + + public static final byte SHIFT_FLAG = 5; + + private PcepFactories() { + } + + /** + * Returns the instance of PCEP Version. + * + * @param version PCEP version + * @return PCEP version + */ + public static PcepFactory getFactory(PcepVersion version) { + switch (version) { + case PCEP_1: + return PcepFactoryVer1.INSTANCE; + default: + throw new IllegalArgumentException("Unknown version: " + version); + } + } + + private static class GenericReader implements PcepMessageReader { + + @Override + public PcepMessage readFrom(ChannelBuffer bb) throws PcepParseException { + + if (!bb.readable()) { + throw new PcepParseException("Empty message received"); + } + + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Ver | Flags | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Currently Version 1 is supported + * Currently no flags are used, it is all ignored + */ + + byte packetVersion = bb.getByte(bb.readerIndex()); + packetVersion = (byte) (packetVersion >> SHIFT_FLAG); + PcepFactory factory; + + switch (packetVersion) { + + case 1: + factory = org.onosproject.pcepio.protocol.ver1.PcepFactoryVer1.INSTANCE; + break; + default: + throw new PcepParseException("Unknown Packet version: " + packetVersion); + } + return factory.getReader().readFrom(bb); + } + } + + /** + * Returns GENERIC_READER. + * + * @return GENERIC_READER + */ + public static PcepMessageReader getGenericReader() { + return GENERIC_READER; + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFactory.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFactory.java new file mode 100755 index 00000000..1a31e0a3 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFactory.java @@ -0,0 +1,255 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +/** + * Abstraction of an Message factory providing Builder functions to PCEP Messages and Objects. + * + */ +public interface PcepFactory { + + /** + * To get Builder Object for Open Message. + * + * @return Builder Object for Open Message + */ + PcepOpenMsg.Builder buildOpenMsg(); + + /** + * To get Builder Object for Open Object. + * + * @return Builder Object for Open Object + */ + PcepOpenObject.Builder buildOpenObject(); + + /** + * To get Builder Object for Keepalive Message. + * + * @return Builder Object for Keepalive Message + */ + PcepKeepaliveMsg.Builder buildKeepaliveMsg(); + + /** + * To get Builder Object for Close Message. + * + * @return Builder Object for Close Message + */ + PcepCloseMsg.Builder buildCloseMsg(); + + /** + * To get Builder Object for Report Message. + * + * @return Builder Object for Report Message + */ + PcepReportMsg.Builder buildReportMsg(); + + /** + * To get Builder Object for Update Message. + * + * @return Builder Object for Update Message + */ + PcepUpdateMsg.Builder buildUpdateMsg(); + + /** + * To get Builder Object for Initiate Message. + * + * @return Builder Object for Initiate Message + */ + PcepInitiateMsg.Builder buildPcepInitiateMsg(); + + /** + * To get Builder Object for LSP Object. + * + * @return Builder Object for LSP Object + */ + PcepLspObject.Builder buildLspObject(); + + /** + * To get Builder Object for SRP Object. + * + * @return Builder Object for SRP Object + */ + PcepSrpObject.Builder buildSrpObject(); + + /** + * To get Builder Object for EndPoints Object. + * + * @return Builder Object for EndPoints Object + */ + PcepEndPointsObject.Builder buildEndPointsObject(); + + /** + * To get Builder Object for ERO Object. + * + * @return Builder Object for ERO Object + */ + PcepEroObject.Builder buildEroObject(); + + /** + * To get Builder Object for RRO Object. + * + * @return Builder Object for RRO Object + */ + PcepRroObject.Builder buildRroObject(); + + /** + * To get Builder Object for LSPA Object. + * + * @return Builder Object for LSPA Object + */ + PcepLspaObject.Builder buildLspaObject(); + + /** + * To get Builder Object for IRO Object. + * + * @return Builder Object for IRO Object + */ + PcepIroObject.Builder buildIroObject(); + + /** + * To get Builder Object for METRIC Object. + * + * @return Builder Object for METRIC Object + */ + PcepMetricObject.Builder buildMetricObject(); + + /** + * To get Builder Object for Bandwidth Object. + * + * @return Builder Object for Bandwidth Object + */ + PcepBandwidthObject.Builder buildBandwidthObject(); + + /** + * Returns PCEP Message Reader. + * + * @return PCEP Message Reader + */ + PcepMessageReader getReader(); + + /** + * Returns PCEP version. + * + * @return PCEP version + */ + PcepVersion getVersion(); + + /** + * Returns PcepStateReport. + * + * @return PcepStateReport + */ + PcepStateReport.Builder buildPcepStateReport(); + + /** + * Returns PcepUpdateRequest. + * + * @return PcepUpdateRequest + */ + PcepUpdateRequest.Builder buildPcepUpdateRequest(); + + /** + * Returns PcInitiatedLspRequest. + * + * @return PcInitiatedLspRequest + */ + PcInitiatedLspRequest.Builder buildPcInitiatedLspRequest(); + + /** + * Returns PcepMsgPath. + * + * @return PcepMsgPath + */ + PcepMsgPath.Builder buildPcepMsgPath(); + + /** + * Return PcepAttribute list. + * + * @return PcepAttribute + */ + PcepAttribute.Builder buildPcepAttribute(); + + /** + * To get Builder Object for LabelUpdate message. + * + * @return Builder Object for LabelUpdate message + */ + PcepLabelUpdateMsg.Builder buildPcepLabelUpdateMsg(); + + /** + * To get Builder Object for PcepLabelUpdate Object. + * + * @return Builder Object for PcepLabelUpdate Object + */ + PcepLabelUpdate.Builder buildPcepLabelUpdateObject(); + + /** + * To get Builder Object for PcepLabel Object. + * + * @return Builder Object for PcepLabel Object + */ + PcepLabelObject.Builder buildLabelObject(); + + /** + * To get Builder Object for Error Message. + * + * @return Builder Object for Error Message + */ + PcepErrorMsg.Builder buildPcepErrorMsg(); + + /** + * To get Builder Object for Error Object. + * + * @return Builder Object for Error Object + */ + PcepErrorObject.Builder buildPcepErrorObject(); + + /** + * To get Builder Object for FecIpv4Adjacency. + * + * @return Builder Object for FecIpv4Adjacency + */ + PcepFecObjectIPv4Adjacency.Builder buildFecIpv4Adjacency(); + + /** + * To get Builder Object for ErrorInfo. + * + * @return Builder Object for ErrorInfo + */ + PcepErrorInfo.Builder buildPcepErrorInfo(); + + /** + * To get Builder Object for PcepError. + * + * @return Builder Object for PcepError + */ + PcepError.Builder buildPcepError(); + + /** + * To get Builder Object for PcepLabelRangeObject. + * + * @return Builder Object for PcepLabelRangeObject + */ + PcepLabelRangeObject.Builder buildPcepLabelRangeObject(); + + /** + * To get Builder Object for PcepLabelRangeResvMsg. + * + * @return Builder Object for PcepLabelRangeResvMsg + */ + PcepLabelRangeResvMsg.Builder buildPcepLabelRangeResvMsg(); +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObject.java new file mode 100755 index 00000000..2df7cc9c --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObject.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP FEC Object. + */ +public interface PcepFecObject { + + /** + * Returns PCEP Version of FEC Object. + * + * @return PCEP Version of FEC Object + */ + PcepVersion getVersion(); + + /** + * Returns FEC Object type. + * + * @return FEC Object type + */ + int getType(); + + /** + * Writes the FEC into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing FEC Object into Channel Buffer. + */ + int write(ChannelBuffer bb) throws PcepParseException; +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4.java new file mode 100755 index 00000000..5ed4e1e3 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4.java @@ -0,0 +1,104 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; + +/** + * Abstraction of an entity providing PCEP FEC Object of Type 1 IPv4 Node ID. + */ +public interface PcepFecObjectIPv4 extends PcepFecObject { + + /** + * Returns NodeID of FEC Object. + * + * @return NodeID of FEC Object + */ + int getNodeID(); + + /** + * Sets NodeID with specified value. + * + * @param value node id + */ + void setNodeID(int value); + + @Override + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build FEC object. + */ + interface Builder { + + /** + * Builds FEC Object IPv4. + * + * @return FEC Object IPv4 + * @throws PcepParseException while creating FEC IPv4 Object. + */ + PcepFecObjectIPv4 build() throws PcepParseException; + + /** + * Returns FEC Object IPv4 header. + * + * @return FEC Object IPv4 header + */ + PcepObjectHeader getFecIpv4ObjHeader(); + + /** + * Sets FEC Object IPv4 header and returns its builder. + * + * @param obj FEC Object IPv4 header + * @return Builder by setting FEC Object IPv4 header + */ + Builder setFecIpv4ObjHeader(PcepObjectHeader obj); + + /** + * Returns NodeID of FEC Object. + * + * @return NodeID of FEC Object + */ + int getNodeID(); + + /** + * Sets NodeID and returns its builder. + * + * @param value node id + * @return builder by setting NodeID + */ + Builder setNodeID(int value); + + /** + * Sets P flag in FEC object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in FEC object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4Adjacency.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4Adjacency.java new file mode 100755 index 00000000..55205299 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4Adjacency.java @@ -0,0 +1,133 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; + +/** + * Abstraction of an entity providing FEC Object of Type 3 IPv4 Adjacency. + */ +public interface PcepFecObjectIPv4Adjacency extends PcepFecObject { + + /** + * Returns Local IPv4Address of FEC Object. + * + * @return Local IPv4Address of FEC Object + */ + int getLocalIPv4Address(); + + /** + * Sets Local IPv4Address with specified value. + * + * @param value Local IPv4Address + */ + void seLocalIPv4Address(int value); + + /** + * Returns Remote IPv4Address of FEC Object. + * + * @return Remote IPv4Address of FEC Object + */ + int getRemoteIPv4Address(); + + /** + * Sets Remote IPv4Address with specified value. + * + * @param value Remote IPv4Address + */ + void seRemoteIPv4Address(int value); + + @Override + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build FEC object. + */ + interface Builder { + + /** + * Builds FEC Object IPv4 Adjacency. + * + * @return FEC Object IPv4 Adjacency + * @throws PcepParseException while building FEC IPv4 Adjacency object. + */ + PcepFecObjectIPv4Adjacency build() throws PcepParseException; + + /** + * Returns FEC Object IPv4 Adjacency header. + * + * @return FEC Object IPv4 Adjacency header + */ + PcepObjectHeader getFecIpv4AdjacencyObjHeader(); + + /** + * Sets FEC Object IPv4 Adjacency header and returns its builder. + * + * @param obj FEC Object IPv4 Adjacency header + * @return Builder by setting FEC Object IPv4 header + */ + Builder setFecIpv4AdjacencyObjHeader(PcepObjectHeader obj); + + /** + * Returns Local IPv4Address of FEC Object. + * + * @return Local IPv4Address of FEC Object + */ + int getLocalIPv4Address(); + + /** + * Sets Local IPv4Address and returns its builder. + * + * @param value Local IPv4Address + * @return Builder by setting Local IPv4Address + */ + Builder seLocalIPv4Address(int value); + + /** + * Sets Remote IPv4Address with specified value. + * + * @return Remote IPv4 Address + */ + int getRemoteIPv4Address(); + + /** + * Sets Remote IPv4Address and returns its builder. + * + * @param value Remote IPv4Address + * @return Builder by setting Remote IPv4Address + */ + Builder seRemoteIPv4Address(int value); + + /** + * Sets P flag in FEC object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in FEC object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4UnnumberedAdjacency.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4UnnumberedAdjacency.java new file mode 100755 index 00000000..d240445e --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv4UnnumberedAdjacency.java @@ -0,0 +1,191 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; + +/** + * Abstraction of an entity providing PCEP FEC Object of Type is 5 Unnumbered Adjacency with IPv4 NodeIDs. + */ +public interface PcepFecObjectIPv4UnnumberedAdjacency extends PcepFecObject { + + /** + * Returns Local NodeID of FEC Object. + * + * @return Local NodeID of FEC Object + */ + int getLocalNodeID(); + + /** + * Sets Local NodeID with specified value. + * + * @param value Local NodeID + */ + void setLocalNodeID(int value); + + /** + * Returns Local InterfaceID of FEC Object. + * + * @return Local InterfaceID of FEC Object + */ + int getLocalInterfaceID(); + + /** + * Sets Local InterfaceID with specified value. + * + * @param value Local InterfaceID + */ + void setLocalInterfaceID(int value); + + /** + * Returns Remote NodeID of FEC Object. + * + * @return Remote NodeID of FEC Object + */ + int getRemoteNodeID(); + + /** + * Sets Remote NodeID with specified value. + * + * @param value Remote NodeID + */ + void setRemoteNodeID(int value); + + /** + * Returns Remote InterfaceID of FEC Object. + * + * @return Remote InterfaceID of FEC Object + */ + int getRemoteInterfaceID(); + + /** + * Sets Remote InterfaceID with specified value. + * + * @param value Remote InterfaceID + */ + void setRemoteInterfaceID(int value); + + @Override + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build bandwidth object. + */ + interface Builder { + + /** + * Builds FEC Unnumbered Adjacency with IPv4 Object. + * + * @return FEC Unnumbered Adjacency with IPv4 Object + * @throws PcepParseException when building FEC IPv4 Unnumbered Adjacency object. + */ + PcepFecObjectIPv4UnnumberedAdjacency build() throws PcepParseException; + + /** + * Returns FEC Unnumbered Adjacency with IPv4 header. + * + * @return FEC Unnumbered Adjacency with IPv4 header + */ + PcepObjectHeader getFecIpv4UnnumberedAdjacencyObjHeader(); + + /** + * Sets FEC Unnumbered Adjacency with IPv4 header and returns its builder. + * + * @param obj FEC Unnumbered Adjacency with IPv4 header + * @return Builder by setting FEC Unnumbered Adjacency with IPv4 header + */ + Builder setFecIpv4UnnumberedAdjacencyObjHeader(PcepObjectHeader obj); + + /** + * Returns Local NodeID of FEC Object. + * + * @return Local NodeID of FEC Object + */ + int getLocalNodeID(); + + /** + * Sets Local NodeID and returns its builder. + * + * @param value Local NodeID + * @return Builder by setting Local NodeID + */ + Builder setLocalNodeID(int value); + + /** + * Returns Local InterfaceID of FEC Object. + * + * @return Local InterfaceID of FEC Object + */ + int getLocalInterfaceID(); + + /** + * Sets Local InterfaceID and returns its builder. + * + * @param value Local InterfaceID + * @return Builder by setting Local InterfaceID + */ + Builder setLocalInterfaceID(int value); + + /** + * Returns Remote NodeID of FEC Object. + * + * @return Remote NodeID of FEC Object + */ + int getRemoteNodeID(); + + /** + * Sets Remote NodeID and returns its builder. + * + * @param value Remote NodeID + * @return Builder by setting Remote NodeID + */ + Builder setRemoteNodeID(int value); + + /** + * Returns Remote InterfaceID of FEC Object. + * + * @return Remote InterfaceID of FEC Object + */ + int getRemoteInterfaceID(); + + /** + * Sets Remote InterfaceID and returns its builder. + * + * @param value Remote InterfaceID + * @return Builder by setting Remote InterfaceID + */ + Builder setRemoteInterfaceID(int value); + + /** + * Sets P flag in FEC object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in FEC object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv6.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv6.java new file mode 100755 index 00000000..1c29b76a --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv6.java @@ -0,0 +1,104 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; + +/** + * Abstraction of an entity providing FEC Object of Type is 2 IPv6 Node ID. + */ +public interface PcepFecObjectIPv6 extends PcepFecObject { + + /** + * Returns NodeID of FEC Object. + * + * @return NodeID of FEC Object + */ + byte[] getNodeID(); + + /** + * Sets NodeID with specified value. + * + * @param value node id + */ + void setNodeID(byte[] value); + + @Override + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build FEC object. + */ + interface Builder { + + /** + * Builds FEC Object IPv6. + * + * @return FEC Object IPv6 + * @throws PcepParseException while building FEC IPv6 Object. + */ + PcepFecObjectIPv6 build() throws PcepParseException; + + /** + * Returns FEC Object IPv6 header. + * + * @return FEC Object IPv6 header + */ + PcepObjectHeader getFecIpv6ObjHeader(); + + /** + * Sets FEC Object IPv6 header and returns its builder. + * + * @param obj FEC Object IPv6 header + * @return Builder by setting FEC Object IPv6 header + */ + Builder setFecIpv6ObjHeader(PcepObjectHeader obj); + + /** + * Returns NodeID of FEC Object. + * + * @return NodeID of FEC Object + */ + byte[] getNodeID(); + + /** + * Sets NodeID and returns its builder. + * + * @param value node id + * @return Builder by setting NodeID + */ + Builder setNodeID(byte[] value); + + /** + * Sets P flag in FEC object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in FEC object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv6Adjacency.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv6Adjacency.java new file mode 100755 index 00000000..ef802780 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepFecObjectIPv6Adjacency.java @@ -0,0 +1,133 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; + +/** + * Abstraction of an entity providing FEC Object of Type is 4 IPv6 Adjacency. + */ +public interface PcepFecObjectIPv6Adjacency extends PcepFecObject { + + /** + * Returns Local IPv6Address of FEC Object. + * + * @return Local IPv6Address of FEC Object + */ + byte[] getLocalIPv6Address(); + + /** + * Sets Local IPv6Address with specified value. + * + * @param value Local IPv6Address + */ + void seLocalIPv6Address(byte[] value); + + /** + * Returns Remote IPv6Address of FEC Object. + * + * @return Remote IPv6Address of FEC Object + */ + byte[] getRemoteIPv6Address(); + + /** + * Sets Remote IPv6Address with specified value. + * + * @param value Remote IPv6Address + */ + void seRemoteIPv6Address(byte[] value); + + @Override + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build FEC object. + */ + interface Builder { + + /** + * Builds FEC Object IPv6 Adjacency. + * + * @return FEC Object IPv6 Adjacency + * @throws PcepParseException while building FEC IPv6 Adjacency object. + */ + PcepFecObjectIPv6Adjacency build() throws PcepParseException; + + /** + * Returns FEC Object IPv6 Adjacency header. + * + * @return FEC Object IPv6 Adjacency header + */ + PcepObjectHeader getFecIpv6AdjacencyObjHeader(); + + /** + * Sets FEC Object IPv6 Adjacency header and returns its builder. + * + * @param obj FEC Object IPv6 Adjacency header + * @return Builder by setting FEC Object IPv6 Adjacency header + */ + Builder setFecIpv6AdjacencyObjHeader(PcepObjectHeader obj); + + /** + * Returns Local IPv6Address of FEC Object. + * + * @return Local IPv6Address of FEC Object + */ + byte[] getLocalIPv6Address(); + + /** + * Sets Local IPv6Address and returns its builder. + * + * @param value Local IPv6Address + * @return Builder by setting Local IPv6Address + */ + Builder setLocalIPv6Address(byte[] value); + + /** + * Returns Remote IPv6Address of FEC Object. + * + * @return Remote IPv6Address of FEC Object + */ + byte[] getRemoteIPv6Address(); + + /** + * Sets Remote IPv6Address and returns its builder. + * + * @param value Remote IPv6Address + * @return Builder by setting Remote IPv6Address + */ + Builder setRemoteIPv6Address(byte[] value); + + /** + * Sets P flag in FEC object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in FEC object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepInitiateMsg.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepInitiateMsg.java new file mode 100755 index 00000000..2b061430 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepInitiateMsg.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Initiate Message. + */ +public interface PcepInitiateMsg extends PcepObject, PcepMessage { + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns list of PcInitiatedLspRequestList. + * + * @return list of PcInitiatedLspRequestList + */ + LinkedList getPcInitiatedLspRequestList(); + + /** + * Sets list of PcInitiatedLspRequestList. + * + * @param llPcInitiatedLspRequestList list of PcInitiatedLspRequestList + */ + void setPcInitiatedLspRequestList(LinkedList llPcInitiatedLspRequestList); + + @Override + void writeTo(ChannelBuffer channelBuffer) throws PcepParseException; + + /** + * Builder interface with get and set functions to build Initiate message. + */ + interface Builder extends PcepMessage.Builder { + + @Override + PcepInitiateMsg build(); + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns list of PcInitiatedLspRequestList. + * + * @return list of PcInitiatedLspRequestList + */ + LinkedList getPcInitiatedLspRequestList(); + + /** + * Sets PcInitiatedLspRequestList. + * + * @param llPcInitiatedLspRequestList list of PcInitiatedLspRequestList + * @return builder by setting list of PcInitiatedLspRequestList + */ + Builder setPcInitiatedLspRequestList(LinkedList llPcInitiatedLspRequestList); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepInterLayerObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepInterLayerObject.java new file mode 100755 index 00000000..675e0557 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepInterLayerObject.java @@ -0,0 +1,137 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; + +/** + * Abstraction of an entity providing PCEP INTER Layer Object. + */ +public interface PcepInterLayerObject { + + /** + * Returns N Flag in INTER Layer Object. + * + * @return N Flag in INTER Layer Object + */ + boolean getbNFlag(); + + /** + * Sets N Flag in INTER Layer Object with specified value. + * + * @param value N Flag + */ + void setbNFlag(boolean value); + + /** + * Returns I Flag in INTER Layer Object. + * + * @return I Flag in INTER Layer Object + */ + boolean getbIFlag(); + + /** + * Sets I Flag in INTER Layer Object with specified value. + * + * @param value I Flag + */ + void setbIFlag(boolean value); + + /** + * Writes the INTER Layer Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing Inter Layer Object. + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build INTER Layer object. + */ + interface Builder { + + /** + * Builds INTER Layer object. + * + * @return INTER Layer object + */ + PcepInterLayerObject build(); + + /** + * Returns INTER Layer object header. + * + * @return INTER Layer object header + */ + PcepObjectHeader getInterLayerObjHeader(); + + /** + * Sets INTER Layer object header and returns its builder. + * + * @param obj INTER Layer object header + * @return Builder by setting INTER Layer object header + */ + Builder setInterLayerObjHeader(PcepObjectHeader obj); + + /** + * Returns N Flag in INTER Layer Object. + * + * @return N Flag in INTER Layer Object + */ + boolean getbNFlag(); + + /** + * Sets N flag and return its builder. + * + * @param value N flag + * @return Builder by setting N flag + */ + Builder setbNFlag(boolean value); + + /** + * Returns I Flag in INTER Layer Object. + * + * @return I Flag in INTER Layer Object + */ + boolean getbIFlag(); + + /** + * Sets I flag and return its builder. + * + * @param value I flag + * @return Builder by setting N flag + */ + Builder setbIFlag(boolean value); + + /** + * Sets P flag in INTER Layer object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in INTER Layer object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepIroObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepIroObject.java new file mode 100755 index 00000000..a1c1fc59 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepIroObject.java @@ -0,0 +1,110 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP IRO Object. + */ +public interface PcepIroObject { + + /** + * Returns list of SubObjects. + * + * @return list of SubObjects + */ + LinkedList getSubObjects(); + + /** + * Sets list of SubObjects. + * + * @param llSubObjects list of SubObjects + */ + void setSubObjects(LinkedList llSubObjects); + + /** + * Writes the IRO into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing IRO object. + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build IRO object. + */ + interface Builder { + + /** + * Builds IRO Object. + * + * @return IRO Object + */ + PcepIroObject build(); + + /** + * Returns IRO object header. + * + * @return IRO object header + */ + PcepObjectHeader getIroObjHeader(); + + /** + * Sets IRO object header and returns its builder. + * + * @param obj IRO object header + * @return Builder by setting IRO object header + */ + Builder setIroObjHeader(PcepObjectHeader obj); + + /** + * Returns list of SubObjects. + * + * @return list of SubObjects + */ + LinkedList getSubObjects(); + + /** + * Sets list of SubObjects in IRO Object and returns its builder. + * + * @param llSubObjects list of SubObjects + * @return Builder by setting list of SubObjects + */ + Builder setSubObjects(LinkedList llSubObjects); + + /** + * Sets P flag in IRO object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in IRO object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepKeepaliveMsg.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepKeepaliveMsg.java new file mode 100755 index 00000000..160f0a2a --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepKeepaliveMsg.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; + +/** + * Abstraction of an entity providing PCEP Keepalive Message. + */ +public interface PcepKeepaliveMsg extends PcepObject, PcepMessage { + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + @Override + void writeTo(ChannelBuffer channelBuffer); + + /** + * Builder interface with get and set functions to build Keepalive message. + */ + interface Builder extends PcepMessage.Builder { + + @Override + PcepKeepaliveMsg build(); + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelObject.java new file mode 100755 index 00000000..b64c21e0 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelObject.java @@ -0,0 +1,171 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP Label Object. + */ +public interface PcepLabelObject { + + /** + * Returns O flag in Label Object. + * + * @return Boolean value + */ + boolean getOFlag(); + + /** + * Sets O flag in Label Object with specified value. + * + * @param value O flag + */ + void setOFlag(boolean value); + + /** + * Returns Label from Label Object. + * + * @return Label value + */ + int getLabel(); + + /** + * Sets Label field in Label Object with specified value. + * + * @param value Label + */ + void setLabel(int value); + + /** + * Returns list of Optional Tlvs. + * + * @return list of Optional Tlvs + */ + LinkedList getOptionalTlv(); + + /** + * Sets Optional Tlvs in Label Object. + * + * @param llOptionalTlv list of Optional Tlvs + */ + void setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Writes the Label Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing LABEL object into Channel Buffer. + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build Label object. + */ + interface Builder { + + /** + * Builds Label Object. + * + * @return Label Object + * @throws PcepParseException while building LABEL object. + */ + PcepLabelObject build() throws PcepParseException; + + /** + * Returns Label object header. + * + * @return Label object header + */ + PcepObjectHeader getLabelObjHeader(); + + /** + * Sets Label object header and returns its builder. + * + * @param obj Label object header + * @return Builder by setting Label object header + */ + Builder setLabelObjHeader(PcepObjectHeader obj); + + /** + * Returns O flag in Label Object. + * + * @return Label value + */ + boolean getOFlag(); + + /** + * Sets O flag and return its builder. + * + * @param value O flag + * @return Builder by setting O flag + */ + Builder setOFlag(boolean value); + + /** + * Returns Label from Label Object. + * + * @return Label value + */ + int getLabel(); + + /** + * Sets Label field and return its builder. + * + * @param value Label field + * @return Builder by setting Label field + */ + Builder setLabel(int value); + + /** + * Returns list of Optional Tlvs. + * + * @return list of Optional Tlvs + */ + LinkedList getOptionalTlv(); + + /** + * Sets list of Optional Tlvs and return its builder. + * + * @param llOptionalTlv list of Optional Tlvs + * @return Builder by setting list of Optional Tlvs + */ + Builder setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Sets P flag in Label object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in Label object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRange.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRange.java new file mode 100755 index 00000000..72d0a38e --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRange.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Label Range. + */ +public interface PcepLabelRange { + + /** + * Returns object of PCEP SRP Object. + * + * @return srpObject + */ + PcepSrpObject getSrpObject(); + + /** + * Sets PCEP SRP Object. + * + * @param srpObject SRP object. + */ + void setSrpObject(PcepSrpObject srpObject); + + /** + * Returns list of PcepLabelRangeObject. + * + * @return Label Range List + */ + LinkedList getLabelRangeList(); + + /** + * Sets list of PcepLabelRangeObject. + * + * @param llLabelRangeList Label Range List + */ + void setLabelRangeList(LinkedList llLabelRangeList); + + /** + * Write the byte stream of PcepLabelRange to channel buffer. + * + * @param bb of type channel buffer + * @return object length index + * @throws PcepParseException while writing LABEL RANGE into Channel Buffer. + */ + int write(ChannelBuffer bb) throws PcepParseException; +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRangeObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRangeObject.java new file mode 100755 index 00000000..9155434e --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRangeObject.java @@ -0,0 +1,182 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; + +/** + * Abstraction of an entity providing PCEP LabelRange Object. + */ +public interface PcepLabelRangeObject { + + /** + * Sets LabelRange Object header. + * + * @param obj LabelRange Object header + */ + void setLabelRangeObjHeader(PcepObjectHeader obj); + + /** + * Sets LabelType in LabelRange Object. + * + * @param labelType label type value + */ + void setLabelType(byte labelType); + + /** + * Sets RangeSize in LabelRange Object. + * + * @param rangeSize range size value + */ + void setRangeSize(int rangeSize); + + /** + * Sets LabelBase in LabelRange Object. + * + * @param labelBase label base value + */ + void setLabelBase(int labelBase); + + /** + * Returns LabelRange object header. + * + * @return LabelRange object header + */ + PcepObjectHeader getLabelRangeObjHeader(); + + /** + * Returns LabelType field in LabelRange object. + * + * @return LabelType field in LabelRange object + */ + byte getLabelType(); + + /** + * Returns RangeSize field in LabelRange object. + * + * @return RangeSize field in LabelRange object + */ + int getRangeSize(); + + /** + * Returns LabelBase field in LabelRange object. + * + * @return LabelBase field in LabelRange object + */ + int getLabelBase(); + + /** + * Writes the LabelRange Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing LABEL RANGE object into Channel Buffer. + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build LabelRange object. + */ + interface Builder { + + /** + * Builds LabelRange Object. + * + * @return LabelRange Object + * @throws PcepParseException while building LABEL RANGE object. + */ + PcepLabelRangeObject build() throws PcepParseException; + + /** + * Returns LabelRange object header. + * + * @return LabelRange object header + */ + PcepObjectHeader getLabelRangeObjHeader(); + + /** + * Sets LabelRange object header and returns its builder. + * + * @param obj LabelRange object header + * @return Builder by setting LabelRange object header + */ + Builder setLabelRangeObjHeader(PcepObjectHeader obj); + + /** + * Returns LabelType field in LabelRange object. + * + * @return LabelType field in LabelRange object + */ + byte getLabelType(); + + /** + * Sets LabelType field and returns its builder. + * + * @param labelType LabelType field + * @return Builder by setting LabelType field + */ + Builder setLabelType(byte labelType); + + /** + * Returns RangeSize field in LabelRange object. + * + * @return RangeSize field in LabelRange object + */ + int getRangeSize(); + + /** + * Sets RangeSize field and returns its builder. + * + * @param rangeSize RangeSize field + * @return Builder by setting RangeSize field + */ + Builder setRangeSize(int rangeSize); + + /** + * Returns LabelBase field in LabelRange object. + * + * @return LabelBase field in LabelRange object + */ + int getLabelBase(); + + /** + * Sets LabelBase field and returns its builder. + * + * @param labelBase LabelBase field + * @return Builder by setting LabelBase field + */ + Builder setLabelBase(int labelBase); + + /** + * Sets P flag in TE object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in TE object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRangeResvMsg.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRangeResvMsg.java new file mode 100755 index 00000000..3e2a3a95 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelRangeResvMsg.java @@ -0,0 +1,79 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Label Range Reservation Message. + */ +public interface PcepLabelRangeResvMsg extends PcepObject, PcepMessage { + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns LabelRange field in Label Range Reservation message. + * + * @return LabelRange field + */ + PcepLabelRange getLabelRange(); + + /** + * Sets LabelRange field in Label Range Reservation message with specified value. + * + * @param lR label range object + */ + void setLabelRange(PcepLabelRange lR); + + @Override + void writeTo(ChannelBuffer channelBuffer) throws PcepParseException; + + /** + * Builder interface with get and set functions to build Label Range Reservation message. + */ + interface Builder extends PcepMessage.Builder { + + @Override + PcepLabelRangeResvMsg build(); + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns LabelRange field in Label Range Reservation message. + * + * @return LabelRange object + */ + PcepLabelRange getLabelRange(); + + /** + * Sets LabelRange field and returns its Builder. + * + * @param lR label range object + * @return builder by setting LabelRange field + */ + Builder setLabelRange(PcepLabelRange lR); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelUpdate.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelUpdate.java new file mode 100644 index 00000000..5ef870d4 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelUpdate.java @@ -0,0 +1,108 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepLabelDownload; +import org.onosproject.pcepio.types.PcepLabelMap; + +/*** + * Abstraction to provide PCEP Label Updates. + */ +public interface PcepLabelUpdate { + + /** + * Writes the byte stream of PcepLabelUpdate into channel buffer. + * + * @param bb of type channel buffer + * @throws PcepParseException while writing LABEL UPDATE. + */ + void write(ChannelBuffer bb) throws PcepParseException; + + /** + * Sets the Label Download object. + * + * @param labelDownload PCEP Label Download object + */ + void setLabelDownload(PcepLabelDownload labelDownload); + + /** + * Returns the PcepLabelDownload object. + * + * @return labelDownload PCEP Label Download + */ + PcepLabelDownload getLabelDownload(); + + /** + * Sets the Label map object. + * + * @param labelMap PCEP Label Map object + */ + void setLabelMap(PcepLabelMap labelMap); + + /** + * Returns the PcepLabelMap object. + * + * @return labelMap PCEP Label Map + */ + PcepLabelMap getLabelMap(); + + /** + * Builder interface with get and set functions to build Label Update message. + */ + interface Builder { + + /** + * Builds PcepLableUpdate Object. + * + * @return PcepLableUpdate Object + * @throws PcepParseException while building LABEL-UPDATE. + */ + PcepLabelUpdate build() throws PcepParseException; + + /** + * Sets the Label Download object. + * + * @param labelDownload PCEP Label Download object + * @return Builder by setting labelDownload object + */ + Builder setLabelDownload(PcepLabelDownload labelDownload); + + /** + * Returns the PcepLabelDownload object. + * + * @return labelDownload PCEP Label Download + */ + PcepLabelDownload getLabelDownload(); + + /** + * Sets the Label map object. + * + * @param labelMap PCEP Label Map object + * @return Builder by setting PcepLabelMap object + */ + Builder setLabelMap(PcepLabelMap labelMap); + + /** + * Returns the PcepLabelMap object. + * + * @return labelMap PCEP Label Map + */ + PcepLabelMap getLabelMap(); + } + +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelUpdateMsg.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelUpdateMsg.java new file mode 100755 index 00000000..3740df3b --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLabelUpdateMsg.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Label Update Message. + */ +public interface PcepLabelUpdateMsg extends PcepObject, PcepMessage { + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns list of PcLabelUpdateList. + * + * @return list of PcLabelUpdateList. + */ + LinkedList getPcLabelUpdateList(); + + /** + * Sets list of PcLabelUpdateList. + * + * @param llPcLabelUpdateList list of PcLabelUpdateList + */ + void setPcLabelUpdateList(LinkedList llPcLabelUpdateList); + + @Override + void writeTo(ChannelBuffer channelBuffer) throws PcepParseException; + + /** + * Builder interface with get and set functions to build Label Update message. + */ + interface Builder extends PcepMessage.Builder { + + @Override + PcepLabelUpdateMsg build(); + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns list of PcLabelUpdateList. + * + * @return list of PcLabelUpdateList. + */ + LinkedList getPcLabelUpdateList(); + + /** + * Sets list of PcLabelUpdateList. + * + * @param llPcLabelUpdateList list of PcLabelUpdateList. + * @return Builder by setting list of PcLabelUpdateList. + */ + Builder setPcLabelUpdateList(LinkedList llPcLabelUpdateList); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLspObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLspObject.java new file mode 100755 index 00000000..5d55250a --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLspObject.java @@ -0,0 +1,286 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP LSP Object. + */ +public interface PcepLspObject { + + /** + * Returns PlspId of LSP Object. + * + * @return PlspId of LSP Object + */ + int getPlspId(); + + /** + * Sets PlspId with specified value. + * + * @param value PlspId + */ + void setPlspId(int value); + + /** + * Returns O flag in LSP Object. + * + * @return O flag in LSP Object + */ + byte getOFlag(); + + /** + * Sets O flag with specified value. + * + * @param value O flag + */ + void setOFlag(byte value); + + /** + * Returns A flag in LSP Object. + * + * @return A flag in LSP Object + */ + boolean getAFlag(); + + /** + * Sets A flag with specified value. + * + * @param value A flag + */ + void setAFlag(boolean value); + + /** + * Returns R flag in LSP Object. + * + * @return R flag in LSP Object + */ + boolean getRFlag(); + + /** + * Sets R flag with specified value. + * + * @param value R flag + */ + void setRFlag(boolean value); + + /** + * Returns S flag in LSP Object. + * + * @return S flag in LSP Object + */ + boolean getSFlag(); + + /** + * Sets S flag with specified value. + * + * @param value S flag + */ + void setSFlag(boolean value); + + /** + * Returns D flag in LSP Object. + * + * @return D flag in LSP Object + */ + boolean getDFlag(); + + /** + * Sets D flag with specified value. + * + * @param value D flag + */ + void setDFlag(boolean value); + + /** + * Returns list of Optional Tlvs in LSP Object. + * + * @return list of Optional Tlvs + */ + LinkedList getOptionalTlv(); + + /** + * Sets list of Optional Tlvs in LSP Object. + * + * @param llOptionalTlv list of Optional Tlvs + */ + void setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Writes the LSP Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing LSP object into Channel Buffer. + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build LSP object. + */ + interface Builder { + + /** + * Builds LSP Object. + * + * @return LSP Object + */ + PcepLspObject build(); + + /** + * Returns LSP object header. + * + * @return LSP object header + */ + PcepObjectHeader getLspObjHeader(); + + /** + * Sets LSP object header and returns its builder. + * + * @param obj LSP object header + * @return Builder by setting LSP object header + */ + Builder setLspObjHeader(PcepObjectHeader obj); + + /** + * Returns PlspId of LSP Object. + * + * @return PlspId of LSP Object + */ + int getPlspId(); + + /** + * Sets PlspId with specific value and return its builder. + * + * @param value PlspId + * @return Builder by setting PlspId + */ + Builder setPlspId(int value); + + /** + * Returns O flag in LSP Object. + * + * @return O flag in LSP Object + */ + byte getOFlag(); + + /** + * Sets O flag with specific value and return its builder. + * + * @param value O flag + * @return Builder by setting O flag + */ + Builder setOFlag(byte value); + + /** + * Returns A flag in LSP Object. + * + * @return A flag in LSP Object + */ + boolean getAFlag(); + + /** + * Sets A flag with specific value and return its builder. + * + * @param value A flag + * @return Builder by setting A flag + */ + Builder setAFlag(boolean value); + + /** + * Returns A flag in LSP Object. + * + * @return A flag in LSP Object + */ + boolean getRFlag(); + + /** + * Sets R flag with specific value and return its builder. + * + * @param value r flag + * @return Builder by setting r flag + */ + Builder setRFlag(boolean value); + + /** + * Returns S flag in LSP Object. + * + * @return S flag in LSP Object + */ + boolean getSFlag(); + + /** + * Sets S flag with specific value and return its builder. + * + * @param value s flag + * @return Builder by setting S flag + */ + Builder setSFlag(boolean value); + + /** + * Returns D flag in LSP Object. + * + * @return D flag in LSP Object + */ + boolean getDFlag(); + + /** + * Sets D flag with specific value and return its builder. + * + * @param value D flag + * @return Builder by setting D flag + */ + Builder setDFlag(boolean value); + + /** + * Returns list of Optional Tlvs in LSP Object. + * + * @return list of Optional Tlvs in LSP Object + */ + LinkedList getOptionalTlv(); + + /** + * Sets list of Optional Tlvs and return its builder. + * + * @param llOptionalTlv list of Optional Tlvs + * @return Builder by setting list of Optional Tlvs + */ + Builder setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Sets P flag in LSP object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in LSP object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLspaObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLspaObject.java new file mode 100755 index 00000000..d541e92b --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepLspaObject.java @@ -0,0 +1,286 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP LSPA Object. + */ +public interface PcepLspaObject { + + /** + * Returns L flag in LSPA Object. + * + * @return L flag in LSPA Object + */ + boolean getLFlag(); + + /** + * Sets L flag in LSPA Object. + * + * @param value L flag + */ + void setLFlag(boolean value); + + /** + * Returns Exclude Any field in LSPA Object. + * + * @return Exclude Any field in LSPA Object + */ + int getExcludeAny(); + + /** + * Sets Exclude Any field in LSPA Object. + * + * @param value Exclude Any field + */ + void setExcludeAny(int value); + + /** + * Returns Include Any field in LSPA Object. + * + * @return Include Any field in LSPA Object + */ + int getIncludeAny(); + + /** + * Sets Include Any field in LSPA Object. + * + * @param value Include Any field + */ + void setIncludeAny(int value); + + /** + * Returns Include All field in LSPA Object. + * + * @return Include All field in LSPA Object + */ + int getIncludeAll(); + + /** + * Sets Include All field in LSPA Object. + * + * @param value Include All field + */ + void setIncludeAll(int value); + + /** + * Returns Setup Priority field in LSPA Object. + * + * @return Setup Priority field in LSPA Object + */ + byte getSetupPriority(); + + /** + * Sets Setup Priority field in LSPA Object. + * + * @param value Setup Priority field + */ + void setSetupPriority(byte value); + + /** + * Returns Hold Priority field in LSPA Object. + * + * @return Hold Priority field in LSPA Object + */ + byte getHoldPriority(); + + /** + * Sets Hold Priority field in LSPA Object. + * + * @param value Hold Priority field + */ + void setHoldPriority(byte value); + + /** + * Returns list of Optional Tlvs in LSPA Object. + * + * @return list of Optional Tlvs in LSPA Object + */ + LinkedList getOptionalTlv(); + + /** + * Sets Optional Tlvs in LSPA Object. + * + * @param llOptionalTlv Optional Tlvs in LSPA Object + */ + void setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Writes the LSPA Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing LSPA object into Channel Buffer. + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build bandwidth object. + */ + interface Builder { + + /** + * Builds LSPA Object. + * + * @return LSPA Object + * @throws PcepParseException while building LSPA object. + */ + PcepLspaObject build() throws PcepParseException; + + /** + * Returns LSPA object header. + * + * @return LSPA object header + */ + PcepObjectHeader getLspaObjHeader(); + + /** + * Sets LSPA object header and returns its builder. + * + * @param obj LSPA object header + * @return Builder by setting LSPA object header + */ + Builder setLspaObjHeader(PcepObjectHeader obj); + + /** + * Returns L flag in LSPA Object. + * + * @return L flag in LSPA Object + */ + boolean getLFlag(); + + /** + * Sets L flag in LSPA Object and return its builder. + * + * @param value L flag in LSPA Object + * @return Builder by setting L flag + */ + Builder setLFlag(boolean value); + + /** + * Returns Exclude Any field in LSPA Object. + * + * @return Exclude Any field in LSPA Object + */ + int getExcludeAny(); + + /** + * Sets Exclude Any field in LSPA Object and return its builder. + * + * @param value Exclude Any field in LSPA Object + * @return Builder by setting Exclude Any field + */ + Builder setExcludeAny(int value); + + /** + * Returns Include Any field in LSPA Object. + * + * @return Include Any field in LSPA Object + */ + int getIncludeAny(); + + /** + * Sets Include Any field in LSPA Object and return its builder. + * + * @param value Include Any field in LSPA Object + * @return Builder by setting Include Any field + */ + Builder setIncludeAny(int value); + + /** + * Returns Include All field in LSPA Object. + * + * @return Include All field in LSPA Object + */ + int getIncludeAll(); + + /** + * Sets Include All field in LSPA Object and return its builder. + * + * @param value Include All field in LSPA Object + * @return Builder by setting Include All field + */ + Builder setIncludeAll(int value); + + /** + * Returns Setup Priority field in LSPA Object. + * + * @return Setup Priority field in LSPA Object + */ + byte getSetupPriority(); + + /** + * Sets Setup Priority field in LSPA Object and return its builder. + * + * @param value Setup Priority field in LSPA Object + * @return Builder by setting Setup Priority field + */ + Builder setSetupPriority(byte value); + + /** + * Returns Hold Priority field in LSPA Object. + * + * @return Hold Priority field in LSPA Object + */ + byte getHoldPriority(); + + /** + * Sets Hold Priority field in LSPA Object and return its builder. + * + * @param value Hold Priority field in LSPA Object + * @return Builder by setting Hold Priority field + */ + Builder setHoldPriority(byte value); + + /** + * Returns list of Optional Tlvs in LSPA Object. + * + * @return list of Optional Tlvs in LSPA Object + */ + LinkedList getOptionalTlv(); + + /** + * Sets list of Optional Tlvs in LSPA Object. + * + * @param llOptionalTlv list of Optional Tlvs + * @return builder by setting list of Optional Tlvs + */ + Builder setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Sets P flag in LSPA object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in LSPA object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessage.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessage.java new file mode 100755 index 00000000..7de07169 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessage.java @@ -0,0 +1,67 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Messages. + */ +public interface PcepMessage extends PcepObject { + + @Override + PcepVersion getVersion(); + + /** + * Returns Type of PCEP Message. + * + * @return Type of PCEP Message + */ + PcepType getType(); + + @Override + void writeTo(ChannelBuffer channelBuffer) throws PcepParseException; + + /** + * Builder interface with get and set functions to build PCEP Message. + */ + interface Builder { + + /** + * Builds PCEP Message. + * + * @return PCEP Message + * @throws PcepParseException when build fails to create PCEP message + */ + PcepMessage build() throws PcepParseException; + + /** + * Returns Version of PCEP Message. + * + * @return Version of PCEP Message + */ + PcepVersion getVersion(); + + /** + * Returns Type of PCEP Message. + * + * @return Type of PCEP Message + */ + PcepType getType(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessageReader.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessageReader.java new file mode 100755 index 00000000..591a033d --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessageReader.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Message Reader. + */ +public interface PcepMessageReader { + + /** + * Reads the Objects in the PCEP Message and Returns PCEP Message. + * + * @param bb Channel Buffer + * @return PCEP Message + * @throws PcepParseException while parsing PCEP message. + * @throws PcepParseException when received message is empty + */ + T readFrom(ChannelBuffer bb) throws PcepParseException; +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessageWriter.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessageWriter.java new file mode 100755 index 00000000..e7477b51 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMessageWriter.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Message Writer. + */ +public interface PcepMessageWriter { + + /** + * Writes the Objects of the PCEP Message into Channel Buffer. + * + * @param bb Channel Buffer + * @param message PCEP Message + * @throws PcepParseException while writing PCEP message. + */ + void write(ChannelBuffer bb, T message) throws PcepParseException; +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMetricObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMetricObject.java new file mode 100755 index 00000000..380fb42e --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMetricObject.java @@ -0,0 +1,225 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; + +/** + * Abstraction of an entity providing PCEP Metric Object. + */ +public interface PcepMetricObject { + + /** + * Returns Metric value in Metric Object. + * + * @return Metric value + */ + int getMetricVal(); + + /** + * Sets Metric value in Metric Object with specified value. + * + * @param value Metric value + */ + void setMetricVal(int value); + + /** + * Returns Y flag in Metric Object. + * + * @return Y flag in Metric Object + */ + byte getYFlag(); + + /** + * Sets Y flag in Metric Object with specified value. + * + * @param value Y flag + */ + void setYFlag(byte value); + + /** + * Returns C flag in Metric Object. + * + * @return C flag in Metric Object + */ + boolean getCFlag(); + + /** + * Sets C flag in Metric Object with specified value. + * + * @param value C flag + */ + void setCFlag(boolean value); + + /** + * Returns B flag in Metric Object. + * + * @return B flag in Metric Object + */ + boolean getBFlag(); + + /** + * Sets B flag in Metric Object with specified value. + * + * @param value B flag + */ + void setBFlag(boolean value); + + /** + * Returns BType field in Metric Object. + * + * @return BType field in Metric Object + */ + byte getBType(); + + /** + * Sets BType field in Metric Object with specified value. + * + * @param value BType field + */ + void setBType(byte value); + + /** + * Writes the Metric Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing METRIC object into Channel Buffer. + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build Metric object. + */ + interface Builder { + + /** + * Builds Metric Object. + * + * @return Metric Object + * @throws PcepParseException when mandatory object is not set + */ + PcepMetricObject build() throws PcepParseException; + + /** + * Returns Metric object header. + * + * @return Metric object header + */ + PcepObjectHeader getMetricObjHeader(); + + /** + * Sets Metric object header and returns its builder. + * + * @param obj Metric object header + * @return Builder by setting Metric object header + */ + Builder setMetricObjHeader(PcepObjectHeader obj); + + /** + * Returns Metric value in Metric Object. + * + * @return Metric value + */ + int getMetricVal(); + + /** + * Sets Metric Value in Metric Object and returns its builder. + * + * @param value Metric Value + * @return Builder by setting Metric Value + */ + Builder setMetricVal(int value); + + /** + * Returns Flags in Metric Object. + * + * @return Flags in Metric Object + */ + byte getYFlag(); + + /** + * Sets Flags in Metric Object and returns its builder. + * + * @param value Flags + * @return Builder by setting Flags + */ + Builder setYFlag(byte value); + + /** + * Returns C flag in Metric Object. + * + * @return C flag in Metric Object + */ + boolean getCFlag(); + + /** + * Sets C flag in Metric Object and returns its builder. + * + * @param value C flag + * @return Builder by setting C flag + */ + Builder setCFlag(boolean value); + + /** + * Returns B flag in Metric Object. + * + * @return B flag in Metric Object + */ + boolean getBFlag(); + + /** + * Sets B flag in Metric Object and returns its builder. + * + * @param value B flag + * @return Builder by setting B flag + */ + Builder setBFlag(boolean value); + + /** + * Returns BType field in Metric Object. + * + * @return BType field in Metric Object + */ + byte getBType(); + + /** + * Sets B Type field in Metric Object and returns its builder. + * + * @param value B Type field + * @return Builder by setting B Type field + */ + Builder setBType(byte value); + + /** + * Sets P flag in Metric object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in Metric object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMsgPath.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMsgPath.java new file mode 100644 index 00000000..4b1d50a5 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepMsgPath.java @@ -0,0 +1,117 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity Provides PCEP Message PAth for update message. + * Reference :PCE extensions for stateful draft-ietf-pce-stateful-pce-10. + */ +public interface PcepMsgPath { + + /** + * Returns object of PcepEroObject. + * + * @return eroObject + */ + PcepEroObject getEroObject(); + + /** + * Returns object of PcepAttribute. + * + * @return pcepAttribute + */ + PcepAttribute getPcepAttribute(); + + /** + * Sets PcepEroObject. + * + * @param eroObject PCEP ERO Object. + */ + void setEroObject(PcepEroObject eroObject); + + /** + * Sets PcepAttribute. + * + * @param pcepAttribute PCEP-Attribute. + */ + void setPcepAttribute(PcepAttribute pcepAttribute); + + /** + * reads ERO object and attribute list. + * + * @param bb of type channel buffer + * @return PcepMsgPath + * @throws PcepParseException while parsing Message Path from Channel Buffer. + */ + PcepMsgPath read(ChannelBuffer bb) throws PcepParseException; + + /** + * writes ERO object and attribute list to channel. + * + * @param bb of type channel buffer + * @return object length index + * @throws PcepParseException while writing Message Path into Channel Buffer. + */ + + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build PcepMsgPath. + */ + interface Builder { + + /** + * Builds PcepMsgPath. + * + * @return PcepMsgPath + * @throws PcepParseException when mandatory object is not set + */ + PcepMsgPath build() throws PcepParseException; + + /** + * Returns object of PcepEroObject. + * + * @return PcepEroObject + */ + PcepEroObject getEroObject(); + + /** + * Returns object of PcepAttribute. + * + * @return pcepAttribute + */ + PcepAttribute getPcepAttribute(); + + /** + * Sets PcepEroObject. + * + * @param eroObject PcepEroObject + * @return Builder by setting ERO object. + */ + Builder setEroObject(PcepEroObject eroObject); + + /** + * Sets PcepAttribute. + * + * @param pcepAttribute PCEP-Attribute + * @return Builder by setting PCEP-Attribute. + */ + Builder setPcepAttribute(PcepAttribute pcepAttribute); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepNai.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepNai.java new file mode 100755 index 00000000..6be8c65a --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepNai.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; + +/** + * Abstraction of an entity provides NAI information in SR ERO Object. + */ +public interface PcepNai { + + /** + * To get the ST type of the NAI information. + * + * @return type of ST info + */ + byte getType(); + + /** + * To write the object information to channelBuffer. + * + * @param cb of type channel buffer + * @return length of written bytes. + */ + int write(ChannelBuffer cb); +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepObject.java new file mode 100755 index 00000000..26dad566 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepObject.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +/** + * Abstraction of an entity providing PCEP Object. + */ +public interface PcepObject extends Writeable { + + /** + * Returns Version of PCEP Object. + * + * @return Version of PCEP Object + */ + PcepVersion getVersion(); +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepOpenMsg.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepOpenMsg.java new file mode 100644 index 00000000..904156f0 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepOpenMsg.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Open Message. + */ +public interface PcepOpenMsg extends PcepObject, PcepMessage { + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Sets OpenObject in Open Message with Specified Obj. + * + * @param obj OpenObject + */ + void setPcepOpenObject(PcepOpenObject obj); + + /** + * Returns OpenObject in Open Message. + * + * @return OpenObject in Open Message + */ + PcepOpenObject getPcepOpenObject(); + + @Override + void writeTo(ChannelBuffer channelBuffer) throws PcepParseException; + + /** + * Builder interface with get and set functions to build Open message. + */ + interface Builder extends PcepMessage.Builder { + + @Override + PcepOpenMsg build() throws PcepParseException; + + /** + * Sets Open Object in Open Message and return its builder. + * + * @param obj Open Object + * @return builder by setting Open Object + */ + Builder setPcepOpenObj(PcepOpenObject obj); + + /** + * Returns OpenObject in Open Message. + * + * @return OpenObject in Open Message + */ + PcepOpenObject getPcepOpenObj(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepOpenObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepOpenObject.java new file mode 100755 index 00000000..13dd2fa8 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepOpenObject.java @@ -0,0 +1,221 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP Open Object. + */ +public interface PcepOpenObject { + + /** + * Returns Open object header. + * + * @return Open object header + */ + PcepObjectHeader getOpenObjHeader(); + + /** + * Sets Open object header in Open Object. + * + * @param obj Open object header + */ + void setOpenObjHeader(PcepObjectHeader obj); + + /** + * Returns version of Open Object. + * + * @return Version of Open Object + */ + PcepVersion getVersion(); + + /** + * Returns KeepAlive Time in Open Object. + * + * @return KeepAlive Time in Open Object + */ + byte getKeepAliveTime(); + + /** + * Sets KeepAlive Time in Open Object with specified value. + * + * @param value KeepAlive Time + */ + void setKeepAliveTime(byte value); + + /** + * Returns Dead Time in Open Object. + * + * @return Dead Time in Open Object + */ + byte getDeadTime(); + + /** + * Sets Dead Time in Open Object with specified value. + * + * @param value Dead Time + */ + void setDeadTime(byte value); + + /** + * Returns SessionId in Open Object. + * + * @return SessionId in Open Object + */ + byte getSessionId(); + + /** + * Sets SessionId in Open Object with specified value. + * + * @param value SessionId + */ + void setSessionId(byte value); + + /** + * Returns list of Optional Tlvs in Open Object. + * + * @return list of Optional Tlvs + */ + LinkedList getOptionalTlv(); + + /** + * Sets list of Optional Tlvs in Open Object. + * + * @param llOptionalTlv list of Optional Tlvs + */ + void setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Writes the Open into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing Open Object into Channel Buffer. + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build Open object. + */ + interface Builder { + + /** + * Builds Open Object. + * + * @return Open Object + * @throws PcepParseException while building PCEP-Open object + */ + PcepOpenObject build() throws PcepParseException; + + /** + * Returns Open object header. + * + * @return Open object header + */ + PcepObjectHeader getOpenObjHeader(); + + /** + * Sets Open object header and returns its builder. + * + * @param obj Open object header + * @return Builder by setting Open object header + */ + Builder setOpenObjHeader(PcepObjectHeader obj); + + /** + * Returns KeepAlive Time in Open Object. + * + * @return KeepAlive Time in Open Object + */ + byte getKeepAliveTime(); + + /** + * Sets KeepAlive Time and returns its builder. + * + * @param value KeepAlive Time + * @return Builder by setting KeepAlive Time + */ + Builder setKeepAliveTime(byte value); + + /** + * Returns Dead Time in Open Object. + * + * @return Dead Time in Open Object + */ + byte getDeadTime(); + + /** + * Sets Dead Time and returns its builder. + * + * @param value Dead Time + * @return Builder by setting Dead Time + */ + Builder setDeadTime(byte value); + + /** + * Returns SessionId in Open Object. + * + * @return SessionId in Open Object + */ + byte getSessionId(); + + /** + * Sets SessionId and returns its builder. + * + * @param value SessionId + * @return Builder by setting SessionId + */ + Builder setSessionId(byte value); + + /** + * Returns list of Optional Tlvs in Open Object. + * + * @return list of Optional Tlvs in Open Object + */ + LinkedList getOptionalTlv(); + + /** + * Sets list of Optional Tlvs and return its Builder. + * + * @param llOptionalTlv list of Optional Tlvs + * @return builder by setting list of Optional Tlvs + */ + Builder setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Sets P flag in Open object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in Open object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepRPObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepRPObject.java new file mode 100755 index 00000000..c6993c3a --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepRPObject.java @@ -0,0 +1,256 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP RP Object. + */ +public interface PcepRPObject { + + /** + * Returns RequestId Number in RP Object. + * + * @return RequestId Number in RP Object + */ + int getRequestIdNum(); + + /** + * Sets RequestId Number with specified value. + * + * @param value RequestId Number + */ + void setRequestIdNum(int value); + + /** + * Returns O flag in RP Object. + * + * @return O flag in RP Object + */ + boolean getOFlag(); + + /** + * Sets O flag with specified value. + * + * @param value O flag + */ + void setOFlag(boolean value); + + /** + * Returns B flag in RP Object. + * + * @return B flag in RP Object + */ + boolean getBFlag(); + + /** + * Sets B flag with specified value. + * + * @param value B flag + */ + void setBFlag(boolean value); + + /** + * Returns R flag in RP Object. + * + * @return R flag in RP Object + */ + boolean getRFlag(); + + /** + * Sets R flag with specified value. + * + * @param value R flag + */ + void setRFlag(boolean value); + + /** + * Returns Priority Flag in RP Object. + * + * @return Priority Flag in RP Object + */ + byte getPriFlag(); + + /** + * Sets Priority Flag with specified value. + * + * @param value Priority Flag + */ + void setPriFlag(byte value); + + /** + * Returns list of Optional Tlvs in RP Object. + * + * @return list of Optional Tlvs in RP Object + */ + LinkedList getOptionalTlv(); + + /** + * Sets list of Optional Tlvs in RP Object and returns its builder. + * + * @param llOptionalTlv list of Optional Tlvs + */ + void setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Writes the RP Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException while writing RP object into Channel Buffer. + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build bandwidth object. + */ + interface Builder { + + /** + * Builds RP Object. + * + * @return RP Object + */ + PcepRPObject build(); + + /** + * Returns RP object header. + * + * @return RP object header + */ + PcepObjectHeader getRPObjHeader(); + + /** + * Sets RP object header and returns its builder. + * + * @param obj RP object header + * @return Builder by setting RP object header + */ + Builder setRPObjHeader(PcepObjectHeader obj); + + /** + * Returns Request Id Number in RP Object. + * + * @return Request Id Number in RP Object + */ + int getRequestIdNum(); + + /** + * Sets Request Id Number and returns its builder. + * + * @param value Request Id Number + * @return Builder by setting Request Id Number + */ + Builder setRequestIdNum(int value); + + /** + * Returns O flag in RP Object. + * + * @return O flag in RP Object + */ + boolean getOFlag(); + + /** + * Sets O flag and returns its builder. + * + * @param value O flag + * @return Builder by setting O flag + */ + Builder setOFlag(boolean value); + + /** + * Returns B flag in RP Object. + * + * @return B flag in RP Object + */ + boolean getBFlag(); + + /** + * Sets B flag and returns its builder. + * + * @param value B flag + * @return Builder by setting B flag + */ + Builder setBFlag(boolean value); + + /** + * Returns R flag in RP Object. + * + * @return R flag in RP Object + */ + boolean getRFlag(); + + /** + * Sets R flag and returns its builder. + * + * @param value R flag + * @return Builder by setting R flag + */ + Builder setRFlag(boolean value); + + /** + * Returns Priority Flag in RP Object. + * + * @return Priority Flag in RP Object + */ + byte getPriFlag(); + + /** + * Sets Priority Flag and returns its builder. + * + * @param value Priority Flag + * @return Builder by setting Priority Flag + */ + Builder setPriFlag(byte value); + + /** + * Returns list of Optional Tlvs in RP Object. + * + * @return list of Optional Tlvs + */ + LinkedList getOptionalTlv(); + + /** + * Sets list of Optional Tlvs and returns its builder. + * + * @param llOptionalTlv list of Optional Tlvs + * @return Builder by setting list of Optional Tlvs + */ + Builder setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Sets P flag in RP object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in RP object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepReportMsg.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepReportMsg.java new file mode 100755 index 00000000..f4355206 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepReportMsg.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Report Message. + */ +public interface PcepReportMsg extends PcepObject, PcepMessage { + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns PcepStateReport list. + * + * @return list of PcepStateReport + */ + LinkedList getStateReportList(); + + /** + * Sets StateReportList. + * + * @param llStateReportList list of PcepStateReport. + */ + void setStateReportList(LinkedList llStateReportList); + + @Override + void writeTo(ChannelBuffer channelBuffer) throws PcepParseException; + + /** + * Builder interface with get and set functions to build Report message. + */ + interface Builder extends PcepMessage.Builder { + + @Override + PcepReportMsg build(); + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns StateReportList. + * + * @return StateReportList. + */ + LinkedList getStateReportList(); + + /** + * Sets list of PcepStateReport and returns builder. + * + * @param llStateReportList list of PcepStateReport. + * @return Builder by setting list of PcepStateReport. + */ + Builder setStateReportList(LinkedList llStateReportList); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepRroObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepRroObject.java new file mode 100755 index 00000000..928ce1a6 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepRroObject.java @@ -0,0 +1,111 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP RRO Object. + */ +public interface PcepRroObject { + + /** + * Returns list of SubObjects. + * + * @return list of SubObjects + */ + LinkedList getSubObjects(); + + /** + * Sets list of SubObjects and return its builder. + * + * @param llSubObjects list of SubObjects + */ + void setSubObjects(LinkedList llSubObjects); + + /** + * Writes the RRO Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException when object header failed to write in channel buffer + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build RRO object. + */ + interface Builder { + + /** + * Builds RRO Object. + * + * @return RRO Object + */ + PcepRroObject build(); + + /** + * Returns RRO object header. + * + * @return RRO object header + */ + PcepObjectHeader getRroObjHeader(); + + /** + * Sets RRO object header and returns its builder. + * + * @param obj RRO object header + * @return Builder by setting RRO object header + */ + Builder setRroObjHeader(PcepObjectHeader obj); + + /** + * Returns list of SubObjects. + * + * @return list of SubObjects + */ + LinkedList getSubObjects(); + + /** + * Sets list of SubObjects in RRO Object and returns its builder. + * + * @param llSubObjects list of SubObjects + * @return Builder by setting list of SubObjects + */ + Builder setSubObjects(LinkedList llSubObjects); + + /** + * Sets P flag in RRO object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in RRO object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepSrpObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepSrpObject.java new file mode 100755 index 00000000..e4816efd --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepSrpObject.java @@ -0,0 +1,171 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP SRP Object. + */ +public interface PcepSrpObject { + + /** + * Returns SRP ID of SRP Object. + * + * @return SRP ID of SRP Object + */ + int getSrpID(); + + /** + * Sets SRP ID with specified value. + * + * @param srpID SRP ID of SRP Object + */ + void setSrpID(int srpID); + + /** + * Returns R flag of SRP Object. + * + * @return R flag of SRP Object + */ + boolean getRFlag(); + + /** + * Sets R flag with specified value. + * + * @param bRFlag R Flag of SRP Object + */ + void setRFlag(boolean bRFlag); + + /** + * sets the optional TLvs. + * + * @param llOptionalTlv list of optional tlvs + */ + void setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Returns list of optional tlvs. + * + * @return llOptionalTlv list of optional tlvs + */ + LinkedList getOptionalTlv(); + + /** + * Writes the SRP Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException when tlv is null + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build SRP object. + */ + interface Builder { + + /** + * Builds SRP Object. + * + * @return SRP Object + * @throws PcepParseException when mandatory object is not set + */ + PcepSrpObject build() throws PcepParseException; + + /** + * Returns SRP object header. + * + * @return SRP object header + */ + PcepObjectHeader getSrpObjHeader(); + + /** + * Sets SRP object header and returns its builder. + * + * @param obj SRP object header + * @return Builder by setting SRP object header + */ + Builder setSrpObjHeader(PcepObjectHeader obj); + + /** + * Returns SRP ID of SRP Object. + * + * @return SRP ID of SRP Object + */ + int getSrpID(); + + /** + * Sets SRP ID and returns its builder. + * + * @param srpID SRP ID + * @return Builder by setting SRP ID + */ + Builder setSrpID(int srpID); + + /** + * Returns R flag of SRP Object. + * + * @return R flag of SRP Object + */ + boolean getRFlag(); + + /** + * Sets R flag and returns its builder. + * + * @param bRFlag R flag + * @return Builder by setting R flag + */ + Builder setRFlag(boolean bRFlag); + + /** + * Returns list of optional tlvs. + * + * @return llOptionalTlv list of optional tlvs + */ + LinkedList getOptionalTlv(); + + /** + * sets the optional TLvs. + * + * @param llOptionalTlv List of optional tlv + * @return builder by setting list of optional tlv. + */ + Builder setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Sets P flag in SRP object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in SRP object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepStateReport.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepStateReport.java new file mode 100755 index 00000000..b8ab9ec8 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepStateReport.java @@ -0,0 +1,207 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity provides State Report for PCEP Report Message. + */ +public interface PcepStateReport { + + /** + * Provides PCEP Message path for report message. + */ + interface PcepMsgPath { + + /** + * Returns PcepEroObject. + * + * @return eroObj + */ + PcepEroObject getEroObject(); + + /** + * Sets PcepEroObject. + * + * @param eroObject Ero Object + */ + void setEroObject(PcepEroObject eroObject); + + /** + * Returns PcepAttribute. + * + * @return attrList + */ + PcepAttribute getPcepAttribute(); + + /** + * Sets PcepAttribute. + * + * @param pcepAttribute Pcep Attribute object + */ + void setPcepAttribute(PcepAttribute pcepAttribute); + + /** + * Returns PcepRroObject. + * + * @return rroObj + */ + PcepRroObject getRroObject(); + + /** + * Sets PcepRroObject. + * + * @param rroObject Rro object + */ + void setRroObject(PcepRroObject rroObject); + + /** + * Returns PcepBandwidthObject. + * + * @return bandwidth object + */ + PcepBandwidthObject getBandwidthObject(); + + /** + * Sets PcepBandwidthObject. + * + * @param bandwidth bandwidth object + */ + void setBandwidthObject(PcepBandwidthObject bandwidth); + + /** + * Reads all the Objects for PCEP Message Path. + * + * @param bb of type channel buffer + * @return PCEP Message path + * @throws PcepParseException when invalid buffer received + */ + PcepMsgPath read(ChannelBuffer bb) throws PcepParseException; + + /** + * Writes all the objects for pcep message path. + * + * @param bb of type channel buffer. + * @return object length index + * @throws PcepParseException when mandatory object is not set + */ + int write(ChannelBuffer bb) throws PcepParseException; + } + + /** + * Returns PcepSrpObject. + * + * @return srpObject + */ + PcepSrpObject getSrpObject(); + + /** + * Returns PcepLspObject. + * + * @return lspObject + */ + PcepLspObject getLspObject(); + + /** + * Returns PcepMsgPath. + * + * @return msgPath + */ + PcepMsgPath getMsgPath(); + + /** + * Sets the SRP Object. + * + * @param srpObj Pcep Srp Object + */ + void setSrpObject(PcepSrpObject srpObj); + + /** + * Sets the LSP Object. + * + * @param lspObject Pcep Lsp Object + */ + void setLspObject(PcepLspObject lspObject); + + /** + * Sets the Path Object. + * + * @param msgPath Pcep MsgPath object + */ + void setMsgPath(PcepMsgPath msgPath); + + /** + * Builder interface with get and set functions to build PcepStateReport. + */ + interface Builder { + + /** + * Builds PcepStateReport. + * + * @return PcepStateReport + * @throws PcepParseException when mandatory object is not set + */ + PcepStateReport build() throws PcepParseException; + + /** + * Returns PcepSrpObject. + * + * @return srpObject + */ + PcepSrpObject getSrpObject(); + + /** + * Returns PcepLspObject. + * + * @return lspObject + */ + PcepLspObject getLspObject(); + + /** + * Returns PcepMsgPath. + * + * @return msgPath + */ + PcepMsgPath getMsgPath(); + + /** + * Sets the SRP Object. + * + * @param srpObj Pcep Srp Object + * @return builder by setting PcepSrpObject + */ + Builder setSrpObject(PcepSrpObject srpObj); + + /** + * Sets the LSP Object. + * + * @param lspObject Pcep Lsp Object + * @return builder by setting PcepLspObject + */ + Builder setLspObject(PcepLspObject lspObject); + + /** + * Sets the Path Object. + * + * @param msgPath Pcep MsgPath object + * @return builder by setting PcepMsgPath + */ + Builder setMsgPath(PcepMsgPath msgPath); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepTEObject.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepTEObject.java new file mode 100755 index 00000000..21f6c71c --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepTEObject.java @@ -0,0 +1,241 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; + +/** + * Abstraction of an entity providing PCEP TE Object. + */ +public interface PcepTEObject { + + /** + * Returns TE object header. + * + * @return TE object header + */ + PcepObjectHeader getTEObjHeader(); + + /** + * Sets TE Object header. + * + * @param obj TE Object header + */ + void setTEObjHeader(PcepObjectHeader obj); + + /** + * Returns ProtocolId in TE Object. + * + * @return ProtocolId in TE Object + */ + byte getProtocolId(); + + /** + * Sets ProtocolId in TE Object. + * + * @param yProtId ProtocolId in TE Object + */ + void setProtocolId(byte yProtId); + + /** + * Returns R flag in TE Object. + * + * @return R flag in TE Object + */ + boolean getRFlag(); + + /** + * Sets R flag in TE Object. + * + * @param bRFlag R flag in TE Object + */ + void setRFlag(boolean bRFlag); + + /** + * Returns S flag in TE Object. + * + * @return S flag in TE Object + */ + boolean getSFlag(); + + /** + * Sets S flag in TE Object. + * + * @param bSFlag S flag in TE Object + */ + void setSFlag(boolean bSFlag); + + /** + * Returns TE ID in TE Object. + * + * @return TE ID in TE Object + */ + int getTEId(); + + /** + * Sets TE ID in TE Object. + * + * @param iTEId TE ID in TE Object + */ + void setTEId(int iTEId); + + /** + * Returns list of Optional Tlvs in TE Object. + * + * @return list of Optional Tlvs + */ + LinkedList getOptionalTlv(); + + /** + * Sets list of Optional Tlvs in TE Object. + * + * @param llOptionalTlv list of Optional Tlvs + */ + void setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Writes the TE Object into channel buffer. + * + * @param bb channel buffer + * @return Returns the writerIndex of this buffer + * @throws PcepParseException when obj header is not written to channel buffer + */ + int write(ChannelBuffer bb) throws PcepParseException; + + /** + * Builder interface with get and set functions to build TE object. + */ + interface Builder { + + /** + * Builds TE Object. + * + * @return TE Object + */ + PcepTEObject build(); + + /** + * Returns TE object header. + * + * @return TE object header + */ + PcepObjectHeader getTEObjHeader(); + + /** + * Sets TE object header and returns its builder. + * + * @param obj TE object header + * @return Builder by setting TE object header + */ + Builder setTEObjHeader(PcepObjectHeader obj); + + /** + * Returns ProtocolId in TE Object. + * + * @return ProtocolId in TE Object + */ + byte getProtocolId(); + + /** + * Sets ProtocolId in TE Object and returns its builder. + * + * @param yProtId ProtocolId in TE Object + * @return Builder by setting ProtocolId + */ + Builder setProtocolId(byte yProtId); + + /** + * Returns R flag in TE Object. + * + * @return R flag in TE Object + */ + boolean getRFlag(); + + /** + * Sets R flag in TE Object and returns its builder. + * + * @param bRFlag R flag in TE Object + * @return Builder by setting R flag + */ + Builder setRFlag(boolean bRFlag); + + /** + * Returns S flag in TE Object. + * + * @return S flag in TE Object + */ + boolean getSFlag(); + + /** + * Sets S flag in TE Object and returns its builder. + * + * @param bSFlag S flag in TE Object + * @return Builder by setting S flag + */ + Builder setSFlag(boolean bSFlag); + + /** + * Returns TE ID in TE Object. + * + * @return TE ID in TE Object + */ + int getTEId(); + + /** + * Sets TE ID in TE Object and returns its builder. + * + * @param iTEId TE ID in TE Object + * @return Builder by setting TE ID + */ + Builder setTEId(int iTEId); + + /** + * Returns list of Optional Tlvs in TE Object. + * + * @return list of Optional Tlvs + */ + LinkedList getOptionalTlv(); + + /** + * Sets list of Optional Tlvs in TE Object and returns its builder. + * + * @param llOptionalTlv list of Optional Tlvs + * @return Builder by setting list of Optional Tlvs + */ + Builder setOptionalTlv(LinkedList llOptionalTlv); + + /** + * Sets P flag in TE object header and returns its builder. + * + * @param value boolean value to set P flag + * @return Builder by setting P flag + */ + Builder setPFlag(boolean value); + + /** + * Sets I flag in TE object header and returns its builder. + * + * @param value boolean value to set I flag + * @return Builder by setting I flag + */ + Builder setIFlag(boolean value); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepTEReportMsg.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepTEReportMsg.java new file mode 100755 index 00000000..3bc5034e --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepTEReportMsg.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP TE Report Message. + */ +public interface PcepTEReportMsg extends PcepObject, PcepMessage { + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns list of PCEP TE Objects. + * + * @return list of PCEP TE Objects + */ + LinkedList getTEReportList(); + + /** + * Sets list of Optional Tlvs in TE Report Message. + * + * @param llTEReportList list of optional Tlvs + */ + void setTEReportList(LinkedList llTEReportList); + + @Override + void writeTo(ChannelBuffer channelBuffer) throws PcepParseException; + + /** + * Builder interface with get and set functions to build TE Report message. + */ + interface Builder extends PcepMessage.Builder { + + @Override + PcepTEReportMsg build(); + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns list of Optional Tlv in TE Report Message. + * + * @return list of Optional Tlv + */ + LinkedList getTEReportList(); + + /** + * Sets list of Optional Tlvs and returns its builder. + * + * @param llTEReportList list of Optional Tlvs + * @return Builder object for TE report message + */ + Builder setTEReportList(LinkedList llTEReportList); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepType.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepType.java new file mode 100755 index 00000000..450fdfac --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepType.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +/** + * Enum to Provide the Different types of PCEP messages. + */ +public enum PcepType { + + NONE(0), OPEN(1), KEEP_ALIVE(2), PATH_COMPUTATION_REQUEST(3), PATH_COMPUTATION_REPLY(4), + NOTIFICATION(5), ERROR(6), CLOSE(7), REPORT(10), UPDATE(11), INITIATE(12), LABEL_UPDATE(13), + TE_REPORT(14), LABEL_RANGE_RESERV(15), MAX(16), END(17); + + int iValue; + + /** + * Assign iValue with the value iVal as the types of PCEP message. + * + * @param iVal type of pcep message + */ + PcepType(int iVal) { + + iValue = iVal; + } + + /** + * Returns iValue as type of PCEP message. + * + * @return iValue type of pcep message + */ + public byte getType() { + + return (byte) iValue; + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepUpdateMsg.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepUpdateMsg.java new file mode 100755 index 00000000..dc2ac3a8 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepUpdateMsg.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Update Message. + */ +public interface PcepUpdateMsg extends PcepObject, PcepMessage { + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns the update request list for PCEP Update Message. + * + * @return list of Update Requests + */ + LinkedList getUpdateRequestList(); + + /** + * Sets the update request list for PCEP update message. + * + * @param llUpdateRequestList is a list of PCEP Update Requests + */ + void setUpdateRequestList(LinkedList llUpdateRequestList); + + @Override + void writeTo(ChannelBuffer channelBuffer) throws PcepParseException; + + /** + * Builder interface with Get and Set Functions to build the PCEP update Message. + */ + interface Builder extends PcepMessage.Builder { + + @Override + PcepUpdateMsg build(); + + @Override + PcepVersion getVersion(); + + @Override + PcepType getType(); + + /** + * Returns the update request list for the PCEP update message. + * + * @return list of Update Requests + */ + LinkedList getUpdateRequestList(); + + /** + * Sets the update request list for the PCEP update message. + * + * @param llUpdateRequestList list of Update requests + * @return builder by setting list llUpdateRequestList of PcepUpdateRequest. + */ + Builder setUpdateRequestList(LinkedList llUpdateRequestList); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepUpdateRequest.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepUpdateRequest.java new file mode 100755 index 00000000..8d1c89e2 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepUpdateRequest.java @@ -0,0 +1,126 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing PCEP Update Request List. + */ +public interface PcepUpdateRequest { + + /** + * Returns object of PCEP SRP Object. + * + * @return srpObject of type PCEP SRP Object + */ + PcepSrpObject getSrpObject(); + + /** + * Returns object of PCEP LSP Object. + * + * @return lspObject of type PCEP LSP Object + */ + PcepLspObject getLspObject(); + + /** + * Returns object of PCEP MSG PATH. + * + * @return msgPath of type PCEP MSG PATH + */ + PcepMsgPath getMsgPath(); + + /** + * Sets the PCEP SRP Object. + * + * @param srpObject object of type PCEP SRP Object + */ + void setSrpObject(PcepSrpObject srpObject); + + /** + * Sets the PCEP LSP Object. + * + * @param lspObject object of type PCEP LSP Object + */ + void setLspObject(PcepLspObject lspObject); + + /** + * sets the PCEP MSG PATH. + * + * @param msgPath object of type PCEP MSG PATH + */ + void setMsgPath(PcepMsgPath msgPath); + + /** + * Builder interface with get and set functions to build PcepUpdateRequest. + */ + interface Builder { + + /** + * Builds PcepUpdateRequest. + * + * @return PcepUpdateRequest + * @throws PcepParseException if mandatory object is not set + */ + PcepUpdateRequest build() throws PcepParseException; + + /** + * Returns PcepSrpObject. + * + * @return srpObject + */ + PcepSrpObject getSrpObject(); + + /** + * Returns PcepLspObject. + * + * @return lspObject + */ + PcepLspObject getLspObject(); + + /** + * Returns PcepMsgPath. + * + * @return msgPath + */ + PcepMsgPath getMsgPath(); + + /** + * Sets the SRP Object. + * + * @param srpObj of type PcepSrpObject + * @return builder by setting PcepSrpObject + */ + Builder setSrpObject(PcepSrpObject srpObj); + + /** + * Sets the LSP Object. + * + * @param lspObject of type PcepLspObject + * @return builder by setting PcepLspObject + */ + Builder setLspObject(PcepLspObject lspObject); + + /** + * Sets the Path Object. + * + * @param msgPath of type PcepMsgPath + * @return builder by setting PcepMsgPath + */ + Builder setMsgPath(PcepMsgPath msgPath); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepVersion.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepVersion.java new file mode 100755 index 00000000..c761ed08 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepVersion.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +/** + * Enum to provide PCEP Message Version. + */ +public enum PcepVersion { + + PCEP_1(1); + + public final int packetVersion; + + /** + * Assign PCEP PacketVersion with WireVersion. + * + * @param wireVersion version of pcep + */ + PcepVersion(final int wireVersion) { + + this.packetVersion = wireVersion; + } + + /** + * Returns Wire version of PCEP Message. + * + * @return packetVersion + */ + public int getWireVersion() { + return packetVersion; + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/Writeable.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/Writeable.java new file mode 100755 index 00000000..37aef58d --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/Writeable.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; + +/** + * Abstraction of an entity providing functionality to write byte streams of + * Messages to channel buffer. + */ +public interface Writeable { + + /** + * Writes byte streams of messages to channel buffer. + * + * @param bb parameter of type channel buffer + * @throws PcepParseException when error occurs while writing pcep message to channel buffer + */ + void writeTo(ChannelBuffer bb) throws PcepParseException; +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/package-info.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/package-info.java new file mode 100644 index 00000000..53ee5934 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Abstraction of an entity providing PCEP messages. + */ +package org.onosproject.pcepio.protocol; diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcInitiatedLspRequestVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcInitiatedLspRequestVer1.java new file mode 100644 index 00000000..d61f7319 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcInitiatedLspRequestVer1.java @@ -0,0 +1,291 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcInitiatedLspRequest; +import org.onosproject.pcepio.protocol.PcepAttribute; +import org.onosproject.pcepio.protocol.PcepEndPointsObject; +import org.onosproject.pcepio.protocol.PcepEroObject; +import org.onosproject.pcepio.protocol.PcepLspObject; +import org.onosproject.pcepio.protocol.PcepSrpObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PcInitiatedLspRequest for PCEP Initiate message. + * Reference : PCE initiated tunnel setup draft-ietf-pce-pce-initiated-lsp-03. + */ +public class PcInitiatedLspRequestVer1 implements PcInitiatedLspRequest { + + /* + * ::= (|) + ::= + + + + [] + ::= + + */ + + protected static final Logger log = LoggerFactory.getLogger(PcInitiatedLspRequestVer1.class); + + //PCEP SRP Object + private PcepSrpObject srpObject; + //PCEP LSP Object + private PcepLspObject lspObject; + //PCEP End Point Object + private PcepEndPointsObject endPointsObject; + //PCEP ERO Object + private PcepEroObject eroObject; + //PCEP Attribute list + private PcepAttribute pcepAttribute; + + /** + * Default constructor. + */ + public PcInitiatedLspRequestVer1() { + srpObject = null; + lspObject = null; + endPointsObject = null; + eroObject = null; + pcepAttribute = null; + + } + + /** + * Constructor to initialize all parameters of PC initiated lsp request. + * + * @param srpObject PCEP srp Object + * @param lspObject PCEP lsp object + * @param endPointsObject PCPE endpoints object + * @param eroObject PCEP ero object + * @param pcepAttribute PCEP attribute + */ + public PcInitiatedLspRequestVer1(PcepSrpObject srpObject, PcepLspObject lspObject, + PcepEndPointsObject endPointsObject, PcepEroObject eroObject, PcepAttribute pcepAttribute) { + this.srpObject = srpObject; + this.lspObject = lspObject; + this.endPointsObject = endPointsObject; + this.eroObject = eroObject; + this.pcepAttribute = pcepAttribute; + + } + + @Override + public PcepSrpObject getSrpObject() { + return srpObject; + } + + @Override + public PcepLspObject getLspObject() { + return lspObject; + } + + @Override + public PcepEndPointsObject getEndPointsObject() { + return endPointsObject; + } + + @Override + public PcepEroObject getEroObject() { + return eroObject; + } + + @Override + public PcepAttribute getPcepAttribute() { + return pcepAttribute; + } + + @Override + public void setSrpObject(PcepSrpObject srpobj) { + this.srpObject = srpobj; + + } + + @Override + public void setLspObject(PcepLspObject lspObject) { + this.lspObject = lspObject; + } + + @Override + public void setEndPointsObject(PcepEndPointsObject endPointsObject) { + this.endPointsObject = endPointsObject; + } + + @Override + public void setEroObject(PcepEroObject eroObject) { + this.eroObject = eroObject; + } + + @Override + public void setPcepAttribute(PcepAttribute pcepAttribute) { + this.pcepAttribute = pcepAttribute; + } + + /** + * Builder class for PC initiated lsp reuqest. + */ + public static class Builder implements PcInitiatedLspRequest.Builder { + + private boolean bIsSRPObjectSet = false; + private boolean bIsLSPObjectSet = false; + private boolean bIsEndPointsObjectSet = false; + private boolean bIsEROObjectSet = false; + private boolean bIsPcepAttributeSet = false; + private boolean bIsbRFlagSet = false; + + //PCEP SRP Object + private PcepSrpObject srpObject; + //PCEP LSP Object + private PcepLspObject lspObject; + //PCEP End Point Object + private PcepEndPointsObject endPointsObject; + //PCEP ERO Object + private PcepEroObject eroObject; + //PCEP Attribute list + private PcepAttribute pcepAttribute; + + @Override + public PcInitiatedLspRequest build() throws PcepParseException { + + //PCEP SRP Object + PcepSrpObject srpObject = null; + //PCEP LSP Object + PcepLspObject lspObject = null; + //PCEP End Point Object + PcepEndPointsObject endPointsObject = null; + //PCEP ERO Object + PcepEroObject eroObject = null; + //PCEP Attribute list + PcepAttribute pcepAttribute = null; + boolean bRFlag = false; + + if (!this.bIsSRPObjectSet) { + throw new PcepParseException("Srp object NOT Set while building PcInitiatedLspRequest"); + } else { + srpObject = this.srpObject; + bRFlag = srpObject.getRFlag(); + } + + if (bRFlag) { + this.bIsbRFlagSet = true; + } else { + this.bIsbRFlagSet = false; + } + + if (!this.bIsLSPObjectSet) { + throw new PcepParseException("LSP Object NOT Set while building PcInitiatedLspRequest"); + } else { + lspObject = this.lspObject; + } + if (!this.bIsbRFlagSet) { + + if (!this.bIsEndPointsObjectSet) { + throw new PcepParseException("EndPoints Object NOT Set while building PcInitiatedLspRequest"); + } else { + endPointsObject = this.endPointsObject; + } + if (!this.bIsEROObjectSet) { + throw new PcepParseException("ERO Object NOT Set while building PcInitiatedLspRequest"); + } else { + eroObject = this.eroObject; + } + if (bIsPcepAttributeSet) { + pcepAttribute = this.pcepAttribute; + } + } + return new PcInitiatedLspRequestVer1(srpObject, lspObject, endPointsObject, eroObject, pcepAttribute); + } + + @Override + public PcepSrpObject getSrpObject() { + return this.srpObject; + } + + @Override + public PcepLspObject getLspObject() { + return this.lspObject; + } + + @Override + public PcepEndPointsObject getEndPointsObject() { + return this.endPointsObject; + } + + @Override + public PcepEroObject getEroObject() { + return this.eroObject; + } + + @Override + public PcepAttribute getPcepAttribute() { + return this.pcepAttribute; + } + + @Override + public Builder setSrpObject(PcepSrpObject srpobj) { + this.srpObject = srpobj; + this.bIsSRPObjectSet = true; + return this; + + } + + @Override + public Builder setLspObject(PcepLspObject lspObject) { + this.lspObject = lspObject; + this.bIsLSPObjectSet = true; + return this; + } + + @Override + public Builder setEndPointsObject(PcepEndPointsObject endPointsObject) { + this.endPointsObject = endPointsObject; + this.bIsEndPointsObjectSet = true; + return this; + } + + @Override + public Builder setEroObject(PcepEroObject eroObject) { + this.eroObject = eroObject; + this.bIsEROObjectSet = true; + return this; + } + + @Override + public Builder setPcepAttribute(PcepAttribute pcepAttribute) { + this.pcepAttribute = pcepAttribute; + this.bIsPcepAttributeSet = true; + return this; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues() + .add("SrpObject", srpObject) + .add("LspObject", lspObject) + .add("EndPointObject", endPointsObject) + .add("EroObject", eroObject) + .add("PcepAttribute", pcepAttribute) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepAttributeVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepAttributeVer1.java new file mode 100644 index 00000000..65a844c2 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepAttributeVer1.java @@ -0,0 +1,431 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepAttribute; +import org.onosproject.pcepio.protocol.PcepBandwidthObject; +import org.onosproject.pcepio.protocol.PcepIroObject; +import org.onosproject.pcepio.protocol.PcepLspaObject; +import org.onosproject.pcepio.protocol.PcepMetricObject; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP Attribute List. + */ +public class PcepAttributeVer1 implements PcepAttribute { + + /* Reference : RFC5440 + * where: + * ::=[] + * [] + * [] + * [] + * + * ::=[] + */ + protected static final Logger log = LoggerFactory.getLogger(PcepAttributeVer1.class); + + public static final int OBJECT_HEADER_LENGTH = 4; + + //PCEP LSPA Object + private PcepLspaObject lspaObject; + private boolean isLspaObjectSet; + + //PCEP Bandwidth Object + private PcepBandwidthObject bandwidthObject; + private boolean isBandwidthObjectSet; + + //PCEP Metric list + private LinkedList llMetricList; + private boolean isMetricListSet; + + //PCEP IRO object + private PcepIroObject iroObject; + private boolean isIroObjectSet; + + /** + * Default constructor to initialize member variables. + */ + public PcepAttributeVer1() { + + lspaObject = null; + bandwidthObject = null; + llMetricList = null; + iroObject = null; + this.isLspaObjectSet = false; + this.isBandwidthObjectSet = false; + this.isMetricListSet = false; + this.isIroObjectSet = false; + } + + /** + * Constructor to initialize all parameters for PCEP attribute. + * + * @param lspaObject PCEP lspa Object. + * @param bandwidthObject PCEP bandwidth object. + * @param llMetricList list of PCEP metric objects. + * @param iroObject PCEP iro object. + */ + public PcepAttributeVer1(PcepLspaObject lspaObject, PcepBandwidthObject bandwidthObject, + LinkedList llMetricList, PcepIroObject iroObject) { + + this.lspaObject = lspaObject; + this.bandwidthObject = bandwidthObject; + this.llMetricList = llMetricList; + this.iroObject = iroObject; + if (lspaObject == null) { + this.isLspaObjectSet = false; + } else { + this.isLspaObjectSet = true; + } + if (bandwidthObject == null) { + this.isBandwidthObjectSet = false; + } else { + this.isBandwidthObjectSet = true; + } + if (llMetricList == null) { + this.isMetricListSet = false; + } else { + this.isMetricListSet = true; + } + if (iroObject == null) { + this.isIroObjectSet = false; + } else { + this.isIroObjectSet = true; + } + } + + /** + * constructor to initialize bandwidthObject. + * + * @param bandwidthObject bandwidth object + */ + public PcepAttributeVer1(PcepBandwidthObject bandwidthObject) { + this.isLspaObjectSet = false; + + this.bandwidthObject = bandwidthObject; + this.isBandwidthObjectSet = true; + + this.isMetricListSet = false; + + this.isIroObjectSet = false; + } + + /** + * Parse list for MeticObject. + * + * @param cb of type channel buffer + * @return true if parsing metric list is success + * @throws PcepParseException when a non metric object is received + */ + public boolean parseMetricList(ChannelBuffer cb) throws PcepParseException { + + if (llMetricList == null) { + llMetricList = new LinkedList<>(); + } + + PcepMetricObject metriclist; + + //caller should verify for metric object + byte yObjClass = PcepMetricObjectVer1.METRIC_OBJ_CLASS; + byte yObjType = PcepMetricObjectVer1.METRIC_OBJ_TYPE; + + while ((yObjClass == PcepMetricObjectVer1.METRIC_OBJ_CLASS) + && (yObjType == PcepMetricObjectVer1.METRIC_OBJ_TYPE)) { + + metriclist = PcepMetricObjectVer1.read(cb); + llMetricList.add(metriclist); + yObjClass = 0; + yObjType = 0; + + if (cb.readableBytes() > OBJECT_HEADER_LENGTH) { + cb.markReaderIndex(); + PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + yObjClass = tempObjHeader.getObjClass(); + yObjType = tempObjHeader.getObjType(); + } + } + return true; + } + + /** + * Reads lspa , bandwidth , Metriclist and Iro objects and sets the objects. + * + * @param cb of type channel buffer + * @return instance of Pcep Attribute + * @throws PcepParseException while parsing Pcep Attributes from channel buffer + */ + + public static PcepAttribute read(ChannelBuffer cb) throws PcepParseException { + if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { + return null; + } + //check whether any pcep attribute is present + cb.markReaderIndex(); + PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + byte yObjClass = tempObjHeader.getObjClass(); + + if (PcepLspaObjectVer1.LSPA_OBJ_CLASS != yObjClass && PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS != yObjClass + && PcepMetricObjectVer1.METRIC_OBJ_CLASS != yObjClass && PcepIroObjectVer1.IRO_OBJ_CLASS != yObjClass) { + //No PCEP attribute is present + return null; + } + + PcepAttributeVer1 pcepAttribute = new PcepAttributeVer1(); + + //If LSPA present then store it.LSPA is optional + if (yObjClass == PcepLspaObjectVer1.LSPA_OBJ_CLASS) { + pcepAttribute.setLspaObject(PcepLspaObjectVer1.read(cb)); + yObjClass = checkNextObject(cb); + } + + //If BANDWIDTH present then store it.BANDWIDTH is optional + if (yObjClass == PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS) { + pcepAttribute.setBandwidthObject(PcepBandwidthObjectVer1.read(cb)); + yObjClass = checkNextObject(cb); + } + + //If Metric list present then store it.MetricList is optional + if (yObjClass == PcepMetricObjectVer1.METRIC_OBJ_CLASS) { + pcepAttribute.parseMetricList(cb); + yObjClass = checkNextObject(cb); + } + + //If IRO present then store it.IRO is optional + if (yObjClass == PcepIroObjectVer1.IRO_OBJ_CLASS) { + pcepAttribute.setIroObject(PcepIroObjectVer1.read(cb)); + } + + PcepLspaObject lspaObject = pcepAttribute.getLspaObject(); + PcepBandwidthObject bandwidthObject = pcepAttribute.getBandwidthObject(); + LinkedList metriclist = pcepAttribute.llMetricList; + PcepIroObject iroObject = pcepAttribute.getIroObject(); + + return new PcepAttributeVer1(lspaObject, bandwidthObject, metriclist, iroObject); + } + + /** + * Checks whether there is a more object or not. + * + * @param cb of type channel buffer + * @return instance of object header + */ + private static byte checkNextObject(ChannelBuffer cb) { + if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { + return 0; + } + cb.markReaderIndex(); + PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + return tempObjHeader.getObjClass(); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + int iLenStartIndex = cb.writerIndex(); + //PCEP LSPA object is optional + if (this.isLspaObjectSet) { + this.lspaObject.write(cb); + } + + //PCEP BANDWIDTH object is optional + if (this.isBandwidthObjectSet) { + this.bandwidthObject.write(cb); + } + + //PCEP Metric list is optional + if (this.isMetricListSet) { + ListIterator listIterator = this.llMetricList.listIterator(); + while (listIterator.hasNext()) { + listIterator.next().write(cb); + } + } + + //PCEP IRO object is optional + if (this.isIroObjectSet) { + this.iroObject.write(cb); + } + return cb.writerIndex() - iLenStartIndex; + } + + @Override + public PcepLspaObject getLspaObject() { + return lspaObject; + } + + @Override + public PcepBandwidthObject getBandwidthObject() { + return bandwidthObject; + } + + @Override + public LinkedList getMetricObjectList() { + return llMetricList; + } + + @Override + public PcepIroObject getIroObject() { + return iroObject; + } + + @Override + public void setBandwidthObject(PcepBandwidthObject bandwidthObject) { + this.isBandwidthObjectSet = true; + this.bandwidthObject = bandwidthObject; + } + + @Override + public void setMetricObjectList(LinkedList llMetricList) { + this.isMetricListSet = true; + this.llMetricList = llMetricList; + + } + + @Override + public void setLspaObject(PcepLspaObject lspaObject) { + this.isLspaObjectSet = true; + this.lspaObject = lspaObject; + } + + @Override + public void setIroObject(PcepIroObject iroObject) { + this.isIroObjectSet = true; + this.iroObject = iroObject; + } + + /** + * Builder class for PCEP attributes. + */ + public static class Builder implements PcepAttribute.Builder { + + //PCEP LSPA Object + private PcepLspaObject lspaObject; + private boolean isLspaObjectSet; + + //PCEP BANDWIDTH Object + private PcepBandwidthObject bandwidthObject; + private boolean isBandwidthObjectSet; + + //PCEP Metric list + private LinkedList llMetricList; + private boolean isMetricListSet; + + //PCEP IRO object + private PcepIroObject iroObject; + private boolean isIroObjectSet; + + @Override + public PcepAttribute build() { + + //PCEP LSPA Object + PcepLspaObject lspaObject = null; + + //PCEP BANDWIDTH Object + PcepBandwidthObject bandwidthObject = null; + + //PCEP Metric list + LinkedList llMetricList = null; + + //PCEP IRO object + PcepIroObject iroObject = null; + + if (this.isLspaObjectSet) { + lspaObject = this.lspaObject; + } + if (this.isBandwidthObjectSet) { + bandwidthObject = this.bandwidthObject; + } + if (this.isMetricListSet) { + llMetricList = this.llMetricList; + } + if (this.isIroObjectSet) { + iroObject = this.iroObject; + } + return new PcepAttributeVer1(lspaObject, bandwidthObject, llMetricList, iroObject); + } + + @Override + public PcepLspaObject getLspaObject() { + return this.lspaObject; + } + + @Override + public PcepBandwidthObject getBandwidthObject() { + return this.bandwidthObject; + } + + @Override + public LinkedList getMetricObjectList() { + return this.llMetricList; + } + + @Override + public PcepIroObject getIroObject() { + return this.iroObject; + } + + @Override + public Builder setBandwidthObject(PcepBandwidthObject bandwidthObject) { + this.isBandwidthObjectSet = true; + this.bandwidthObject = bandwidthObject; + return this; + } + + @Override + public Builder setMetricObjectList(LinkedList llMetricList) { + this.isMetricListSet = true; + this.llMetricList = llMetricList; + return this; + } + + @Override + public Builder setLspaObject(PcepLspaObject lspaObject) { + this.isLspaObjectSet = true; + this.lspaObject = lspaObject; + return this; + } + + @Override + public Builder setIroObject(PcepIroObject iroObject) { + this.isIroObjectSet = true; + this.iroObject = iroObject; + return this; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues() + .add("lspaObject", lspaObject) + .add("bandwidthObject", bandwidthObject) + .add("MetricObjectList", llMetricList) + .add("IroObject", iroObject) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java new file mode 100644 index 00000000..1c78d5b4 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java @@ -0,0 +1,233 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepBandwidthObject; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PcepBandwidthObject. + */ +public class PcepBandwidthObjectVer1 implements PcepBandwidthObject { + + /* + * RFC : 5440 , section : 7.7. + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Bandwidth | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + The BANDWIDTH Object format + */ + + protected static final Logger log = LoggerFactory.getLogger(PcepBandwidthObjectVer1.class); + /* + * Requested bandwidth: BANDWIDTH Object-Type is 1. + Bandwidth of an existing TE LSP for which a re-optimization is + requested. BANDWIDTH Object-Type is 2. + */ + //Right now handling type 1 + public static final byte BANDWIDTH_OBJ_TYPE = 1; + public static final byte BANDWIDTH_OBJ_CLASS = 5; + public static final byte BANDWIDTH_OBJECT_VERSION = 1; + public static final short BANDWIDTH_OBJ_MINIMUM_LENGTH = 8; + + static final PcepObjectHeader DEFAULT_BANDWIDTH_OBJECT_HEADER = new PcepObjectHeader(BANDWIDTH_OBJ_CLASS, + BANDWIDTH_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, + BANDWIDTH_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader bandwidthObjHeader; + private int iBandwidth; + + /** + * Constructor to bandwidth object header and bandwidth. + * + * @param bandwidthObjHeader bandwidth object header + * @param iBandwidth bandwidth value + */ + public PcepBandwidthObjectVer1(PcepObjectHeader bandwidthObjHeader, int iBandwidth) { + this.bandwidthObjHeader = bandwidthObjHeader; + this.iBandwidth = iBandwidth; + } + + /** + * Constructor to initialize bandwidth. + * + * @param iBandwidth bandwidth value + */ + public PcepBandwidthObjectVer1(int iBandwidth) { + this.bandwidthObjHeader = DEFAULT_BANDWIDTH_OBJECT_HEADER; + this.iBandwidth = iBandwidth; + } + + /** + * Returns Object Header. + * + * @return bandwidthObjHeader + */ + public PcepObjectHeader getBandwidthObjHeader() { + return this.bandwidthObjHeader; + } + + /** + * Sets Object Header. + * + * @param obj bandwidth object header + */ + public void setBandwidthObjHeader(PcepObjectHeader obj) { + this.bandwidthObjHeader = obj; + } + + @Override + public int getBandwidth() { + return this.iBandwidth; + } + + @Override + public void setBandwidth(int iBandwidth) { + this.iBandwidth = iBandwidth; + } + + /** + * Reads from channel buffer and returns object of PcepBandwidthObject. + * + * @param cb channel buffer to parse + * @return object of PcepBandwidthObject + * @throws PcepParseException while parsing channel buffer + */ + public static PcepBandwidthObject read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader bandwidthObjHeader; + int iBandwidth; + + bandwidthObjHeader = PcepObjectHeader.read(cb); + iBandwidth = cb.readInt(); + + return new PcepBandwidthObjectVer1(bandwidthObjHeader, iBandwidth); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + //write Object header + int objStartIndex = cb.writerIndex(); + int objLenIndex = bandwidthObjHeader.write(cb); + + if (objLenIndex <= 0) { + throw new PcepParseException("Failed to write bandwidth object header. Index " + objLenIndex); + } + + cb.writeInt(iBandwidth); + short hLength = (short) (cb.writerIndex() - objStartIndex); + cb.setShort(objLenIndex, hLength); + //will be helpful during print(). + bandwidthObjHeader.setObjLen(hLength); + + return cb.writerIndex() - objStartIndex; + } + + /** + * builder class for PCEP bandwidth object. + */ + public static class Builder implements PcepBandwidthObject.Builder { + + private PcepObjectHeader bandwidthObjHeader; + private boolean bIsHeaderSet = false; + + private int iBandwidth; + private boolean bIsBandwidthSet = false; + + private boolean bPFlag; + private boolean bIsPFlagSet = false; + + private boolean bIFlag; + private boolean bIsIFlagSet = false; + + @Override + public PcepBandwidthObject build() throws PcepParseException { + + PcepObjectHeader bandwidthObjHeader = this.bIsHeaderSet ? this.bandwidthObjHeader + : DEFAULT_BANDWIDTH_OBJECT_HEADER; + + if (bIsPFlagSet) { + bandwidthObjHeader.setPFlag(bPFlag); + } + + if (bIsIFlagSet) { + bandwidthObjHeader.setIFlag(bIFlag); + } + + if (!this.bIsBandwidthSet) { + throw new PcepParseException("bandwidth not Set while building Bandwidth Object."); + } + + return new PcepBandwidthObjectVer1(bandwidthObjHeader, iBandwidth); + } + + @Override + public int getBandwidth() { + return this.iBandwidth; + } + + @Override + public PcepObjectHeader getBandwidthObjHeader() { + return this.bandwidthObjHeader; + } + + @Override + public Builder setBandwidthObjHeader(PcepObjectHeader obj) { + this.bandwidthObjHeader = obj; + return this; + } + + @Override + public Builder setBandwidth(int iBandwidth) { + this.iBandwidth = iBandwidth; + this.bIsBandwidthSet = true; + return this; + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("BandwidthObjectHeader", bandwidthObjHeader) + .add("Bandwidth", iBandwidth).toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepCloseMsgVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepCloseMsgVer1.java new file mode 100644 index 00000000..bcc679d3 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepCloseMsgVer1.java @@ -0,0 +1,351 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepCloseMsg; +import org.onosproject.pcepio.protocol.PcepMessageReader; +import org.onosproject.pcepio.protocol.PcepMessageWriter; +import org.onosproject.pcepio.protocol.PcepType; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP Close Message. + */ +class PcepCloseMsgVer1 implements PcepCloseMsg { + + /* + * RFC : 5440 , section : 6.8 + * ::= + * + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Ver | Flags | Message-Type | Message-Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Object-Class | OT |Res|P|I| Object Length (bytes) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved | Flags | Reason | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // Optional TLVs // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + protected static final Logger log = LoggerFactory.getLogger(PcepCloseMsgVer1.class); + + // Pcep version: 1 + public static final byte PACKET_VERSION = 1; + public static final int PACKET_MINIMUM_LENGTH = 12; + public static final PcepType MSG_TYPE = PcepType.CLOSE; + public static final byte CLOSE_OBJ_TYPE = 1; + public static final byte CLOSE_OBJ_CLASS = 15; + public static final byte CLOSE_OBJECT_VERSION = 1; + public static final byte DEFAULT_REASON = 1; // Default reason to close + public static final short CLOSE_OBJ_MINIMUM_LENGTH = 8; + public static final int SHIFT_FLAG = 5; + static final PcepObjectHeader DEFAULT_CLOSE_HEADER = new PcepObjectHeader(CLOSE_OBJ_CLASS, CLOSE_OBJ_TYPE, + PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, CLOSE_OBJ_MINIMUM_LENGTH); + + private final PcepObjectHeader closeObjHeader; + private byte yReason; + private LinkedList llOptionalTlv; + + public static final PcepCloseMsgVer1.Reader READER = new Reader(); + + /** + * Reader class for reading close message for channel buffer. + */ + static class Reader implements PcepMessageReader { + PcepObjectHeader closeObjHeader; + byte yReason; + // Optional TLV + private LinkedList llOptionalTlv; + + @Override + public PcepCloseMsg readFrom(ChannelBuffer cb) throws PcepParseException { + + if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) { + throw new PcepParseException("Packet size is less than the minimum length."); + } + // fixed value property version == 1 + byte version = cb.readByte(); + version = (byte) (version >> SHIFT_FLAG); + if (version != PACKET_VERSION) { + throw new PcepParseException("Wrong version. Expected=PcepVersion.PCEP_1(1), got=" + version); + } + // fixed value property type == 7 + byte type = cb.readByte(); + if (type != MSG_TYPE.getType()) { + throw new PcepParseException("Wrong type. Expected=PcepType.CLOSE(7), got=" + type); + } + short length = cb.readShort(); + if (length < PACKET_MINIMUM_LENGTH) { + throw new PcepParseException("Wrong length. Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + + length); + } + closeObjHeader = PcepObjectHeader.read(cb); + // Reserved + cb.readShort(); + // Flags + cb.readByte(); + // Reason + yReason = cb.readByte(); + // parse optional TLV + llOptionalTlv = parseOptionalTlv(cb); + return new PcepCloseMsgVer1(closeObjHeader, yReason, llOptionalTlv); + } + } + + /** + * Parse the list of Optional Tlvs. + * + * @param cb channel buffer + * @return list of Optional Tlvs + * @throws PcepParseException when fails to parse optional tlvs + */ + public static LinkedList parseOptionalTlv(ChannelBuffer cb) throws PcepParseException { + + LinkedList llOptionalTlv = new LinkedList<>(); + /* + rfc 5440: + Optional TLVs may be included within the CLOSE object body. The + specification of such TLVs is outside the scope of this document. + */ + return llOptionalTlv; + } + + /** + * constructor to initialize PCEP close Message with all the parameters. + * + * @param closeObjHeader object header for close message + * @param yReason reason for closing the channel + * @param llOptionalTlv list of optional tlvs + */ + PcepCloseMsgVer1(PcepObjectHeader closeObjHeader, byte yReason, LinkedList llOptionalTlv) { + + this.closeObjHeader = closeObjHeader; + this.yReason = yReason; + this.llOptionalTlv = llOptionalTlv; + } + + /** + * Builder class for PCEP close message. + */ + static class Builder implements PcepCloseMsg.Builder { + + // PCEP Close message fields + private boolean bIsHeaderSet = false; + private PcepObjectHeader closeObjHeader; + private boolean bIsReasonSet = false; + private byte yReason; + private LinkedList llOptionalTlv = new LinkedList<>(); + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepType getType() { + return PcepType.CLOSE; + } + + @Override + public PcepCloseMsg build() { + + PcepObjectHeader closeObjHeader = this.bIsHeaderSet ? this.closeObjHeader : DEFAULT_CLOSE_HEADER; + byte yReason = this.bIsReasonSet ? this.yReason : DEFAULT_REASON; + + if (bIsPFlagSet) { + closeObjHeader.setPFlag(bPFlag); + } + + if (bIsIFlagSet) { + closeObjHeader.setIFlag(bIFlag); + } + return new PcepCloseMsgVer1(closeObjHeader, yReason, this.llOptionalTlv); + } + + @Override + public PcepObjectHeader getCloseObjHeader() { + return this.closeObjHeader; + } + + @Override + public Builder setCloseObjHeader(PcepObjectHeader obj) { + this.closeObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public byte getReason() { + return this.yReason; + } + + @Override + public Builder setReason(byte value) { + this.yReason = value; + this.bIsReasonSet = true; + return this; + } + + @Override + public Builder setOptionalTlv(LinkedList llOptionalTlv) { + this.llOptionalTlv = llOptionalTlv; + return this; + } + + @Override + public LinkedList getOptionalTlv() { + return this.llOptionalTlv; + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + } + + @Override + public void writeTo(ChannelBuffer cb) throws PcepParseException { + WRITER.write(cb, this); + } + + static final Writer WRITER = new Writer(); + + /** + * Writer class for writing close message to channel buffer. + */ + static class Writer implements PcepMessageWriter { + + @Override + public void write(ChannelBuffer cb, PcepCloseMsgVer1 message) throws PcepParseException { + int startIndex = cb.writerIndex(); + // first 3 bits set to version + cb.writeByte((byte) (PACKET_VERSION << SHIFT_FLAG)); + // message type + cb.writeByte(MSG_TYPE.getType()); + // length is length of variable message, will be updated at the end + // Store the position of message + // length in buffer + int msgLenIndex = cb.writerIndex(); + cb.writeShort((short) 0); + int objStartIndex = cb.writerIndex(); + int objLenIndex = message.closeObjHeader.write(cb); + if (objLenIndex <= 0) { + throw new PcepParseException("Failed to write Close object header."); + } + // first 3 bits set to version + cb.writeShort(0); // Reserved + cb.writeByte(0); // Flags + cb.writeByte(message.yReason); + // Pack optional TLV + packOptionalTlv(cb, message); + int length = cb.writerIndex() - objStartIndex; + cb.setShort(objLenIndex, (short) length); + // will be helpful during print(). + message.closeObjHeader.setObjLen((short) length); + // As per RFC the length of object should be + // multiples of 4 + int pad = length % 4; + if (pad != 0) { + pad = 4 - pad; + for (int i = 0; i < pad; i++) { + cb.writeByte((byte) 0); + } + length = length + pad; + } + // update message length field + length = cb.writerIndex() - startIndex; + cb.setShort(msgLenIndex, (short) length); + } + + public void packOptionalTlv(ChannelBuffer cb, PcepCloseMsgVer1 message) { + + LinkedList llOptionalTlv = message.llOptionalTlv; + ListIterator listIterator = llOptionalTlv.listIterator(); + while (listIterator.hasNext()) { + listIterator.next().write(cb); + } + } + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepType getType() { + return MSG_TYPE; + } + + @Override + public byte getReason() { + return this.yReason; + } + + @Override + public void setReason(byte value) { + this.yReason = value; + } + + @Override + public LinkedList getOptionalTlv() { + return this.llOptionalTlv; + } + + @Override + public void setOptionalTlv(LinkedList llOptionalTlv) { + this.llOptionalTlv = llOptionalTlv; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("closeObjectHeader", closeObjHeader).add("Reason", yReason) + .add("OptionalTlvlist", llOptionalTlv).toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEndPointsObjectVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEndPointsObjectVer1.java new file mode 100644 index 00000000..08dc0c9b --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEndPointsObjectVer1.java @@ -0,0 +1,256 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepEndPointsObject; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP Endpoints Object. + */ +public class PcepEndPointsObjectVer1 implements PcepEndPointsObject { + + /* + * RFC : 5440 , section : 7.6 + * An End point is defined as follows: + END-POINTS Object-Class is 4. + + END-POINTS Object-Type is 1 for IPv4 and 2 for IPv6. + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Object-Class | OT |Res|P|I| Object Length (bytes) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Source IPv4 address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Destination IPv4 address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + */ + protected static final Logger log = LoggerFactory.getLogger(PcepEndPointsObjectVer1.class); + + static final byte END_POINTS_OBJ_TYPE = 1; + static final byte END_POINTS_OBJ_CLASS = 4; + static final byte END_POINTS_OBJECT_VERSION = 1; + static final short END_POINTS_OBJ_MINIMUM_LENGTH = 12; + public static byte endPointObjType; + + static final PcepObjectHeader DEFAULT_END_POINTS_OBJECT_HEADER = new PcepObjectHeader(END_POINTS_OBJ_CLASS, + END_POINTS_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, + END_POINTS_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader endPointsObjHeader; + public int sourceIpAddress; + public int destIpAddress; + + /** + * Constructor to initialize all variables. + * + * @param endPointsObjHeader end points object header + * @param sourceIpAddress source IP address + * @param destIpAddress destination IP address + */ + public PcepEndPointsObjectVer1(PcepObjectHeader endPointsObjHeader, int sourceIpAddress, int destIpAddress) { + + this.endPointsObjHeader = endPointsObjHeader; + this.sourceIpAddress = sourceIpAddress; + this.destIpAddress = destIpAddress; + } + + /** + * Sets End Points Object Header. + * + * @param obj of PcepObjectHeader + */ + public void setEndPointsObjHeader(PcepObjectHeader obj) { + this.endPointsObjHeader = obj; + } + + @Override + public void setSourceIpAddress(int sourceIpAddress) { + this.sourceIpAddress = sourceIpAddress; + } + + @Override + public void setDestIpAddress(int destIpAddress) { + this.destIpAddress = destIpAddress; + } + + @Override + public int getSourceIpAddress() { + return this.sourceIpAddress; + } + + @Override + public int getDestIpAddress() { + return this.destIpAddress; + } + + /** + * Reads from channel buffer and returns object of PcepEndPointsObject. + * + * @param cb of channel buffer + * @return object of PcepEndPointsObject + * @throws PcepParseException while parsing channel buffer + */ + public static PcepEndPointsObject read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader endPointsObjHeader; + int sourceIpAddress; + int destIpAddress; + + endPointsObjHeader = PcepObjectHeader.read(cb); + if (endPointsObjHeader.getObjType() == END_POINTS_OBJ_TYPE + && endPointsObjHeader.getObjClass() == END_POINTS_OBJ_CLASS) { + sourceIpAddress = cb.readInt(); + destIpAddress = cb.readInt(); + } else { + throw new PcepParseException("Expected PcepEndPointsObject."); + } + return new PcepEndPointsObjectVer1(endPointsObjHeader, sourceIpAddress, destIpAddress); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + int objStartIndex = cb.writerIndex(); + //write common header + int objLenIndex = endPointsObjHeader.write(cb); + + //write source IPv4 IP + cb.writeInt(sourceIpAddress); + //write destination IPv4 IP + cb.writeInt(destIpAddress); + + int length = cb.writerIndex() - objStartIndex; + //now write EndPoints Object Length + cb.setShort(objLenIndex, (short) length); + //will be helpful during print(). + endPointsObjHeader.setObjLen((short) length); + + return cb.writerIndex(); + + } + + /** + * Builder class for PCEP end points objects. + */ + public static class Builder implements PcepEndPointsObject.Builder { + + private boolean bIsHeaderSet = false; + private boolean bIsSourceIpAddressset = false; + private boolean bIsDestIpAddressset = false; + private PcepObjectHeader endpointsObjHeader; + private int sourceIpAddress; + private int destIpAddress; + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + @Override + public PcepEndPointsObject build() throws PcepParseException { + + PcepObjectHeader endpointsObjHeader = this.bIsHeaderSet ? this.endpointsObjHeader + : DEFAULT_END_POINTS_OBJECT_HEADER; + + if (bIsPFlagSet) { + endpointsObjHeader.setPFlag(bPFlag); + } + + if (bIsIFlagSet) { + endpointsObjHeader.setIFlag(bIFlag); + } + + if (!this.bIsSourceIpAddressset) { + throw new PcepParseException("SourceIpAddress not set while building EndPoints object"); + } + + if (!this.bIsDestIpAddressset) { + throw new PcepParseException("DestIpAddress not set while building EndPoints object"); + } + + return new PcepEndPointsObjectVer1(endpointsObjHeader, this.sourceIpAddress, this.destIpAddress); + } + + @Override + public PcepObjectHeader getEndPointsObjHeader() { + return this.endpointsObjHeader; + } + + @Override + public Builder setEndPointsObjHeader(PcepObjectHeader obj) { + this.endpointsObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public int getSourceIpAddress() { + return this.sourceIpAddress; + } + + @Override + public Builder setSourceIpAddress(int sourceIpAddress) { + this.sourceIpAddress = sourceIpAddress; + this.bIsSourceIpAddressset = true; + return this; + } + + @Override + public int getDestIpAddress() { + return this.destIpAddress; + } + + @Override + public Builder setDestIpAddress(int destIpAddress) { + this.destIpAddress = destIpAddress; + this.bIsDestIpAddressset = true; + return this; + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("sourceIpAddress", sourceIpAddress) + .add("destIpAddress", destIpAddress).toString(); + } + +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java new file mode 100644 index 00000000..4d7cb16e --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java @@ -0,0 +1,407 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepEroObject; +import org.onosproject.pcepio.types.AutonomousSystemTlv; +import org.onosproject.pcepio.types.IPv4SubObject; +import org.onosproject.pcepio.types.IPv6SubObject; +import org.onosproject.pcepio.types.PathKeySubObject; +import org.onosproject.pcepio.types.PcepErrorDetailInfo; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; +import org.onosproject.pcepio.types.SrEroSubObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP Ero Object. + */ +public class PcepEroObjectVer1 implements PcepEroObject { + /* + * rfc3209 + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Object-Class | OT |Res|P|I| Object Length (bytes) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // (Subobjects) // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + If a Path message contains multiple EXPLICIT_ROUTE objects, only the + first object is meaningful. Subsequent EXPLICIT_ROUTE objects MAY be + ignored and SHOULD NOT be propagated. + + In current implementation, only strict hops are supported. So, + empty ERO with no sub-objects is considered illegal. + + Subobjects: + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+ + |L| Type | Length | (Subobject contents) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+ + + L + + The L bit is an attribute of the subobject. The L bit is set + if the subobject represents a loose hop in the explicit route. + If the bit is not set, the subobject represents a strict hop in + the explicit route. + + Type + + The Type indicates the type of contents of the subobject. + + + Subobject 1: IPv4 address + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |L| Type | Length | IPv4 address (4 bytes) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IPv4 address (continued) | Prefix Length | Resvd | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Subobject 2: IPv6 Prefix + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |L| Type | Length | IPv6 address (16 bytes) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IPv6 address (continued) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IPv6 address (continued) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IPv6 address (continued) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IPv6 address (continued) | Prefix Length | Resvd | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Subobject 3: Autonomous System Number + + The contents of an Autonomous System (AS) number subobject are a 2- + octet AS number. The abstract node represented by this subobject is + the set of nodes belonging to the autonomous system. + + The length of the AS number subobject is 4 octets. + + Subobject 4: PATH_KEY_32_BIT_SUB_OBJ_TYPE: + + Pathkey subobject(RFC 5520): + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |L| Type | Length | Path-Key | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | PCE ID (4 bytes) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Subobject 5: SR_ERO_SUB_OBJ_TYPE: + + SR-ERO subobject: (draft-ietf-pce-segment-routing-00) + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |L| Type | Length | ST | Flags |F|S|C|M| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | SID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // NAI (variable) // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + protected static final Logger log = LoggerFactory.getLogger(PcepEroObjectVer1.class); + + public static final byte ERO_OBJ_TYPE = 1; + public static final byte ERO_OBJ_CLASS = 7; + public static final byte ERO_OBJECT_VERSION = 1; + public static final short ERO_OBJ_MINIMUM_LENGTH = 12; + public static final byte IPV4_TYPE = 1; + public static final byte PATH_KEY_32_BIT_SUB_OBJ_TYPE = 64; + public static final int LABEL_SUB_OBJ_TYPE = 3; + public static final int SR_ERO_SUB_OBJ_TYPE = 96; + public static final int OBJECT_HEADER_LENGTH = 4; + public static final int YTYPE_SHIFT_VALUE = 0x7F; + + static final PcepObjectHeader DEFAULT_ERO_OBJECT_HEADER = new PcepObjectHeader(ERO_OBJ_CLASS, ERO_OBJ_TYPE, + PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, ERO_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader eroObjHeader; + private LinkedList llSubObjects = new LinkedList<>(); + + /** + * reset variables. + */ + public PcepEroObjectVer1() { + this.eroObjHeader = null; + this.llSubObjects = null; + } + + /** + * Constructor to initialize parameters of ERO object. + * + * @param eroObjHeader ERO object header + * @param llSubObjects list of sub objects. + */ + public PcepEroObjectVer1(PcepObjectHeader eroObjHeader, LinkedList llSubObjects) { + + this.eroObjHeader = eroObjHeader; + this.llSubObjects = llSubObjects; + } + + /** + * Returns ERO object header. + * + * @return eroObjHeader ERO object header + */ + public PcepObjectHeader getEroObjHeader() { + return this.eroObjHeader; + } + + /** + * Sets Object Header. + * + * @param obj ERO object header + */ + public void setEroObjHeader(PcepObjectHeader obj) { + this.eroObjHeader = obj; + } + + @Override + public LinkedList getSubObjects() { + return this.llSubObjects; + } + + @Override + public void setSubObjects(LinkedList llSubObjects) { + this.llSubObjects = llSubObjects; + } + + /** + * Reads from channel buffer and returns object of PcepEroObject. + * + * @param cb channel buffer. + * @return object of PcepEroObject + * @throws PcepParseException when ERO object is not present in channel buffer + */ + public static PcepEroObject read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader eroObjHeader; + LinkedList llSubObjects = new LinkedList<>(); + + eroObjHeader = PcepObjectHeader.read(cb); + + if (eroObjHeader.getObjClass() != PcepEroObjectVer1.ERO_OBJ_CLASS) { + log.debug("ErrorType:" + PcepErrorDetailInfo.ERROR_TYPE_6 + " ErrorValue:" + + PcepErrorDetailInfo.ERROR_VALUE_9); + throw new PcepParseException(PcepErrorDetailInfo.ERROR_TYPE_6, PcepErrorDetailInfo.ERROR_VALUE_9); + } + + if (eroObjHeader.getObjLen() > OBJECT_HEADER_LENGTH) { + ChannelBuffer tempCb = cb.readBytes(eroObjHeader.getObjLen() - OBJECT_HEADER_LENGTH); + llSubObjects = parseSubObjects(tempCb); + } + return new PcepEroObjectVer1(eroObjHeader, llSubObjects); + } + + /** + * Parse list of Sub Objects. + * + * @param cb channel buffer + * @return list of Sub Objects + * @throws PcepParseException when fails to parse sub object list + */ + protected static LinkedList parseSubObjects(ChannelBuffer cb) throws PcepParseException { + + LinkedList llSubObjects = new LinkedList<>(); + + while (0 < cb.readableBytes()) { + + //check the Type of the TLV + byte yType = cb.readByte(); + yType = (byte) (yType & (YTYPE_SHIFT_VALUE)); + byte hLength = cb.readByte(); + + PcepValueType subObj; + + switch (yType) { + + case IPv4SubObject.TYPE: + subObj = IPv4SubObject.read(cb); + break; + case IPv6SubObject.TYPE: + byte[] ipv6Value = new byte[IPv6SubObject.VALUE_LENGTH]; + cb.readBytes(ipv6Value, 0, IPv6SubObject.VALUE_LENGTH); + subObj = new IPv6SubObject(ipv6Value); + break; + case AutonomousSystemTlv.TYPE: + subObj = AutonomousSystemTlv.read(cb); + break; + case PathKeySubObject.TYPE: + subObj = PathKeySubObject.read(cb); + break; + case SrEroSubObject.TYPE: + subObj = SrEroSubObject.read(cb); + break; + default: + throw new PcepParseException("Unexpected sub object. Type: " + (int) yType); + } + // Check for the padding + int pad = hLength % 4; + if (0 < pad) { + pad = 4 - pad; + if (pad <= cb.readableBytes()) { + cb.skipBytes(pad); + } + } + + llSubObjects.add(subObj); + } + if (0 < cb.readableBytes()) { + throw new PcepParseException("Subobject parsing error. Extra bytes received."); + } + return llSubObjects; + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + //write Object header + int objStartIndex = cb.writerIndex(); + + int objLenIndex = eroObjHeader.write(cb); + + if (objLenIndex <= 0) { + throw new PcepParseException("Failed to write ERO object header. Index " + objLenIndex); + } + + ListIterator listIterator = llSubObjects.listIterator(); + + while (listIterator.hasNext()) { + listIterator.next().write(cb); + } + + //Update object length now + int length = cb.writerIndex() - objStartIndex; + cb.setShort(objLenIndex, (short) length); + //will be helpful during print(). + eroObjHeader.setObjLen((short) length); + + //As per RFC the length of object should be multiples of 4 + int pad = length % 4; + + if (pad != 0) { + pad = 4 - pad; + for (int i = 0; i < pad; i++) { + cb.writeByte((byte) 0); + } + length = length + pad; + } + + objLenIndex = cb.writerIndex(); + return objLenIndex; + } + + /** + * Builder class for PCEP ERO object. + */ + public static class Builder implements PcepEroObject.Builder { + + private boolean bIsHeaderSet = false; + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + private PcepObjectHeader eroObjHeader; + LinkedList llSubObjects = new LinkedList<>(); + + @Override + public PcepEroObject build() { + + PcepObjectHeader eroObjHeader = this.bIsHeaderSet ? this.eroObjHeader : DEFAULT_ERO_OBJECT_HEADER; + + if (bIsPFlagSet) { + eroObjHeader.setPFlag(bPFlag); + } + + if (bIsIFlagSet) { + eroObjHeader.setIFlag(bIFlag); + } + + return new PcepEroObjectVer1(eroObjHeader, this.llSubObjects); + } + + @Override + public PcepObjectHeader getEroObjHeader() { + return this.eroObjHeader; + } + + @Override + public Builder setEroObjHeader(PcepObjectHeader obj) { + this.eroObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public LinkedList getSubObjects() { + return this.llSubObjects; + } + + @Override + public Builder setSubObjects(LinkedList llSubObjects) { + this.llSubObjects = llSubObjects; + return this; + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("EroObjHeader", eroObjHeader).add("SubObjects", llSubObjects) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java new file mode 100644 index 00000000..594e40c1 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java @@ -0,0 +1,204 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepError; +import org.onosproject.pcepio.protocol.PcepErrorInfo; +import org.onosproject.pcepio.protocol.PcepErrorObject; +import org.onosproject.pcepio.protocol.PcepRPObject; +import org.onosproject.pcepio.protocol.PcepTEObject; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP Error Info. + * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02. + */ +public class PcepErrorInfoVer1 implements PcepErrorInfo { + + protected static final Logger log = LoggerFactory.getLogger(PcepErrorInfoVer1.class); + //Error list is optional + private LinkedList errList; + + /** + * Constructor to add PCEP error object to the list. + * + * @param llRPObjList list of PCEP RP object + * @param llTEObjList list of PCEP TE object + * @param llErrObjList list of PCEP error object + */ + public PcepErrorInfoVer1(LinkedList llRPObjList, LinkedList llTEObjList, + LinkedList llErrObjList) { + this.errList = new LinkedList<>(); + if ((llErrObjList != null) && (!llErrObjList.isEmpty())) { + this.errList.add(new PcepErrorVer1(llRPObjList, llTEObjList, llErrObjList)); + } + } + + /** + * Constructor to initialize error info. + * + * @param errll linked list or pcep error + */ + public PcepErrorInfoVer1(LinkedList errll) { + this.errList = errll; + } + + @Override + public boolean isErrorInfoPresent() { + return !this.errList.isEmpty(); + } + + @Override + public void read(ChannelBuffer cb) throws PcepParseException { + PcepObjectHeader tempObjHeader; + + while (0 < cb.readableBytes()) { + cb.markReaderIndex(); + tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + byte yObjClass = tempObjHeader.getObjClass(); + if ((yObjClass != PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjClass != PcepTEObjectVer1.TE_OBJ_CLASS) + && (yObjClass != PcepErrorObjectVer1.ERROR_OBJ_CLASS)) { + throw new PcepParseException("Unknown Object is present in PCEP-ERROR. Object Class: " + yObjClass); + } + + this.errList.add(PcepErrorVer1.read(cb)); + } + } + + @Override + public void write(ChannelBuffer cb) throws PcepParseException { + //write + ListIterator listIterator = errList.listIterator(); + while (listIterator.hasNext()) { + PcepError pcepError = listIterator.next(); + + //RP Object list is optional + LinkedList llRPObjList = pcepError.getRPObjList(); + if (llRPObjList != null) { + ListIterator rpListIterator = llRPObjList.listIterator(); + while (rpListIterator.hasNext()) { + rpListIterator.next().write(cb); + } + } + + //TE Object list is optional + LinkedList llTEObjList = pcepError.getTEObjList(); + if (llTEObjList != null) { + ListIterator teListIterator = llTEObjList.listIterator(); + while (teListIterator.hasNext()) { + teListIterator.next().write(cb); + } + } + + // is mandatory + boolean bIsErrorObjListFound = false; + + LinkedList llErrObjList = pcepError.getErrorObjList(); + if (llErrObjList != null) { + ListIterator errObjListIterator = llErrObjList.listIterator(); + while (errObjListIterator.hasNext()) { + errObjListIterator.next().write(cb); + bIsErrorObjListFound = true; + } + } + + if (!bIsErrorObjListFound) { + throw new PcepParseException(" is mandatory."); + } + } + } + + @Override + public LinkedList getErrorType() { + LinkedList errorType = new LinkedList<>(); + ListIterator listIterator = errList.listIterator(); + PcepErrorObject errObj; + int error; + while (listIterator.hasNext()) { + PcepError pcepError = listIterator.next(); + LinkedList llErrObjList = pcepError.getErrorObjList(); + if (llErrObjList != null) { + ListIterator errObjListIterator = llErrObjList.listIterator(); + while (errObjListIterator.hasNext()) { + errObj = errObjListIterator.next(); + error = errObj.getErrorType(); + errorType.add(error); + } + } + } + return errorType; + } + + @Override + public LinkedList getErrorValue() { + LinkedList errorValue = new LinkedList<>(); + ListIterator listIterator = errList.listIterator(); + PcepErrorObject errObj; + int error; + while (listIterator.hasNext()) { + PcepError pcepError = listIterator.next(); + LinkedList llErrObjList = pcepError.getErrorObjList(); + if (llErrObjList != null) { + ListIterator errObjListIterator = llErrObjList.listIterator(); + while (errObjListIterator.hasNext()) { + errObj = errObjListIterator.next(); + error = errObj.getErrorValue(); + errorValue.add(error); + } + } + } + return errorValue; + } + + /** + * Builder class for PCEP error info. + */ + public static class Builder implements PcepErrorInfo.Builder { + private LinkedList errll; + + @Override + public PcepErrorInfo build() { + return new PcepErrorInfoVer1(errll); + } + + @Override + public LinkedList getPcepErrorList() { + return this.errll; + } + + @Override + public Builder setPcepErrorList(LinkedList errll) { + this.errll = errll; + return this; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("ErrorList", errList).toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java new file mode 100644 index 00000000..927d83d6 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java @@ -0,0 +1,383 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepErrorInfo; +import org.onosproject.pcepio.protocol.PcepErrorMsg; +import org.onosproject.pcepio.protocol.PcepErrorObject; +import org.onosproject.pcepio.protocol.PcepMessageReader; +import org.onosproject.pcepio.protocol.PcepMessageWriter; +import org.onosproject.pcepio.protocol.PcepOpenObject; +import org.onosproject.pcepio.protocol.PcepType; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.onosproject.pcepio.types.ErrorObjListWithOpen; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; +import com.google.common.base.MoreObjects.ToStringHelper; + +/** + * Provides PCEP Error Message. + */ +public class PcepErrorMsgVer1 implements PcepErrorMsg { + + /* + * PCE Error message format. + + ::= + ( [] ) | + [] + + ::=[] + + ::=[ | ] + + + ::=[] + + ::=[] + + ::=[] + */ + + protected static final Logger log = LoggerFactory.getLogger(PcepOpenMsgVer1.class); + public static final byte PACKET_VERSION = 1; + public static final int PACKET_MINIMUM_LENGTH = 12; + public static final PcepType MSG_TYPE = PcepType.ERROR; + + //Below either one should be present. + private ErrorObjListWithOpen errObjListWithOpen; //optional ( [] ) + private PcepErrorInfo errInfo; //optional [] + + public static final PcepErrorMsgVer1.Reader READER = new Reader(); + + /** + * constructor to initialize variables. + */ + public PcepErrorMsgVer1() { + errObjListWithOpen = null; + errInfo = null; + } + + /** + * Constructor to initialize variables. + * + * @param errObjListWithOpen error-object-list with open object + * @param errInfo error information + */ + public PcepErrorMsgVer1(ErrorObjListWithOpen errObjListWithOpen, PcepErrorInfo errInfo) { + this.errObjListWithOpen = errObjListWithOpen; + this.errInfo = errInfo; + } + + /** + * Reader class for reading PCEP error Message from channel buffer. + */ + public static class Reader implements PcepMessageReader { + + ErrorObjListWithOpen errObjListWithOpen; + PcepErrorInfo errInfo; + PcepObjectHeader tempObjHeader; + + @Override + public PcepErrorMsg readFrom(ChannelBuffer cb) throws PcepParseException { + + errObjListWithOpen = null; + errInfo = null; + tempObjHeader = null; + + if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) { + throw new PcepParseException("Packet size is less than the minimum length."); + } + + byte version = cb.readByte(); + version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG); + if (version != PACKET_VERSION) { + throw new PcepParseException("Wrong version: Expected=PcepVersion.PCEP_1(1), got=" + version); + } + // fixed value property type == 1 + byte type = cb.readByte(); + if (type != MSG_TYPE.getType()) { + throw new PcepParseException("Wrong type: Expected=PcepType.ERROR(6), got=" + type); + } + int length = cb.readShort(); + if (length < PACKET_MINIMUM_LENGTH) { + throw new PcepParseException( + "Wrong length: Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + length); + } + + //parse + parsePCErrMsg(cb); + + // If other than RP or TE or PCEP-ERROR present then it is error. + if (0 < cb.readableBytes()) { + PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); + throw new PcepParseException("Unexpected Object found. Object Class : " + tempObjHeader.getObjClass()); + } + + return new PcepErrorMsgVer1(errObjListWithOpen, errInfo); + } + + /** + * Parsing PCErr Message. + * + * @param cb channel buffer. + * @throws PcepParseException if mandatory fields are missing + * output: this.errObjListWithOpen, this.errInfo + */ + public void parsePCErrMsg(ChannelBuffer cb) throws PcepParseException { + //If PCEP-ERROR list is followed by OPEN Object then store into ErrorObjListWithOpen. + // ( [] + //If PCEP-ERROR list is followed by RP or TE Object then store into errInfo. [] + //If only PCEP-ERROR list is present then store into ErrorObjListWithOpen. + PcepObjectHeader tempObjHeader; + LinkedList llErrObjList; + + if (0 >= cb.readableBytes()) { + throw new PcepParseException("PCEP-ERROR message came with empty objects."); + } + + //parse PCEP-ERROR list + llErrObjList = new LinkedList<>(); + tempObjHeader = parseErrorObjectList(llErrObjList, cb); + + //check whether OPEN-OBJECT is present. + if ((tempObjHeader != null) + && (tempObjHeader.getObjClass() == PcepOpenObjectVer1.OPEN_OBJ_CLASS)) { + + if (llErrObjList.isEmpty()) { + throw new PcepParseException(" should be present if OPEN-OBJECT exists"); + } + + PcepOpenObject pcepOpenObj = PcepOpenObjectVer1.read(cb); + this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList, pcepOpenObj); + + } else if ((tempObjHeader != null) //check whether RP or TE Object is present. + && ((tempObjHeader.getObjClass() == PcepRPObjectVer1.RP_OBJ_CLASS) + || (tempObjHeader.getObjClass() == PcepTEObjectVer1.TE_OBJ_CLASS))) { + + this.errInfo = new PcepErrorInfoVer1(null, null, llErrObjList); + this.errInfo.read(cb); + + } else if (!llErrObjList.isEmpty()) { + //If only PCEP-ERROR list is present then store it in errObjListWithOpen. + this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList); + } else { + throw new PcepParseException("Empty PCEP-ERROR message."); + } + } + + /** + * Parse error-obj-list. + * + * @param llErrObjList error object list output + * @param cb channel buffer input + * @throws PcepParseException if mandatory fields are missing + * @return error object header + */ + public PcepObjectHeader parseErrorObjectList(LinkedList llErrObjList, ChannelBuffer cb) + throws PcepParseException { + PcepObjectHeader tempObjHeader = null; + + while (0 < cb.readableBytes()) { + cb.markReaderIndex(); + tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + if (tempObjHeader.getObjClass() == PcepErrorObjectVer1.ERROR_OBJ_CLASS) { + llErrObjList.add(PcepErrorObjectVer1.read(cb)); + } else { + break; + } + } + return tempObjHeader; + } + } + + /** + * Builder class for PCEP error message. + */ + public static class Builder implements PcepErrorMsg.Builder { + // Pcep error message fields + + private ErrorObjListWithOpen errObjListWithOpen = null; //optional ( [] ) + private PcepErrorInfo errInfo = null; //optional [] + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepType getType() { + return PcepType.ERROR; + } + + @Override + public PcepErrorMsg build() { + return new PcepErrorMsgVer1(this.errObjListWithOpen, this.errInfo); + } + + @Override + public ErrorObjListWithOpen getErrorObjListWithOpen() { + return this.errObjListWithOpen; + } + + @Override + public Builder setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) { + this.errObjListWithOpen = errObjListWithOpen; + return this; + } + + @Override + public PcepErrorInfo getPcepErrorInfo() { + return this.errInfo; + } + + @Override + public Builder setPcepErrorInfo(PcepErrorInfo errInfo) { + this.errInfo = errInfo; + return this; + } + } + + @Override + public void writeTo(ChannelBuffer cb) throws PcepParseException { + WRITER.write(cb, this); + } + + public static final Writer WRITER = new Writer(); + + /** + * Writer class for writing PCEP error Message to channel buffer. + */ + static class Writer implements PcepMessageWriter { + @Override + public void write(ChannelBuffer cb, PcepErrorMsgVer1 message) throws PcepParseException { + int startIndex = cb.writerIndex(); + // first 3 bits set to version + cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG)); + // message type 0xC + cb.writeByte(MSG_TYPE.getType()); + // length is length of variable message, will be updated at the end + // Store the position of message + // length in buffer + int msgLenIndex = cb.writerIndex(); + cb.writeShort(0); + ErrorObjListWithOpen errObjListWithOpen = message.getErrorObjListWithOpen(); + PcepErrorInfo errInfo = message.getPcepErrorInfo(); + + // write ( [] ) if exists. + // otherwise write [] + + if ((errObjListWithOpen != null) + && (errObjListWithOpen.isErrorObjListWithOpenPresent())) { + errObjListWithOpen.write(cb); + } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) { + errInfo.write(cb); + } else { + throw new PcepParseException("Empty PCEP-ERROR message."); + } + // PcepErrorMessage message length field + int length = cb.writerIndex() - startIndex; + cb.setShort(msgLenIndex, (short) length); + } + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepType getType() { + return MSG_TYPE; + } + + @Override + public ErrorObjListWithOpen getErrorObjListWithOpen() { + return this.errObjListWithOpen; + } + + @Override + public void setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) { + this.errObjListWithOpen = errObjListWithOpen; + } + + @Override + public PcepErrorInfo getPcepErrorInfo() { + return this.errInfo; + } + + @Override + public void setPcepErrorInfo(PcepErrorInfo errInfo) { + this.errInfo = errInfo; + } + + /** + * Return list of Error types. + * + * @return error types list + */ + public LinkedList getErrorType() { + LinkedList llErrorType = new LinkedList<>(); + if ((errObjListWithOpen != null) + && (errObjListWithOpen.isErrorObjListWithOpenPresent())) { + llErrorType = errObjListWithOpen.getErrorType(); + } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) { + llErrorType = errInfo.getErrorType(); + } + + return llErrorType; + } + + /** + * Return list of Error values. + * + * @return error value list + */ + public LinkedList getErrorValue() { + LinkedList llErrorValue = new LinkedList<>(); + if ((errObjListWithOpen != null) + && (errObjListWithOpen.isErrorObjListWithOpenPresent())) { + llErrorValue = errObjListWithOpen.getErrorValue(); + } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) { + llErrorValue = errInfo.getErrorValue(); + } + + return llErrorValue; + } + + @Override + public String toString() { + ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass()); + + if ((errObjListWithOpen != null) + && (errObjListWithOpen.isErrorObjListWithOpenPresent())) { + toStrHelper.add("ErrorObjectListWithOpen", errObjListWithOpen); + } + if ((errInfo != null) && (errInfo.isErrorInfoPresent())) { + toStrHelper.add("ErrorInfo", errInfo); + } + + return toStrHelper.toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java new file mode 100644 index 00000000..48a337f4 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java @@ -0,0 +1,341 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepErrorObject; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP Error Object. + */ +public class PcepErrorObjectVer1 implements PcepErrorObject { + + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Object-Class | OT |Res|P|I| Object Length (bytes) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved | Flags | Error-Type | Error-value | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // Optional TLVs // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + protected static final Logger log = LoggerFactory.getLogger(PcepErrorObjectVer1.class); + + public static final byte ERROR_OBJ_TYPE = 1; + public static final byte ERROR_OBJ_CLASS = 13; + public static final byte ERROR_OBJECT_VERSION = 1; + //ERROR_OBJ_MINIMUM_LENGTH = CommonHeaderLen(4)+ErrorObjectHeaderLen(4) + public static final short ERROR_OBJ_MINIMUM_LENGTH = 8; + public static final int OBJECT_HEADER_LENGTH = 4; + + public static final PcepObjectHeader DEFAULT_ERROR_OBJECT_HEADER = new PcepObjectHeader(ERROR_OBJ_CLASS, + ERROR_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, + ERROR_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader errorObjHeader; + private byte yErrorType; + private byte yErrorValue; + private LinkedList llOptionalTlv; // Optional TLV + + /** + * Constructor to initialize variables. + * + * @param errorObjHeader ERROR Object header + * @param yErrorType Error Type + * @param yErrorValue Error Value + * @param llOptionalTlv list of optional TLV + */ + + public PcepErrorObjectVer1(PcepObjectHeader errorObjHeader, byte yErrorType, byte yErrorValue, + LinkedList llOptionalTlv) { + this.errorObjHeader = errorObjHeader; + this.yErrorType = yErrorType; + this.yErrorValue = yErrorValue; + this.llOptionalTlv = llOptionalTlv; + } + + /** + * sets Object Header. + * + * @param obj Error-Object header + */ + public void setLspObjHeader(PcepObjectHeader obj) { + this.errorObjHeader = obj; + } + + @Override + public void setErrorType(byte yErrorType) { + this.yErrorType = yErrorType; + } + + @Override + public void setErrorValue(byte yErrorValue) { + this.yErrorValue = yErrorValue; + } + + /** + * returns object header. + * + * @return errorObjHeader Error-Object header + */ + public PcepObjectHeader getErrorObjHeader() { + return this.errorObjHeader; + } + + @Override + public int getErrorType() { + return this.yErrorType; + } + + @Override + public byte getErrorValue() { + return this.yErrorValue; + } + + @Override + public LinkedList getOptionalTlv() { + return this.llOptionalTlv; + } + + @Override + public void setOptionalTlv(LinkedList llOptionalTlv) { + this.llOptionalTlv = llOptionalTlv; + } + + /** + * Reads from channel buffer and returns object of PcepErrorObject. + * + * @param cb of channel buffer. + * @return object of PCEP-ERROR-OBJECT + */ + public static PcepErrorObject read(ChannelBuffer cb) { + + PcepObjectHeader errorObjHeader; + byte yErrorType; + byte yErrorValue; + LinkedList llOptionalTlv; + + errorObjHeader = PcepObjectHeader.read(cb); + + //take only ErrorObject buffer. + ChannelBuffer tempCb = cb.readBytes(errorObjHeader.getObjLen() - OBJECT_HEADER_LENGTH); + tempCb.readByte(); //ignore Reserved + tempCb.readByte(); //ignore Flags + yErrorType = tempCb.readByte(); + yErrorValue = tempCb.readByte(); + + llOptionalTlv = parseOptionalTlv(tempCb); + + return new PcepErrorObjectVer1(errorObjHeader, yErrorType, yErrorValue, llOptionalTlv); + } + + /** + * returns Linked list of optional tlvs. + * + * @param cb channel buffer. + * @return Linked list of optional tlvs + */ + protected static LinkedList parseOptionalTlv(ChannelBuffer cb) { + + LinkedList llOutOptionalTlv = new LinkedList<>(); + + byte[] yTemp = new byte[cb.readableBytes()]; + cb.readBytes(yTemp); + + return llOutOptionalTlv; + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + //write Object header + int objStartIndex = cb.writerIndex(); + + int objLenIndex = errorObjHeader.write(cb); + + if (objLenIndex <= 0) { + throw new PcepParseException("While writing Error Object Header."); + } + + //write Reserved + cb.writeByte(0); + //write Flags + cb.writeByte(0); + //write ErrorType and ErrorValue + cb.writeByte(this.yErrorType); + cb.writeByte(this.yErrorValue); + + // Add optional TLV + packOptionalTlv(cb); + + //Update object length now + int length = cb.writerIndex() - objStartIndex; + //will be helpful during print(). + errorObjHeader.setObjLen((short) length); + // As per RFC the length of object should be + // multiples of 4 + int pad = length % 4; + if (pad != 0) { + pad = 4 - pad; + for (int i = 0; i < pad; i++) { + cb.writeByte((byte) 0); + } + length = length + pad; + } + + cb.setShort(objLenIndex, (short) length); + return length; + } + + /** + * Pack the Optional tlvs. + * + * @param cb channel buffer. + * @return writer index. + */ + protected int packOptionalTlv(ChannelBuffer cb) { + + ListIterator listIterator = llOptionalTlv.listIterator(); + int startIndex = cb.writerIndex(); + while (listIterator.hasNext()) { + PcepValueType tlv = listIterator.next(); + + if (tlv == null) { + log.debug("TLV is null from OptionalTlv list"); + continue; + } + tlv.write(cb); + } + + return cb.writerIndex() - startIndex; + } + + /** + * Builder class for PCEP error object. + */ + public static class Builder implements PcepErrorObject.Builder { + + private boolean bIsHeaderSet = false; + + private PcepObjectHeader errorObjHeader; + private byte yErrorType; + private byte yErrorValue; + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + private LinkedList llOptionalTlv = new LinkedList<>(); + + @Override + public PcepErrorObject build() { + + PcepObjectHeader errorObjHeader = this.bIsHeaderSet ? this.errorObjHeader : DEFAULT_ERROR_OBJECT_HEADER; + + if (bIsPFlagSet) { + errorObjHeader.setPFlag(bPFlag); + } + + if (bIsIFlagSet) { + errorObjHeader.setIFlag(bIFlag); + } + + return new PcepErrorObjectVer1(errorObjHeader, yErrorType, yErrorValue, llOptionalTlv); + } + + @Override + public PcepObjectHeader getErrorObjHeader() { + return this.errorObjHeader; + } + + @Override + public Builder setErrorObjHeader(PcepObjectHeader obj) { + this.errorObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public int getErrorType() { + return this.yErrorType; + } + + @Override + public Builder setErrorType(byte value) { + this.yErrorType = value; + return this; + } + + @Override + public byte getErrorValue() { + return this.yErrorValue; + } + + @Override + public Builder setErrorValue(byte value) { + this.yErrorValue = value; + return this; + } + + @Override + public Builder setOptionalTlv(LinkedList llOptionalTlv) { + this.llOptionalTlv = llOptionalTlv; + return this; + } + + @Override + public LinkedList getOptionalTlv() { + return this.llOptionalTlv; + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("ObjectHeader", errorObjHeader).add("ErrorType", yErrorType) + .add("ErrorValue", yErrorValue).add("OptionalTlv", llOptionalTlv).toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java new file mode 100644 index 00000000..0ea51410 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java @@ -0,0 +1,399 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepError; +import org.onosproject.pcepio.protocol.PcepErrorObject; +import org.onosproject.pcepio.protocol.PcepRPObject; +import org.onosproject.pcepio.protocol.PcepTEObject; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PcepError list which contains RP or TE objects. + * Reference:PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02. + */ +public class PcepErrorVer1 implements PcepError { + + /* + ::=[ | ] + + + ::=[] + + ::=[] + */ + + protected static final Logger log = LoggerFactory.getLogger(PcepErrorVer1.class); + + private boolean isErroInfoSet; + //PcepErrorObject list + private LinkedList llErrObjList; + //PcepRPObject list + private LinkedList llRPObjList; + //PcepTEObject list + private LinkedList llTEObjList; + private boolean isTEObjListSet; + + public static final int OBJECT_HEADER_LENGTH = 4; + + /** + * Constructor to initialize variable. + */ + public PcepErrorVer1() { + this.llRPObjList = null; + this.llTEObjList = null; + this.llErrObjList = null; + } + + /** + * Constructor to initialize variable. + * + * @param llRPObjList list of PcepRPObject + * @param llTEObjList list of PcepTEObject + * @param llErrObjListObjList list of PcepErrorObject + */ + public PcepErrorVer1(LinkedList llRPObjList, LinkedList llTEObjList, + LinkedList llErrObjListObjList) { + this.llRPObjList = llRPObjList; + this.llTEObjList = llTEObjList; + this.llErrObjList = llErrObjListObjList; + } + + /** + * Constructor to initialize PcepError. + * + * @param llErrObjList list of PcepErrorObject + */ + public PcepErrorVer1(LinkedList llErrObjList) { + this.llRPObjList = null; + this.llTEObjList = null; + this.llErrObjList = llErrObjList; + } + + @Override + public LinkedList getRPObjList() { + return this.llRPObjList; + } + + @Override + public LinkedList getTEObjList() { + return this.llTEObjList; + } + + @Override + public LinkedList getErrorObjList() { + return this.llErrObjList; + } + + /** + * Parse RP List from the channel buffer. + * + * @param cb of type channel buffer + * @throws PcepParseException if mandatory fields are missing + */ + public void parseRPList(ChannelBuffer cb) throws PcepParseException { + byte yObjClass; + byte yObjType; + + llRPObjList = new LinkedList<>(); + + // caller should verify for RP object + if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { + log.debug("Unable to find RP Object"); + return; + } + + cb.markReaderIndex(); + PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + yObjClass = tempObjHeader.getObjClass(); + yObjType = tempObjHeader.getObjType(); + PcepRPObject rpObj; + while ((yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjType == PcepRPObjectVer1.RP_OBJ_TYPE)) { + rpObj = PcepRPObjectVer1.read(cb); + llRPObjList.add(rpObj); + + if (cb.readableBytes() > OBJECT_HEADER_LENGTH) { + cb.markReaderIndex(); + tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + yObjClass = tempObjHeader.getObjClass(); + yObjType = tempObjHeader.getObjType(); + } else { + break; + } + } + } + + /** + * Parse TE List from the channel buffer. + * + * @param cb of type channel buffer + * @throws PcepParseException if mandatory fields are missing + */ + public void parseTEList(ChannelBuffer cb) throws PcepParseException { + byte yObjClass; + byte yObjType; + + llTEObjList = new LinkedList<>(); + + // caller should verify for TE object + if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { + log.debug("Unable to find TE Object"); + return; + } + + cb.markReaderIndex(); + PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + yObjClass = tempObjHeader.getObjClass(); + yObjType = tempObjHeader.getObjType(); + PcepTEObject teObj; + while ((yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) && ((yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_NODE_VALUE) + || (yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_LINK_VALUE))) { + teObj = PcepTEObjectVer1.read(cb); + llTEObjList.add(teObj); + + if (cb.readableBytes() > OBJECT_HEADER_LENGTH) { + cb.markReaderIndex(); + tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + yObjClass = tempObjHeader.getObjClass(); + yObjType = tempObjHeader.getObjType(); + } else { + break; + } + } + } + + /** + * parseErrObjList from the channel buffer. + * + * @param cb of type channel buffer + * @throws PcepParseException if mandatory fields are missing + */ + public void parseErrObjList(ChannelBuffer cb) throws PcepParseException { + byte yObjClass; + byte yObjType; + boolean bIsErrorObjFound = false; + + llErrObjList = new LinkedList<>(); + + // caller should verify for RP object + if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { + throw new PcepParseException("Unable to find PCEP-ERROR Object"); + } + + cb.markReaderIndex(); + PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + yObjClass = tempObjHeader.getObjClass(); + yObjType = tempObjHeader.getObjType(); + PcepErrorObject errorObject; + while ((yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) && (yObjType == PcepErrorObjectVer1.ERROR_OBJ_TYPE)) { + errorObject = PcepErrorObjectVer1.read(cb); + llErrObjList.add(errorObject); + bIsErrorObjFound = true; + + if (cb.readableBytes() > OBJECT_HEADER_LENGTH) { + cb.markReaderIndex(); + tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + yObjClass = tempObjHeader.getObjClass(); + yObjType = tempObjHeader.getObjType(); + } else { + break; + } + } + + if (!bIsErrorObjFound) { + throw new PcepParseException("At least one PCEP-ERROR Object should be present."); + } + } + + /** + * Reads the byte stream of PcepError from channel buffer. + * + * @param cb of type channel buffer + * @return PcepError error part of PCEP-ERROR + * @throws PcepParseException if mandatory fields are missing + */ + public static PcepErrorVer1 read(ChannelBuffer cb) throws PcepParseException { + if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { + throw new PcepParseException("Unknown Object"); + } + + PcepErrorVer1 pcepError = new PcepErrorVer1(); + // check whether any PCEP Error Info is present + cb.markReaderIndex(); + PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + byte yObjClass = tempObjHeader.getObjClass(); + + //If RPlist present then store it.RPList and TEList are optional + if (yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) { + log.debug("RP_LIST"); + pcepError.parseRPList(cb); + yObjClass = checkNextObject(cb); + } else if (yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) { + log.debug("TE_LIST"); + pcepError.parseTEList(cb); + yObjClass = checkNextObject(cb); + } + + if (yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) { + log.debug("PCEP-ERROR obj list"); + pcepError.parseErrObjList(cb); + yObjClass = checkNextObject(cb); + } + + return pcepError; + } + + /** + * Checks Next Object. + * + * @param cb of type channel buffer. + * @return object type class. + */ + private static byte checkNextObject(ChannelBuffer cb) { + if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { + return 0; + } + cb.markReaderIndex(); + PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); + cb.resetReaderIndex(); + return tempObjHeader.getObjClass(); + } + + /** + * Writes the byte stream of PCEP error to the channel buffer. + * + * @param cb of type channel buffer + * @return object length index + * @throws PcepParseException if mandatory fields are missing + */ + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + int iLenStartIndex = cb.writerIndex(); + + // RPlist is optional + if (this.isErroInfoSet) { + ListIterator rpObjlistIterator = this.llRPObjList.listIterator(); + while (rpObjlistIterator.hasNext()) { + rpObjlistIterator.next().write(cb); + } + } + + // TElist is optional + if (this.isTEObjListSet) { + ListIterator teObjlistIterator = this.llTEObjList.listIterator(); + while (teObjlistIterator.hasNext()) { + teObjlistIterator.next().write(cb); + } + } + //ErrList is mandatory + ListIterator errlistIterator = this.llErrObjList.listIterator(); + while (errlistIterator.hasNext()) { + errlistIterator.next().write(cb); + } + + return cb.writerIndex() - iLenStartIndex; + } + + /** + * Builder for error part of PCEP-ERROR. + */ + public static class Builder implements PcepError.Builder { + + private LinkedList llRPObjList; + private LinkedList llTEObjList; + private LinkedList llErrObjList; + + @Override + public PcepError build() { + return new PcepErrorVer1(llRPObjList, llTEObjList, llErrObjList); + } + + @Override + public LinkedList getRPObjList() { + return this.llRPObjList; + } + + @Override + public Builder setRPObjList(LinkedList llRPObjList) { + this.llRPObjList = llRPObjList; + return this; + } + + @Override + public LinkedList getTEObjList() { + return this.llTEObjList; + } + + @Override + public Builder setTEObjList(LinkedList llTEObjList) { + this.llTEObjList = llTEObjList; + return this; + } + + @Override + public LinkedList getErrorObjList() { + return this.llErrObjList; + } + + @Override + public Builder setErrorObjList(LinkedList llErrObjList) { + this.llErrObjList = llErrObjList; + return this; + } + + } + + @Override + public void setRPObjList(LinkedList llRPObjList) { + this.llRPObjList = llRPObjList; + } + + @Override + public void setTEObjList(LinkedList llTEObjList) { + this.llTEObjList = llTEObjList; + } + + @Override + public void setErrorObjList(LinkedList llErrObjList) { + this.llErrObjList = llErrObjList; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues() + .add("RpObjectList", llRPObjList) + .add("TeObjectList", llTEObjList) + .add("ErrorObjectList", llErrObjList) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFactoryVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFactoryVer1.java new file mode 100644 index 00000000..6b5d450a --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFactoryVer1.java @@ -0,0 +1,226 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.onosproject.pcepio.protocol.PcInitiatedLspRequest; +import org.onosproject.pcepio.protocol.PcepAttribute; +import org.onosproject.pcepio.protocol.PcepBandwidthObject; +import org.onosproject.pcepio.protocol.PcepCloseMsg; +import org.onosproject.pcepio.protocol.PcepEndPointsObject; +import org.onosproject.pcepio.protocol.PcepEroObject; +import org.onosproject.pcepio.protocol.PcepErrorInfo; +import org.onosproject.pcepio.protocol.PcepError; +import org.onosproject.pcepio.protocol.PcepErrorMsg; +import org.onosproject.pcepio.protocol.PcepErrorObject; +import org.onosproject.pcepio.protocol.PcepFactory; +import org.onosproject.pcepio.protocol.PcepFecObjectIPv4Adjacency; +import org.onosproject.pcepio.protocol.PcepInitiateMsg; +import org.onosproject.pcepio.protocol.PcepIroObject; +import org.onosproject.pcepio.protocol.PcepKeepaliveMsg; +import org.onosproject.pcepio.protocol.PcepLabelObject; +import org.onosproject.pcepio.protocol.PcepLabelRangeObject; +import org.onosproject.pcepio.protocol.PcepLabelRangeResvMsg; +import org.onosproject.pcepio.protocol.PcepLabelUpdate; +import org.onosproject.pcepio.protocol.PcepLabelUpdateMsg; +import org.onosproject.pcepio.protocol.PcepLspObject; +import org.onosproject.pcepio.protocol.PcepLspaObject; +import org.onosproject.pcepio.protocol.PcepMessage; +import org.onosproject.pcepio.protocol.PcepMessageReader; +import org.onosproject.pcepio.protocol.PcepMetricObject; +import org.onosproject.pcepio.protocol.PcepMsgPath; +import org.onosproject.pcepio.protocol.PcepOpenMsg; +import org.onosproject.pcepio.protocol.PcepOpenObject; +import org.onosproject.pcepio.protocol.PcepReportMsg; +import org.onosproject.pcepio.protocol.PcepRroObject; +import org.onosproject.pcepio.protocol.PcepSrpObject; +import org.onosproject.pcepio.protocol.PcepStateReport; +import org.onosproject.pcepio.protocol.PcepUpdateMsg; +import org.onosproject.pcepio.protocol.PcepUpdateRequest; +import org.onosproject.pcepio.protocol.PcepVersion; + +/** + * Provides PCEP Factory and returns builder classes for all objects and messages. + */ +public class PcepFactoryVer1 implements PcepFactory { + + public static final PcepFactoryVer1 INSTANCE = new PcepFactoryVer1(); + + @Override + public PcepOpenMsg.Builder buildOpenMsg() { + return new PcepOpenMsgVer1.Builder(); + } + + @Override + public PcepOpenObject.Builder buildOpenObject() { + return new PcepOpenObjectVer1.Builder(); + } + + @Override + public PcepKeepaliveMsg.Builder buildKeepaliveMsg() { + return new PcepKeepaliveMsgVer1.Builder(); + } + + @Override + public PcepCloseMsg.Builder buildCloseMsg() { + return new PcepCloseMsgVer1.Builder(); + } + + @Override + public PcepUpdateMsg.Builder buildUpdateMsg() { + return new PcepUpdateMsgVer1.Builder(); + } + + @Override + public PcepReportMsg.Builder buildReportMsg() { + return new PcepReportMsgVer1.Builder(); + } + + @Override + public PcepInitiateMsg.Builder buildPcepInitiateMsg() { + return new PcepInitiateMsgVer1.Builder(); + } + + @Override + public PcepLspObject.Builder buildLspObject() { + return new PcepLspObjectVer1.Builder(); + } + + @Override + public PcepMessageReader getReader() { + return PcepMessageVer1.READER; + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepSrpObject.Builder buildSrpObject() { + return new PcepSrpObjectVer1.Builder(); + } + + @Override + public PcepEndPointsObject.Builder buildEndPointsObject() { + return new PcepEndPointsObjectVer1.Builder(); + } + + @Override + public PcepEroObject.Builder buildEroObject() { + return new PcepEroObjectVer1.Builder(); + } + + @Override + public PcepRroObject.Builder buildRroObject() { + return new PcepRroObjectVer1.Builder(); + } + + @Override + public PcepLspaObject.Builder buildLspaObject() { + return new PcepLspaObjectVer1.Builder(); + } + + @Override + public PcepIroObject.Builder buildIroObject() { + return new PcepIroObjectVer1.Builder(); + } + + @Override + public PcepMetricObject.Builder buildMetricObject() { + return new PcepMetricObjectVer1.Builder(); + } + + @Override + public PcepBandwidthObject.Builder buildBandwidthObject() { + return new PcepBandwidthObjectVer1.Builder(); + } + + @Override + public PcepMsgPath.Builder buildPcepMsgPath() { + return new PcepMsgPathVer1.Builder(); + } + + @Override + public PcepStateReport.Builder buildPcepStateReport() { + return new PcepStateReportVer1.Builder(); + } + + @Override + public PcepUpdateRequest.Builder buildPcepUpdateRequest() { + return new PcepUpdateRequestVer1.Builder(); + } + + @Override + public PcInitiatedLspRequest.Builder buildPcInitiatedLspRequest() { + return new PcInitiatedLspRequestVer1.Builder(); + } + + @Override + public PcepAttribute.Builder buildPcepAttribute() { + return new PcepAttributeVer1.Builder(); + } + + @Override + public PcepLabelUpdateMsg.Builder buildPcepLabelUpdateMsg() { + return new PcepLabelUpdateMsgVer1.Builder(); + } + + @Override + public PcepLabelUpdate.Builder buildPcepLabelUpdateObject() { + return new PcepLabelUpdateVer1.Builder(); + } + + @Override + public PcepLabelObject.Builder buildLabelObject() { + return new PcepLabelObjectVer1.Builder(); + } + + @Override + public PcepErrorMsg.Builder buildPcepErrorMsg() { + return new PcepErrorMsgVer1.Builder(); + } + + @Override + public PcepErrorObject.Builder buildPcepErrorObject() { + return new PcepErrorObjectVer1.Builder(); + } + + @Override + public PcepFecObjectIPv4Adjacency.Builder buildFecIpv4Adjacency() { + return new PcepFecObjectIPv4AdjacencyVer1.Builder(); + } + + @Override + public PcepErrorInfo.Builder buildPcepErrorInfo() { + return new PcepErrorInfoVer1.Builder(); + } + + @Override + public PcepError.Builder buildPcepError() { + return new PcepErrorVer1.Builder(); + } + + @Override + public PcepLabelRangeObject.Builder buildPcepLabelRangeObject() { + return new PcepLabelRangeObjectVer1.Builder(); + } + + @Override + public PcepLabelRangeResvMsg.Builder buildPcepLabelRangeResvMsg() { + return new PcepLabelRangeResvMsgVer1.Builder(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4AdjacencyVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4AdjacencyVer1.java new file mode 100644 index 00000000..51c672d3 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4AdjacencyVer1.java @@ -0,0 +1,253 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepFecObjectIPv4Adjacency; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP fec Object IPv4 Adjacency object. + */ +public class PcepFecObjectIPv4AdjacencyVer1 implements PcepFecObjectIPv4Adjacency { + + /* + * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5 + * + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Local IPv4 address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Remote IPv4 address | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + FEC Object-Type is 3 IPv4 Adjacency + */ + protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv4AdjacencyVer1.class); + + public static final byte FEC_OBJ_TYPE = 3; + public static final byte FEC_OBJ_CLASS = 36; //to be defined + public static final byte FEC_OBJECT_VERSION = 1; + public static final short FEC_OBJ_MINIMUM_LENGTH = 12; + public static final int MINIMUM_COMMON_HEADER_LENGTH = 4; + + static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE, + PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader fecObjHeader; + private int localIPv4Address; + private int remoteIPv4Address; + + /** + * Constructor to initialize parameters for PCEP fec object . + * + * @param fecObjHeader FEC Object header + * @param localIPv4Address Local IPv4 Address + * @param remoteIPv4Address Remote IPv4 Address + */ + public PcepFecObjectIPv4AdjacencyVer1(PcepObjectHeader fecObjHeader, int localIPv4Address, int remoteIPv4Address) { + this.fecObjHeader = fecObjHeader; + this.localIPv4Address = localIPv4Address; + this.remoteIPv4Address = remoteIPv4Address; + } + + /** + * Sets Object header. + * + * @param obj Pcep fec Object Header + */ + public void setFecIpv4ObjHeader(PcepObjectHeader obj) { + this.fecObjHeader = obj; + } + + @Override + public int getLocalIPv4Address() { + return this.localIPv4Address; + } + + @Override + public void seLocalIPv4Address(int value) { + this.localIPv4Address = value; + } + + @Override + public int getRemoteIPv4Address() { + return this.remoteIPv4Address; + } + + @Override + public void seRemoteIPv4Address(int value) { + this.remoteIPv4Address = value; + } + + /** + * Reads from channel buffer and Returns object of PcepFecObjectIPv4Adjacency. + * + * @param cb of channel buffer. + * @return object of PcepFecObjectIPv4Adjacency + * @throws PcepParseException when fails to read from channel buffer + */ + public static PcepFecObjectIPv4Adjacency read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader fecObjHeader; + int localIPv4Address; + int remoteIPv4Address; + + fecObjHeader = PcepObjectHeader.read(cb); + + //take only FEC IPv4 Adjacency Object buffer. + ChannelBuffer tempCb = cb.readBytes(fecObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH); + localIPv4Address = tempCb.readInt(); + remoteIPv4Address = tempCb.readInt(); + + return new PcepFecObjectIPv4AdjacencyVer1(fecObjHeader, localIPv4Address, remoteIPv4Address); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + int objStartIndex = cb.writerIndex(); + + //Write common header + int objLenIndex = fecObjHeader.write(cb); + cb.writeInt(localIPv4Address); + cb.writeInt(remoteIPv4Address); + + //Now write FEC IPv4 Adjacency Object Length + cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex)); + return cb.writerIndex(); + } + + /** + * Builder class for PCEP fec object IPv4 Adjacency. + */ + public static class Builder implements PcepFecObjectIPv4Adjacency.Builder { + private boolean bIsHeaderSet = false; + private boolean bIsLocalIPv4Addressset = false; + private boolean bIsRemoteIPv4Addressset = false; + + private PcepObjectHeader fecObjHeader; + int localIPv4Address; + int remoteIPv4Address; + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + @Override + public PcepFecObjectIPv4Adjacency build() throws PcepParseException { + PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER; + + if (!this.bIsLocalIPv4Addressset) { + throw new PcepParseException( + "Local IPv4 Address not set while building PcepFecObjectIPv4Adjacency object."); + } + + if (!this.bIsRemoteIPv4Addressset) { + throw new PcepParseException( + " Remote IPv4 Address not set while building PcepFecObjectIPv4Adjacency object."); + } + + if (bIsPFlagSet) { + fecObjHeader.setPFlag(bPFlag); + } + + if (bIsIFlagSet) { + fecObjHeader.setIFlag(bIFlag); + } + return new PcepFecObjectIPv4AdjacencyVer1(fecObjHeader, this.localIPv4Address, this.remoteIPv4Address); + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + + @Override + public PcepObjectHeader getFecIpv4AdjacencyObjHeader() { + return this.fecObjHeader; + } + + @Override + public Builder setFecIpv4AdjacencyObjHeader(PcepObjectHeader obj) { + this.fecObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public int getLocalIPv4Address() { + return this.localIPv4Address; + } + + @Override + public Builder seLocalIPv4Address(int value) { + this.localIPv4Address = value; + this.bIsLocalIPv4Addressset = true; + return this; + } + + @Override + public int getRemoteIPv4Address() { + return this.remoteIPv4Address; + } + + @Override + public Builder seRemoteIPv4Address(int value) { + this.remoteIPv4Address = value; + this.bIsRemoteIPv4Addressset = true; + return this; + } + + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public int getType() { + return FEC_OBJ_TYPE; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("fecObjHeader", fecObjHeader) + .add("localIPv4Address", localIPv4Address) + .add("remoteIPv4Address", remoteIPv4Address).toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4UnnumberedAdjacencyVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4UnnumberedAdjacencyVer1.java new file mode 100644 index 00000000..f2f54cda --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4UnnumberedAdjacencyVer1.java @@ -0,0 +1,334 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepFecObjectIPv4UnnumberedAdjacency; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides Pcep Fec Object IPv4 Unnumbered Adjacency object. + */ +public class PcepFecObjectIPv4UnnumberedAdjacencyVer1 implements PcepFecObjectIPv4UnnumberedAdjacency { + + /* + * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5 + * + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Local Node-ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Local Interface ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Remote Node-ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Remote Interface ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + FEC Object-Type is 5, Unnumbered Adjacency with IPv4 NodeIDs + */ + protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv4UnnumberedAdjacencyVer1.class); + + public static final byte FEC_OBJ_TYPE = 5; + public static final byte FEC_OBJ_CLASS = 63; //to be defined + public static final byte FEC_OBJECT_VERSION = 1; + public static final short FEC_OBJ_MINIMUM_LENGTH = 20; + public static final int MINIMUM_COMMON_HEADER_LENGTH = 4; + + static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE, + PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader fecObjHeader; + private int localNodeID; + private int localInterfaceID; + private int remoteNodeID; + private int remoteInterfaceID; + + /** + * Constructor to initialize parameter for PCEP fec object. + * + * @param fecObjHeader fec object header + * @param localNodeID local node ID + * @param localInterfaceID local interface ID + * @param remoteNodeID remote node ID + * @param remoteInterfaceID remote interface ID + */ + public PcepFecObjectIPv4UnnumberedAdjacencyVer1(PcepObjectHeader fecObjHeader, int localNodeID, + int localInterfaceID, int remoteNodeID, int remoteInterfaceID) { + this.fecObjHeader = fecObjHeader; + this.localNodeID = localNodeID; + this.localInterfaceID = localInterfaceID; + this.remoteNodeID = remoteNodeID; + this.remoteInterfaceID = remoteInterfaceID; + } + + /** + * Sets Object Header. + * + * @param obj object header + */ + public void setFecIpv4UnnumberedAdjacencyObjHeader(PcepObjectHeader obj) { + this.fecObjHeader = obj; + } + + @Override + public void setLocalNodeID(int localNodeID) { + this.localNodeID = localNodeID; + } + + /** + * Returns Object Header. + * + * @return fecObjHeader fec object header + */ + public PcepObjectHeader getFecIpv4UnnumberedAdjacencyObjHeader() { + return this.fecObjHeader; + } + + @Override + public int getLocalNodeID() { + return this.localNodeID; + } + + @Override + public int getLocalInterfaceID() { + return this.localInterfaceID; + } + + @Override + public void setLocalInterfaceID(int localInterfaceID) { + this.localInterfaceID = localInterfaceID; + } + + @Override + public int getRemoteNodeID() { + return this.remoteNodeID; + } + + @Override + public void setRemoteNodeID(int remoteNodeID) { + this.remoteNodeID = remoteNodeID; + } + + @Override + public int getRemoteInterfaceID() { + return this.remoteInterfaceID; + } + + @Override + public void setRemoteInterfaceID(int remoteInterfaceID) { + this.remoteInterfaceID = remoteInterfaceID; + } + + /** + * Reads from channel buffer and returns object of PcepFecObjectIPv4UnnumberedAdjacency. + * + * @param cb of channel buffer + * @return object of PcepFecObjectIPv4UnnumberedAdjacency + * @throws PcepParseException when fails to read from channel buffer + */ + public static PcepFecObjectIPv4UnnumberedAdjacency read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader fecObjHeader; + int localNodeID; + int localInterfaceID; + int remoteNodeID; + int remoteInterfaceID; + + fecObjHeader = PcepObjectHeader.read(cb); + + //take only FEC IPv4 Unnumbered Adjacency Object buffer. + ChannelBuffer tempCb = cb.readBytes(fecObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH); + localNodeID = tempCb.readInt(); + localInterfaceID = tempCb.readInt(); + remoteNodeID = tempCb.readInt(); + remoteInterfaceID = tempCb.readInt(); + + return new PcepFecObjectIPv4UnnumberedAdjacencyVer1(fecObjHeader, localNodeID, localInterfaceID, remoteNodeID, + remoteInterfaceID); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + int objStartIndex = cb.writerIndex(); + + //Write common header + int objLenIndex = fecObjHeader.write(cb); + cb.writeInt(localNodeID); + cb.writeInt(localInterfaceID); + cb.writeInt(remoteNodeID); + cb.writeInt(remoteInterfaceID); + + //Now write FEC IPv4 Unnumbered Adjacency Object Length + cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex)); + + return cb.writerIndex(); + } + + /** + * Builder class for PCEP Fec object IPv4 unnumbered Adjacency. + */ + public static class Builder implements PcepFecObjectIPv4UnnumberedAdjacency.Builder { + private boolean bIsHeaderSet = false; + private boolean bIsLocalNodeIDset = false; + private boolean bIsLocalInterfaceIDset = false; + private boolean bIsRemoteNodeIDset = false; + private boolean bIsRemoteInterfaceIDset = false; + + private PcepObjectHeader fecObjHeader; + private int localNodeID; + private int localInterfaceID; + private int remoteNodeID; + private int remoteInterfaceID; + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + @Override + public PcepFecObjectIPv4UnnumberedAdjacency build() throws PcepParseException { + PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER; + + if (!this.bIsLocalNodeIDset) { + throw new PcepParseException( + " Local Node ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object."); + } + if (!this.bIsLocalInterfaceIDset) { + throw new PcepParseException( + " Local Interface ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object."); + } + if (!this.bIsRemoteNodeIDset) { + throw new PcepParseException( + " Remote Node ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object."); + } + if (!this.bIsRemoteInterfaceIDset) { + throw new PcepParseException( + " Remote Interface ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object."); + } + if (bIsPFlagSet) { + fecObjHeader.setPFlag(bPFlag); + } + if (bIsIFlagSet) { + fecObjHeader.setIFlag(bIFlag); + } + return new PcepFecObjectIPv4UnnumberedAdjacencyVer1(fecObjHeader, this.localNodeID, this.localInterfaceID, + this.remoteNodeID, this.remoteInterfaceID); + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + + @Override + public PcepObjectHeader getFecIpv4UnnumberedAdjacencyObjHeader() { + return this.fecObjHeader; + } + + @Override + public Builder setFecIpv4UnnumberedAdjacencyObjHeader(PcepObjectHeader obj) { + this.fecObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public int getLocalNodeID() { + return this.localNodeID; + } + + @Override + public Builder setLocalNodeID(int value) { + this.localNodeID = value; + this.bIsLocalNodeIDset = true; + return this; + } + + @Override + public int getLocalInterfaceID() { + return this.localInterfaceID; + } + + @Override + public Builder setLocalInterfaceID(int value) { + this.localInterfaceID = value; + this.bIsLocalInterfaceIDset = true; + return this; + } + + @Override + public int getRemoteNodeID() { + return this.remoteNodeID; + } + + @Override + public Builder setRemoteNodeID(int value) { + this.remoteNodeID = value; + this.bIsRemoteNodeIDset = true; + return this; + } + + @Override + public int getRemoteInterfaceID() { + return this.remoteInterfaceID; + } + + @Override + public Builder setRemoteInterfaceID(int value) { + this.remoteInterfaceID = value; + this.bIsRemoteInterfaceIDset = true; + return this; + } + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public int getType() { + return FEC_OBJ_TYPE; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("LocalNodeID: ", localNodeID) + .add("LocalInterfaceID: ", localInterfaceID).add("RemoteNodeID: ", remoteNodeID) + .add("RemoteInterfaceID: ", remoteInterfaceID).toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4Ver1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4Ver1.java new file mode 100644 index 00000000..354547a1 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4Ver1.java @@ -0,0 +1,217 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepFecObjectIPv4; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides Pcep Fec Object IPv4 object. + */ +public class PcepFecObjectIPv4Ver1 implements PcepFecObjectIPv4 { + + /* + * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5 + * + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IPv4 Node ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + FEC Object-Type is 1 IPv4 Node ID + */ + protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv4Ver1.class); + + public static final byte FEC_OBJ_TYPE = 1; + public static final byte FEC_OBJ_CLASS = 63; //to be defined + public static final byte FEC_OBJECT_VERSION = 1; + public static final short FEC_OBJ_MINIMUM_LENGTH = 8; + public static final int MINIMUM_COMMON_HEADER_LENGTH = 4; + + static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE, + PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader fecObjHeader; + private int nodeID; + + /** + * Constructor to initialize parameters for PCEP fec object. + * + * @param fecObjHeader fec object header + * @param nodeID node id + */ + public PcepFecObjectIPv4Ver1(PcepObjectHeader fecObjHeader, int nodeID) { + this.fecObjHeader = fecObjHeader; + this.nodeID = nodeID; + } + + /** + * Sets the Object Header. + * + * @param obj object header + */ + public void setFecIpv4ObjHeader(PcepObjectHeader obj) { + this.fecObjHeader = obj; + } + + @Override + public void setNodeID(int nodeID) { + this.nodeID = nodeID; + } + + /** + * Returns Object Header. + * + * @return fecObjHeader fec object header + */ + public PcepObjectHeader getFecIpv4ObjHeader() { + return this.fecObjHeader; + } + + @Override + public int getNodeID() { + return this.nodeID; + } + + /** + * Reads from channel buffer and returns object of PcepFecObjectIPv4. + * + * @param cb of channel buffer + * @return object of PcepFecObjectIPv4 + * @throws PcepParseException when fails to read from channel buffer + */ + public static PcepFecObjectIPv4 read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader fecObjHeader; + int nodeID; + fecObjHeader = PcepObjectHeader.read(cb); + nodeID = cb.readInt(); + return new PcepFecObjectIPv4Ver1(fecObjHeader, nodeID); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + int objStartIndex = cb.writerIndex(); + + //write common header + int objLenIndex = fecObjHeader.write(cb); + cb.writeInt(nodeID); + + //now write FEC IPv4 Object Length + cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex)); + return cb.writerIndex(); + } + + /** + * Builder class for PCEP fec pobject IPv4. + */ + public static class Builder implements PcepFecObjectIPv4.Builder { + private boolean bIsHeaderSet = false; + private boolean bIsNodeIdset = false; + + private PcepObjectHeader fecObjHeader; + private int nodeID; + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + @Override + public PcepFecObjectIPv4 build() throws PcepParseException { + PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER; + + if (!this.bIsNodeIdset) { + throw new PcepParseException("NodeID not set while building PcepFecObjectIPv4 object."); + } + if (bIsPFlagSet) { + fecObjHeader.setPFlag(bPFlag); + } + if (bIsIFlagSet) { + fecObjHeader.setIFlag(bIFlag); + } + return new PcepFecObjectIPv4Ver1(fecObjHeader, this.nodeID); + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + + @Override + public PcepObjectHeader getFecIpv4ObjHeader() { + return this.fecObjHeader; + } + + @Override + public Builder setFecIpv4ObjHeader(PcepObjectHeader obj) { + this.fecObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public int getNodeID() { + return this.nodeID; + } + + @Override + public Builder setNodeID(int value) { + this.nodeID = value; + this.bIsNodeIdset = true; + return this; + } + + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public int getType() { + return FEC_OBJ_TYPE; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("fecObjHeader", fecObjHeader) + .add("nodeID: ", nodeID) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6AdjacencyVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6AdjacencyVer1.java new file mode 100644 index 00000000..f8ea7869 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6AdjacencyVer1.java @@ -0,0 +1,249 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepFecObjectIPv6Adjacency; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides Pcep Fec Object IPv6 Adjacency object. + */ +public class PcepFecObjectIPv6AdjacencyVer1 implements PcepFecObjectIPv6Adjacency { + + /* + * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5 + * + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // Local IPv6 address (16 bytes) // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // Remote IPv6 address (16 bytes) // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + FEC Object-Type is 4 IPv6 Adjacency + */ + protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv6AdjacencyVer1.class); + + public static final byte FEC_OBJ_TYPE = 4; + public static final byte FEC_OBJ_CLASS = 63; //to be defined + public static final byte FEC_OBJECT_VERSION = 1; + public static final short FEC_OBJ_MINIMUM_LENGTH = 36; + public static final int MINIMUM_COMMON_HEADER_LENGTH = 4; + public static final int IPV6_ADDRESS_LENGTH = 16; + + static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE, + PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader fecObjHeader; + private byte[] localIPv6Address = new byte[IPV6_ADDRESS_LENGTH]; + private byte[] remoteIPv6Address = new byte[IPV6_ADDRESS_LENGTH]; + + /** + * Constructor to initialize parameters for PCEP fec object. + * + * @param fecObjHeader fec object header + * @param localIPv6Address local IPv6 address + * @param remoteIPv6Address remote IPv6 address + */ + public PcepFecObjectIPv6AdjacencyVer1(PcepObjectHeader fecObjHeader, byte[] localIPv6Address, + byte[] remoteIPv6Address) { + this.fecObjHeader = fecObjHeader; + this.localIPv6Address = localIPv6Address; + this.remoteIPv6Address = remoteIPv6Address; + } + + /** + * Sets Object Header. + * + * @param obj object header + */ + public void setFecIpv4ObjHeader(PcepObjectHeader obj) { + this.fecObjHeader = obj; + } + + @Override + public byte[] getLocalIPv6Address() { + return this.localIPv6Address; + } + + @Override + public void seLocalIPv6Address(byte[] value) { + this.localIPv6Address = value; + } + + @Override + public byte[] getRemoteIPv6Address() { + return this.remoteIPv6Address; + } + + @Override + public void seRemoteIPv6Address(byte[] value) { + this.remoteIPv6Address = value; + } + + /** + * Reads channel buffer and Returns object of PcepFecObjectIPv6Adjacency. + * + * @param cb of channel buffer + * @return object of PcepFecObjectIPv6Adjacency + * @throws PcepParseException when fails tp read from channel buffer + */ + public static PcepFecObjectIPv6Adjacency read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader fecObjHeader; + byte[] localIPv6Address = new byte[IPV6_ADDRESS_LENGTH]; + byte[] remoteIPv6Address = new byte[IPV6_ADDRESS_LENGTH]; + fecObjHeader = PcepObjectHeader.read(cb); + cb.readBytes(localIPv6Address, 0, IPV6_ADDRESS_LENGTH); + cb.readBytes(remoteIPv6Address, 0, IPV6_ADDRESS_LENGTH); + return new PcepFecObjectIPv6AdjacencyVer1(fecObjHeader, localIPv6Address, remoteIPv6Address); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + int objStartIndex = cb.writerIndex(); + + //write common header + int objLenIndex = fecObjHeader.write(cb); + cb.writeBytes(localIPv6Address); + cb.writeBytes(remoteIPv6Address); + //now write FEC IPv6 Adjacency Object Length + cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex)); + return cb.writerIndex(); + } + + /** + * Builder class for PCEP fec object IPv6 Adjacency. + */ + public static class Builder implements PcepFecObjectIPv6Adjacency.Builder { + private boolean bIsHeaderSet = false; + private boolean bIsLocalIPv6Addressset = false; + private boolean bIsRemoteIPv6Addressset = false; + + private PcepObjectHeader fecObjHeader; + byte[] localIPv6Address = new byte[IPV6_ADDRESS_LENGTH]; + byte[] remoteIPv6Address = new byte[IPV6_ADDRESS_LENGTH]; + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + @Override + public PcepFecObjectIPv6Adjacency build() throws PcepParseException { + PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER; + + if (!this.bIsLocalIPv6Addressset) { + throw new PcepParseException( + "Local IPv6 Address not set while building PcepFecObjectIPv6Adjacency object."); + } + if (!this.bIsRemoteIPv6Addressset) { + throw new PcepParseException( + "Remote IPv6 Address not set while building PcepFecObjectIPv6Adjacency object."); + } + if (bIsPFlagSet) { + fecObjHeader.setPFlag(bPFlag); + } + if (bIsIFlagSet) { + fecObjHeader.setIFlag(bIFlag); + } + return new PcepFecObjectIPv6AdjacencyVer1(fecObjHeader, this.localIPv6Address, this.remoteIPv6Address); + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + + @Override + public PcepObjectHeader getFecIpv6AdjacencyObjHeader() { + return this.fecObjHeader; + } + + @Override + public Builder setFecIpv6AdjacencyObjHeader(PcepObjectHeader obj) { + this.fecObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public byte[] getLocalIPv6Address() { + return this.localIPv6Address; + } + + @Override + public Builder setLocalIPv6Address(byte[] value) { + this.localIPv6Address = value; + this.bIsLocalIPv6Addressset = true; + return this; + } + + @Override + public byte[] getRemoteIPv6Address() { + return this.remoteIPv6Address; + } + + @Override + public Builder setRemoteIPv6Address(byte[] value) { + this.remoteIPv6Address = value; + this.bIsRemoteIPv6Addressset = true; + return this; + } + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public int getType() { + return FEC_OBJ_TYPE; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("localIPv6Address", localIPv6Address) + .add("remoteIPv6Address: ", remoteIPv6Address) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6Ver1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6Ver1.java new file mode 100644 index 00000000..240a96f7 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6Ver1.java @@ -0,0 +1,220 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepFecObjectIPv6; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides Pcep Fec Object IPv6 object. + */ +public class PcepFecObjectIPv6Ver1 implements PcepFecObjectIPv6 { + + /* + * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5 + * + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // IPv6 Node ID (16 bytes) // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + FEC Object-Type is 2 IPv6 Node ID + */ + protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv6Ver1.class); + + public static final byte FEC_OBJ_TYPE = 2; + public static final byte FEC_OBJ_CLASS = 63; //to be defined + public static final byte FEC_OBJECT_VERSION = 1; + public static final short FEC_OBJ_MINIMUM_LENGTH = 20; + public static final int MINIMUM_COMMON_HEADER_LENGTH = 4; + public static final int IPV6_ADDRESS_LENGTH = 16; + + static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE, + PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader fecObjHeader; + private byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH]; + + /** + * Constructor to initialize parameters for PCEP fec object. + * + * @param fecObjHeader Fec object header + * @param nodeID node ID + */ + public PcepFecObjectIPv6Ver1(PcepObjectHeader fecObjHeader, byte[] nodeID) { + this.fecObjHeader = fecObjHeader; + this.nodeID = nodeID; + } + + /** + * Sets the Object header. + * + * @param obj object header + */ + public void setFecIpv6ObjHeader(PcepObjectHeader obj) { + this.fecObjHeader = obj; + } + + @Override + public void setNodeID(byte[] nodeID) { + this.nodeID = nodeID; + } + + /** + * Returns object header. + * + * @return fec Object Header + */ + public PcepObjectHeader getFecIpv6ObjHeader() { + return this.fecObjHeader; + } + + @Override + public byte[] getNodeID() { + return this.nodeID; + } + + /** + * reads the channel buffer and returns object of PcepFecObjectIPv6. + * + * @param cb of channel buffer. + * @return object of PcepFecObjectIPv6 + * @throws PcepParseException when fails to read from channel buffer + */ + public static PcepFecObjectIPv6 read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader fecObjHeader; + byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH]; + fecObjHeader = PcepObjectHeader.read(cb); + cb.readBytes(nodeID, 0, IPV6_ADDRESS_LENGTH); + return new PcepFecObjectIPv6Ver1(fecObjHeader, nodeID); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + int objStartIndex = cb.writerIndex(); + + //write common header + int objLenIndex = fecObjHeader.write(cb); + cb.writeBytes(nodeID); + + //now write FEC IPv4 Object Length + cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex)); + return cb.writerIndex(); + } + + /** + * Builder class for PCEP fec object IPv6. + */ + public static class Builder implements PcepFecObjectIPv6.Builder { + private boolean bIsHeaderSet = false; + private boolean bIsNodeIdset = false; + + private PcepObjectHeader fecObjHeader; + private byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH]; + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + @Override + public PcepFecObjectIPv6 build() throws PcepParseException { + PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER; + + if (!this.bIsNodeIdset) { + throw new PcepParseException(" NodeID not set while building PcepFecObjectIPv6 object."); + } + if (bIsPFlagSet) { + fecObjHeader.setPFlag(bPFlag); + } + if (bIsIFlagSet) { + fecObjHeader.setIFlag(bIFlag); + } + return new PcepFecObjectIPv6Ver1(fecObjHeader, this.nodeID); + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + + @Override + public PcepObjectHeader getFecIpv6ObjHeader() { + return this.fecObjHeader; + } + + @Override + public Builder setFecIpv6ObjHeader(PcepObjectHeader obj) { + this.fecObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public byte[] getNodeID() { + return this.nodeID; + } + + @Override + public Builder setNodeID(byte[] value) { + this.nodeID = value; + this.bIsNodeIdset = true; + return this; + } + + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public int getType() { + return FEC_OBJ_TYPE; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("fecObjHeader", fecObjHeader) + .add("NodeID: ", nodeID) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInitiateMsgVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInitiateMsgVer1.java new file mode 100644 index 00000000..60d14b07 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInitiateMsgVer1.java @@ -0,0 +1,332 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcInitiatedLspRequest; +import org.onosproject.pcepio.protocol.PcepAttribute; +import org.onosproject.pcepio.protocol.PcepEndPointsObject; +import org.onosproject.pcepio.protocol.PcepEroObject; +import org.onosproject.pcepio.protocol.PcepInitiateMsg; +import org.onosproject.pcepio.protocol.PcepLspObject; +import org.onosproject.pcepio.protocol.PcepMessageReader; +import org.onosproject.pcepio.protocol.PcepMessageWriter; +import org.onosproject.pcepio.protocol.PcepSrpObject; +import org.onosproject.pcepio.protocol.PcepType; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP initiate message. + */ +class PcepInitiateMsgVer1 implements PcepInitiateMsg { + + protected static final Logger log = LoggerFactory.getLogger(PcepInitiateMsgVer1.class); + + // Ref : PCE initiated tunnel setup draft-ietf-pce-pce-initiated-lsp-03, section 5.1 + /* ::= + * + * Where: + * ::= [] + * ::= (|) + * ::= + * + * + * + * [] + * ::= + * + */ + + static final byte PACKET_VERSION = 1; + /* considering LspDelete Request PcInitiate msg will contain + * common header + * srp object + * lsp object + * so min length for this can be + * PACKET_MINIMUM_LENGTH = CommonHeaderLen(4)+SrpObjectMinLen(12)+LspObjectMinLen(8) + */ + public static final short PACKET_MINIMUM_LENGTH = 24; + public static final short MINIMUM_COMMON_HEADER_LENGTH = 4; + public static final PcepType MSG_TYPE = PcepType.INITIATE; + private LinkedList llPcInitiatedLspRequestList; + public static final PcepInitiateMsgVer1.Reader READER = new Reader(); + + /** + * Reader class for reading of Pcep initiate message from channel buffer. + */ + static class Reader implements PcepMessageReader { + + LinkedList llPcInitiatedLspRequestList; + + @Override + public PcepInitiateMsg readFrom(ChannelBuffer cb) throws PcepParseException { + + if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) { + return null; + } + + llPcInitiatedLspRequestList = new LinkedList<>(); + + byte version = cb.readByte(); + version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG); + if (version != PACKET_VERSION) { + throw new PcepParseException("Wrong version. Expected=PcepVersion.PCEP_1(1), received=" + version); + } + byte type = cb.readByte(); + if (type != MSG_TYPE.getType()) { + throw new PcepParseException("Wrong type. Expected=PcepType.INITIATE(12), recived=" + type); + } + short length = cb.readShort(); + + if (length < PACKET_MINIMUM_LENGTH) { + throw new PcepParseException("Wrong length. Initiate message length expected to be >= " + + PACKET_MINIMUM_LENGTH + ", but received=" + length); + } + + log.debug("reading PcInitiate message of length " + length); + + // parse Start initiate/deletion list + if (!parsePcInitiatedLspRequestList(cb)) { + throw new PcepParseException("Parsing PCE-initiated-lsp-Request-list failed"); + } + + return new PcepInitiateMsgVer1(llPcInitiatedLspRequestList); + } + + /** + * To parse PcInitiatedLspRequestList from PcInitiate Message. + * + * @param cb of type channel buffer + * @return true if parsing PcInitiatedLspRequestList is success, false otherwise + * @throws PcepParseException while parsing from channel buffer + */ + public boolean parsePcInitiatedLspRequestList(ChannelBuffer cb) throws PcepParseException { + + boolean isDelLspRequest = false; + + if (cb == null) { + throw new PcepParseException("Channel buffer is empty"); + } + + while (0 < cb.readableBytes()) { + PcInitiatedLspRequest pceInitLspReq = new PcInitiatedLspRequestVer1(); + + //store SRP object + PcepSrpObject srpObj; + srpObj = PcepSrpObjectVer1.read(cb); + pceInitLspReq.setSrpObject(srpObj); + isDelLspRequest = srpObj.getRFlag(); + + //store LSP object + PcepLspObject lspObj; + lspObj = PcepLspObjectVer1.read(cb); + pceInitLspReq.setLspObject(lspObj); + + /* if R bit will be set then pcInitiate msg will contain only LSp and SRP objects + * so if R bit is not set then we should read for Ero and EndPoint objects also. + */ + if (!isDelLspRequest) { + + //store EndPoint object + PcepEndPointsObject endPointObj; + endPointObj = PcepEndPointsObjectVer1.read(cb); + pceInitLspReq.setEndPointsObject(endPointObj); + + //store ERO object + PcepEroObject eroObj; + eroObj = PcepEroObjectVer1.read(cb); + pceInitLspReq.setEroObject(eroObj); + + if (cb.readableBytes() > MINIMUM_COMMON_HEADER_LENGTH) { + pceInitLspReq.setPcepAttribute(PcepAttributeVer1.read(cb)); + } + } + llPcInitiatedLspRequestList.add(pceInitLspReq); + } + return true; + } + } + + /** + * Constructor to initialize PcInitiatedLspRequest. + * + * @param llPcInitiatedLspRequestList list of PcInitiatedLspRequest + */ + PcepInitiateMsgVer1(LinkedList llPcInitiatedLspRequestList) { + + if (llPcInitiatedLspRequestList == null) { + throw new NullPointerException("PcInitiatedLspRequestList cannot be null."); + } + this.llPcInitiatedLspRequestList = llPcInitiatedLspRequestList; + } + + /** + * Builder class for PCEP initiate message. + */ + static class Builder implements PcepInitiateMsg.Builder { + + // Pcep initiate message fields + LinkedList llPcInitiatedLspRequestList; + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepType getType() { + return PcepType.INITIATE; + } + + @Override + public PcepInitiateMsg build() { + return new PcepInitiateMsgVer1(this.llPcInitiatedLspRequestList); + } + + @Override + public LinkedList getPcInitiatedLspRequestList() { + return this.llPcInitiatedLspRequestList; + } + + @Override + public Builder setPcInitiatedLspRequestList(LinkedList ll) { + this.llPcInitiatedLspRequestList = ll; + return this; + } + } + + @Override + public void writeTo(ChannelBuffer cb) throws PcepParseException { + WRITER.write(cb, this); + } + + static final Writer WRITER = new Writer(); + + /** + * Writer class for writing pcep initiate message to channel buffer. + */ + static class Writer implements PcepMessageWriter { + + @Override + public void write(ChannelBuffer cb, PcepInitiateMsgVer1 message) throws PcepParseException { + + boolean isDelLspRequest = false; + int startIndex = cb.writerIndex(); + // first 3 bits set to version + cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG)); + // message type 0xC + cb.writeByte(MSG_TYPE.getType()); + // length is length of variable message, will be updated at the end + // Store the position of message + // length in buffer + int msgLenIndex = cb.writerIndex(); + cb.writeShort(0); + + ListIterator listIterator = message.llPcInitiatedLspRequestList.listIterator(); + + while (listIterator.hasNext()) { + + PcInitiatedLspRequest listReq = listIterator.next(); + + //Srp Object is mandatory + PcepSrpObject srpObj = listReq.getSrpObject(); + if (srpObj != null) { + isDelLspRequest = srpObj.getRFlag(); + srpObj.write(cb); + } else { + throw new PcepParseException("SRP Object is mandatory for PcInitiate message."); + } + + //LSP Object is mandatory + PcepLspObject lspObj = listReq.getLspObject(); + if (lspObj != null) { + lspObj.write(cb); + } else { + throw new PcepParseException("LSP Object is mandatory for PcInitiate message."); + } + + /* if R bit will be set then pcInitiate msg will contain only LSp and SRP objects + * so if R bit is not set then we should read for Ero and EndPoint objects also. + */ + + if (!isDelLspRequest) { + + //EndPoints object is mandatory + PcepEndPointsObject endPointObj = listReq.getEndPointsObject(); + if (endPointObj != null) { + endPointObj.write(cb); + } else { + throw new PcepParseException("End points Object is mandatory for PcInitiate message."); + } + + //Ero object is mandatory + PcepEroObject eroObj = listReq.getEroObject(); + if (eroObj != null) { + eroObj.write(cb); + } else { + throw new PcepParseException("ERO Object is mandatory for PcInitiate message."); + } + + //PcepAttribute is optional + PcepAttribute pcepAttribute = listReq.getPcepAttribute(); + if (pcepAttribute != null) { + pcepAttribute.write(cb); + } + } + } + + // PCInitiate message length field + int length = cb.writerIndex() - startIndex; + cb.setShort(msgLenIndex, (short) length); + } + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepType getType() { + return MSG_TYPE; + } + + @Override + public LinkedList getPcInitiatedLspRequestList() { + return this.llPcInitiatedLspRequestList; + } + + @Override + public void setPcInitiatedLspRequestList(LinkedList ll) { + this.llPcInitiatedLspRequestList = ll; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("PcInitiaitedLspRequestList", llPcInitiatedLspRequestList) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java new file mode 100644 index 00000000..5130d9e9 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java @@ -0,0 +1,263 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pcepio.protocol.ver1; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepInterLayerObject; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP inter layer object. + */ +public class PcepInterLayerObjectVer1 implements PcepInterLayerObject { + + /* + * 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved |N|I| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + protected static final Logger log = LoggerFactory.getLogger(PcepInterLayerObjectVer1.class); + + public static final byte INTER_LAYER_OBJ_TYPE = 1; + public static final byte INTER_LAYER_OBJ_CLASS = 18; + public static final byte INTER_LAYER_OBJECT_VERSION = 1; + public static final short INTER_LAYER_OBJ_MINIMUM_LENGTH = 8; + public static final boolean DEFAULT_IFLAG = false; + public static final boolean DEFAULT_NFLAG = false; + public static final int OBJECT_HEADER_LENGTH = 4; + public static final int NFLAG_SHIFT_VALUE = 0x02; + public static final int IFLAG_SHIFT_VALUE = 0x01; + + static final PcepObjectHeader DEFAULT_INTER_LAYER_OBJECT_HEADER = new PcepObjectHeader(INTER_LAYER_OBJ_CLASS, + INTER_LAYER_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, + INTER_LAYER_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader interLayerObjHeader; + private boolean bNFlag; + private boolean bIFlag; + + /** + * Constructor to initialize all parameters for Pcep Inter Layer Object. + * + * @param interLayerObjHeader inter layer object header + * @param bNFlag N flag + * @param bIFlag I flag + */ + public PcepInterLayerObjectVer1(PcepObjectHeader interLayerObjHeader, boolean bNFlag, boolean bIFlag) { + + this.interLayerObjHeader = interLayerObjHeader; + this.bNFlag = bNFlag; + this.bIFlag = bIFlag; + } + + /** + * Sets Object Header. + * + * @param obj object header + */ + public void setInterLayerObjHeader(PcepObjectHeader obj) { + this.interLayerObjHeader = obj; + } + + @Override + public void setbNFlag(boolean bNFlag) { + this.bNFlag = bNFlag; + } + + @Override + public void setbIFlag(boolean bIFlag) { + this.bIFlag = bIFlag; + } + + /** + * Returns object header. + * + * @return inter Layer Object Header + */ + public PcepObjectHeader getInterLayerObjHeader() { + return this.interLayerObjHeader; + } + + @Override + public boolean getbNFlag() { + return this.bNFlag; + } + + @Override + public boolean getbIFlag() { + return this.bIFlag; + } + + /** + * Reads channel buffer and returns object of PcepInterLayerObject. + * + * @param cb of type channel buffer + * @return object of PcepInterLayerObject + * @throws PcepParseException when fails to read from channel buffer + */ + public static PcepInterLayerObject read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader interLayerObjHeader; + boolean bNFlag; + boolean bIFlag; + + interLayerObjHeader = PcepObjectHeader.read(cb); + + //take only InterLayerObject buffer. + ChannelBuffer tempCb = cb.readBytes(interLayerObjHeader.getObjLen() - OBJECT_HEADER_LENGTH); + + int iTemp = tempCb.readInt(); + bIFlag = ((iTemp & (byte) IFLAG_SHIFT_VALUE) == IFLAG_SHIFT_VALUE); + bNFlag = ((iTemp & (byte) NFLAG_SHIFT_VALUE) == NFLAG_SHIFT_VALUE); + + return new PcepInterLayerObjectVer1(interLayerObjHeader, bNFlag, bIFlag); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + //write Object header + int objStartIndex = cb.writerIndex(); + + int objLenIndex = interLayerObjHeader.write(cb); + + if (objLenIndex <= 0) { + throw new PcepParseException(" ObjectLength Index is " + objLenIndex); + } + + int iTemp = 0; + + if (bIFlag) { + iTemp = iTemp | (byte) IFLAG_SHIFT_VALUE; + } + if (bNFlag) { + iTemp = iTemp | (byte) NFLAG_SHIFT_VALUE; + } + + cb.writeInt(iTemp); + + //Update object length now + int length = cb.writerIndex() - objStartIndex; + //will be helpful during print(). + interLayerObjHeader.setObjLen((short) length); + cb.setShort(objLenIndex, (short) length); + + objLenIndex = cb.writerIndex(); + return objLenIndex; + } + + /** + * Builder class for PCEP inter layer object. + */ + public static class Builder implements PcepInterLayerObject.Builder { + + private boolean bIsHeaderSet = false; + private boolean bIsNFlagset = false; + private boolean bIsIFlagset = false; + + private PcepObjectHeader interLayerObjHeader; + private boolean bNFlag; + private boolean bIFlag; + + private boolean bIsPFlagSet = false; + private boolean bPFalg; + + private boolean bIsIFlagSet = false; + private boolean iFlag; + + @Override + public PcepInterLayerObject build() { + PcepObjectHeader interLayerObjHeader = this.bIsHeaderSet ? this.interLayerObjHeader + : DEFAULT_INTER_LAYER_OBJECT_HEADER; + + boolean bNFlag = this.bIsNFlagset ? this.bNFlag : DEFAULT_NFLAG; + boolean bIFlag = this.bIsIFlagset ? this.bIFlag : DEFAULT_IFLAG; + + if (bIsPFlagSet) { + interLayerObjHeader.setPFlag(bPFalg); + } + + if (bIsIFlagSet) { + interLayerObjHeader.setIFlag(iFlag); + } + return new PcepInterLayerObjectVer1(interLayerObjHeader, bNFlag, bIFlag); + } + + @Override + public PcepObjectHeader getInterLayerObjHeader() { + return this.interLayerObjHeader; + } + + @Override + public Builder setInterLayerObjHeader(PcepObjectHeader obj) { + this.interLayerObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public boolean getbNFlag() { + return this.bNFlag; + } + + @Override + public Builder setbNFlag(boolean value) { + this.bNFlag = value; + this.bIsNFlagset = true; + return this; + } + + @Override + public boolean getbIFlag() { + return this.bIFlag; + } + + @Override + public Builder setbIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagset = true; + return this; + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFalg = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.iFlag = value; + this.bIsIFlagSet = true; + return this; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("IFlag", bIFlag) + .add("NFlag", bNFlag).toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepIroObjectVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepIroObjectVer1.java new file mode 100644 index 00000000..2e01bdaa --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepIroObjectVer1.java @@ -0,0 +1,299 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepIroObject; +import org.onosproject.pcepio.types.IPv4SubObject; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP iro object. + */ +public class PcepIroObjectVer1 implements PcepIroObject { + + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // (Sub-objects) // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + The IRO Object format + + Each IPV4 suboject + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |L| Type | Length | IPv4 address (4 bytes) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | IPv4 address (continued) | Prefix Length | Resvd | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + protected static final Logger log = LoggerFactory.getLogger(PcepIroObjectVer1.class); + + public static final byte IRO_OBJ_TYPE = 1; + public static final byte IRO_OBJ_CLASS = 10; + public static final byte IRO_OBJECT_VERSION = 1; + public static final short IRO_OBJ_MINIMUM_LENGTH = 12; + public static final int OBJECT_HEADER_LENGTH = 4; + public static final int YTYPE_SHIFT_VALUE = 0x7F; + + public static final PcepObjectHeader DEFAULT_IRO_OBJECT_HEADER = new PcepObjectHeader(IRO_OBJ_CLASS, IRO_OBJ_TYPE, + PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, IRO_OBJ_MINIMUM_LENGTH); + + private short iroObjType = 0; + private byte yLength; + private byte yPrefixLength; + private byte yResvd; + private PcepObjectHeader iroObjHeader; + private LinkedList llSubObjects = new LinkedList<>(); + + /** + * Default constructor. + */ + public PcepIroObjectVer1() { + this.iroObjHeader = null; + this.iroObjType = 0; + this.yLength = 0; + } + + /** + * Constructor to initialize member variables. + * + * @param iroObjHeader IRO object header + * @param llSubObjects list of sub-objects + */ + public PcepIroObjectVer1(PcepObjectHeader iroObjHeader, LinkedList llSubObjects) { + this.iroObjHeader = iroObjHeader; + this.llSubObjects = llSubObjects; + } + + /** + * Returns object header. + * + * @return iroObjHeader IRO object header + */ + public PcepObjectHeader getIroObjHeader() { + return this.iroObjHeader; + } + + /** + * Sets IRO Object Header. + * + * @param obj IRO object header + */ + public void setIroObjHeader(PcepObjectHeader obj) { + this.iroObjHeader = obj; + } + + @Override + public LinkedList getSubObjects() { + return this.llSubObjects; + } + + @Override + public void setSubObjects(LinkedList llSubObjects) { + this.llSubObjects = llSubObjects; + } + + /** + * Reads from channel buffer and return object of PcepIroObject. + * + * @param cb of type channel buffer + * @return object of PcepIroObject + * @throws PcepParseException while parsing from channel buffer + */ + public static PcepIroObject read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader iroObjHeader; + LinkedList llSubObjects; + + iroObjHeader = PcepObjectHeader.read(cb); + + //take only IroObject buffer. + ChannelBuffer tempCb = cb.readBytes(iroObjHeader.getObjLen() - OBJECT_HEADER_LENGTH); + llSubObjects = parseSubObjects(tempCb); + return new PcepIroObjectVer1(iroObjHeader, llSubObjects); + } + + /** + * Returns linked list of sub objects. + * + * @param cb of type channel buffer + * @return linked list of sub objects + * @throws PcepParseException while parsing subobjects from channel buffer + */ + protected static LinkedList parseSubObjects(ChannelBuffer cb) throws PcepParseException { + + LinkedList llSubObjects = new LinkedList<>(); + + while (0 < cb.readableBytes()) { + + //check the Type of the Subobjects. + byte yType = cb.readByte(); + yType = (byte) (yType & (YTYPE_SHIFT_VALUE)); + byte hLength = cb.readByte(); + + PcepValueType subObj; + switch (yType) { + + case IPv4SubObject.TYPE: + subObj = IPv4SubObject.read(cb); + break; + + default: + throw new PcepParseException("Invalid sub object. Type: " + (int) yType); + } + + // Check for the padding + int pad = hLength % 4; + if (0 < pad) { + pad = 4 - pad; + if (pad <= cb.readableBytes()) { + cb.skipBytes(pad); + } + } + llSubObjects.add(subObj); + } + return llSubObjects; + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + //write Object header + int objStartIndex = cb.writerIndex(); + + int objLenIndex = iroObjHeader.write(cb); + + if (objLenIndex <= 0) { + throw new PcepParseException(" ObjectLength is " + objLenIndex); + } + + ListIterator listIterator = llSubObjects.listIterator(); + while (listIterator.hasNext()) { + listIterator.next().write(cb); + } + + //Update object length now + int length = cb.writerIndex() - objStartIndex; + //will be helpful during print(). + iroObjHeader.setObjLen((short) length); + // As per RFC the length of object should be + // multiples of 4 + int pad = length % 4; + if (pad != 0) { + pad = 4 - pad; + for (int i = 0; i < pad; i++) { + cb.writeByte((byte) 0); + } + length = length + pad; + } + cb.setShort(objLenIndex, (short) length); + objLenIndex = cb.writerIndex(); + return objLenIndex; + } + + /** + * Builder class for PCEP iro object. + */ + public static class Builder implements PcepIroObject.Builder { + + private boolean bIsHeaderSet = false; + + private PcepObjectHeader iroObjHeader; + LinkedList llSubObjects = new LinkedList<>(); + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + @Override + public PcepIroObject build() { + + PcepObjectHeader iroObjHeader = this.bIsHeaderSet ? this.iroObjHeader : DEFAULT_IRO_OBJECT_HEADER; + + if (bIsPFlagSet) { + iroObjHeader.setPFlag(bPFlag); + } + + if (bIsIFlagSet) { + iroObjHeader.setIFlag(bIFlag); + } + + return new PcepIroObjectVer1(iroObjHeader, this.llSubObjects); + } + + @Override + public PcepObjectHeader getIroObjHeader() { + return this.iroObjHeader; + } + + @Override + public Builder setIroObjHeader(PcepObjectHeader obj) { + this.iroObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public LinkedList getSubObjects() { + return this.llSubObjects; + } + + @Override + public Builder setSubObjects(LinkedList llSubObjects) { + this.llSubObjects = llSubObjects; + return this; + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("IroObjectHeader", iroObjHeader) + .add("SubObjects", llSubObjects).toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepKeepaliveMsgVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepKeepaliveMsgVer1.java new file mode 100644 index 00000000..8b6e9382 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepKeepaliveMsgVer1.java @@ -0,0 +1,154 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepKeepaliveMsg; +import org.onosproject.pcepio.protocol.PcepMessageReader; +import org.onosproject.pcepio.protocol.PcepMessageWriter; +import org.onosproject.pcepio.protocol.PcepType; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP keep alive message. + */ +class PcepKeepaliveMsgVer1 implements PcepKeepaliveMsg { + + /* + ::= + + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Ver | Flags | Message-Type | Message-Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + protected static final Logger log = LoggerFactory.getLogger(PcepKeepaliveMsgVer1.class); + // Pcep version: 1 + public static final byte PACKET_VERSION = 1; + public static final int PACKET_MINIMUM_LENGTH = 4; + public static final PcepType MSG_TYPE = PcepType.KEEP_ALIVE; + + public static final PcepKeepaliveMsgVer1.Reader READER = new Reader(); + + /** + * Reader class for reading PCEP keepalive message from channel buffer. + */ + static class Reader implements PcepMessageReader { + + @Override + public PcepKeepaliveMsg readFrom(ChannelBuffer cb) throws PcepParseException { + + if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) { + throw new PcepParseException("Packet size is less than the minimum required length."); + } + // fixed value property version == 1 + byte version = cb.readByte(); + version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG); + if (version != PACKET_VERSION) { + throw new PcepParseException("Wrong version: Expected=PcepVersion.KEEP_ALIVE_1(2), got=" + version); + } + // fixed value property type == 2 + byte type = cb.readByte(); + if (type != MSG_TYPE.getType()) { + throw new PcepParseException("Wrong type: Expected=PcepType.KEEP_ALIVE_1(2), got=" + type); + } + short length = cb.readShort(); + if (length < PACKET_MINIMUM_LENGTH) { + throw new PcepParseException("Wrong length: Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + + length); + } + return new PcepKeepaliveMsgVer1(); + } + } + + /** + * Default constructor. + */ + PcepKeepaliveMsgVer1() { + } + + /** + * Builder class for PCEP keepalive message. + */ + static class Builder implements PcepKeepaliveMsg.Builder { + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepType getType() { + return PcepType.KEEP_ALIVE; + } + + @Override + public PcepKeepaliveMsg build() { + return new PcepKeepaliveMsgVer1(); + } + } + + @Override + public void writeTo(ChannelBuffer cb) { + WRITER.write(cb, this); + } + + static final Writer WRITER = new Writer(); + + /** + * Writer class for writing the PCEP keepalive message to channel buffer. + */ + static class Writer implements PcepMessageWriter { + + @Override + public void write(ChannelBuffer cb, PcepKeepaliveMsgVer1 message) { + int startIndex = cb.writerIndex(); + // first 3 bits set to version + cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG)); + // message type + cb.writeByte(MSG_TYPE.getType()); + // length is length of variable message, will be updated at the end + // Store the position of message + // length in buffer + int msgLenIndex = cb.writerIndex(); + cb.writeShort((short) 0); + // update message length field + int length = cb.writerIndex() - startIndex; + cb.setShort(msgLenIndex, (short) length); + } + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepType getType() { + return MSG_TYPE; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelObjectVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelObjectVer1.java new file mode 100644 index 00000000..a4ac87c3 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelObjectVer1.java @@ -0,0 +1,370 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepLabelObject; +import org.onosproject.pcepio.types.NexthopIPv4addressTlv; +import org.onosproject.pcepio.types.NexthopIPv6addressTlv; +import org.onosproject.pcepio.types.NexthopUnnumberedIPv4IDTlv; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP label object. + */ +public class PcepLabelObjectVer1 implements PcepLabelObject { + + /* + * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.4. + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Reserved | Flags |O| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Label | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // Optional TLV // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + The LABEL Object format + */ + protected static final Logger log = LoggerFactory.getLogger(PcepLspObjectVer1.class); + + public static final byte LABEL_OBJ_TYPE = 1; + public static final byte LABEL_OBJ_CLASS = 35; //TBD : to be defined + public static final byte LABEL_OBJECT_VERSION = 1; + public static final byte OBJECT_HEADER_LENGTH = 4; + public static final boolean DEFAULT_OFLAG = false; + + // LSP_OBJ_MINIMUM_LENGTH = CommonHeaderLen(4)+ LspObjectHeaderLen(8) + public static final short LABEL_OBJ_MINIMUM_LENGTH = 12; + + public static final int OFLAG_SET = 1; + public static final int OFLAG_RESET = 0; + public static final int MINIMUM_COMMON_HEADER_LENGTH = 4; + + static final PcepObjectHeader DEFAULT_LABEL_OBJECT_HEADER = new PcepObjectHeader(LABEL_OBJ_CLASS, LABEL_OBJ_TYPE, + PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, LABEL_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader labelObjHeader; + private boolean bOFlag; + private int label; + // Optional TLV + private LinkedList llOptionalTlv; + + /** + * Constructor to initialize parameters for PCEP label object. + * + * @param labelObjHeader label object header + * @param bOFlag O flag + * @param label label + * @param llOptionalTlv list of optional tlvs + */ + public PcepLabelObjectVer1(PcepObjectHeader labelObjHeader, boolean bOFlag, int label, + LinkedList llOptionalTlv) { + this.labelObjHeader = labelObjHeader; + this.bOFlag = bOFlag; + this.label = label; + this.llOptionalTlv = llOptionalTlv; + } + + @Override + public LinkedList getOptionalTlv() { + return this.llOptionalTlv; + } + + @Override + public void setOptionalTlv(LinkedList llOptionalTlv) { + this.llOptionalTlv = llOptionalTlv; + } + + @Override + public boolean getOFlag() { + return this.bOFlag; + } + + @Override + public void setOFlag(boolean value) { + this.bOFlag = value; + } + + @Override + public int getLabel() { + return this.label; + } + + @Override + public void setLabel(int value) { + this.label = value; + } + + /** + * Reads form channel buffer and returns objects of PcepLabelObject. + * + * @param cb of type channel buffer + * @return objects of PcepLabelObject + * @throws PcepParseException when fails to read from channel buffer + */ + public static PcepLabelObject read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader labelObjHeader; + + boolean bOFlag; + int label; + + // Optional TLV + LinkedList llOptionalTlv = new LinkedList<>(); + labelObjHeader = PcepObjectHeader.read(cb); + + //take only LspObject buffer. + ChannelBuffer tempCb = cb.readBytes(labelObjHeader.getObjLen() - OBJECT_HEADER_LENGTH); + + int iTemp = tempCb.readInt(); + bOFlag = (iTemp & (byte) 0x01) == 1; + label = tempCb.readInt(); + + // parse optional TLV + llOptionalTlv = parseOptionalTlv(tempCb); + return new PcepLabelObjectVer1(labelObjHeader, bOFlag, label, llOptionalTlv); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + //write Object header + int objStartIndex = cb.writerIndex(); + int objLenIndex = labelObjHeader.write(cb); + + if (objLenIndex <= 0) { + throw new PcepParseException(" ObjectLength Index is " + objLenIndex); + } + + byte oFlag; + + oFlag = (byte) ((bOFlag) ? OFLAG_SET : OFLAG_RESET); + cb.writeInt(oFlag); + cb.writeInt(label); + + // Add optional TLV + packOptionalTlv(cb); + + //Update object length now + int length = cb.writerIndex() - objStartIndex; + + //will be helpful during print(). + labelObjHeader.setObjLen((short) length); + cb.setShort(objLenIndex, (short) length); + return cb.writerIndex(); + } + + /** + * Returns list of optional tlvs. + * + * @param cb of type channel buffer + * @return list of optional tlvs. + * @throws PcepParseException when fails to parse list of optional tlvs + */ + protected static LinkedList parseOptionalTlv(ChannelBuffer cb) throws PcepParseException { + + LinkedList llOutOptionalTlv = new LinkedList<>(); + + while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) { + + PcepValueType tlv; + short hType = cb.readShort(); + short hLength = cb.readShort(); + int iValue = 0; + + switch (hType) { + + case NexthopIPv4addressTlv.TYPE: + iValue = cb.readInt(); + tlv = new NexthopIPv4addressTlv(iValue); + break; + case NexthopIPv6addressTlv.TYPE: + byte[] ipv6Value = new byte[NexthopIPv6addressTlv.VALUE_LENGTH]; + cb.readBytes(ipv6Value, 0, NexthopIPv6addressTlv.VALUE_LENGTH); + tlv = new NexthopIPv6addressTlv(ipv6Value); + break; + case NexthopUnnumberedIPv4IDTlv.TYPE: + tlv = NexthopUnnumberedIPv4IDTlv.read(cb); + break; + default: + throw new PcepParseException("Unsupported TLV type :" + hType); + } + + // Check for the padding + int pad = hLength % 4; + if (0 < pad) { + pad = 4 - pad; + if (pad <= cb.readableBytes()) { + cb.skipBytes(pad); + } + } + + llOutOptionalTlv.add(tlv); + } + + if (0 < cb.readableBytes()) { + + throw new PcepParseException("Optional Tlv parsing error. Extra bytes received."); + } + return llOutOptionalTlv; + } + + /** + * Returns the writer index. + * + * @param cb of channel buffer. + * @return writer index + */ + protected int packOptionalTlv(ChannelBuffer cb) { + + ListIterator listIterator = llOptionalTlv.listIterator(); + + while (listIterator.hasNext()) { + PcepValueType tlv = listIterator.next(); + + if (tlv == null) { + log.debug("tlv is null from OptionalTlv list"); + continue; + } + tlv.write(cb); + } + return cb.writerIndex(); + } + + /** + * Builder class for PCEP label object. + */ + public static class Builder implements PcepLabelObject.Builder { + + private boolean bIsHeaderSet = false; + private boolean bIsOFlagSet = false; + private boolean bIsLabelSet = false; + + private PcepObjectHeader labelObjHeader; + private boolean bOFlag; + private int label; + + LinkedList llOptionalTlv = new LinkedList<>(); + + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + + @Override + public PcepLabelObject build() throws PcepParseException { + PcepObjectHeader labelObjHeader = this.bIsHeaderSet ? this.labelObjHeader : DEFAULT_LABEL_OBJECT_HEADER; + boolean bOFlag = this.bIsOFlagSet ? this.bOFlag : DEFAULT_OFLAG; + + if (!this.bIsLabelSet) { + throw new PcepParseException(" Label NOT Set while building PcepLabelObject."); + } + if (bIsPFlagSet) { + labelObjHeader.setPFlag(bPFlag); + } + if (bIsIFlagSet) { + labelObjHeader.setIFlag(bIFlag); + } + return new PcepLabelObjectVer1(labelObjHeader, bOFlag, this.label, this.llOptionalTlv); + } + + @Override + public PcepObjectHeader getLabelObjHeader() { + return this.labelObjHeader; + } + + @Override + public Builder setLabelObjHeader(PcepObjectHeader obj) { + this.labelObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public boolean getOFlag() { + return this.bOFlag; + } + + @Override + public Builder setOFlag(boolean value) { + this.bOFlag = value; + this.bIsOFlagSet = true; + return this; + } + + @Override + public int getLabel() { + return this.label; + } + + @Override + public Builder setLabel(int value) { + this.label = value; + this.bIsLabelSet = true; + return this; + } + + @Override + public LinkedList getOptionalTlv() { + return this.llOptionalTlv; + } + + @Override + public Builder setOptionalTlv(LinkedList llOptionalTlv) { + this.llOptionalTlv = llOptionalTlv; + return this; + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("OFlag", bOFlag) + .add("label", label) + .add("OptionalTlvList", llOptionalTlv) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java new file mode 100644 index 00000000..9e4be911 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java @@ -0,0 +1,377 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepLabelRangeObject; +import org.onosproject.pcepio.types.PathSetupTypeTlv; +import org.onosproject.pcepio.types.PcepObjectHeader; +import org.onosproject.pcepio.types.PcepValueType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP label range object. + */ +public class PcepLabelRangeObjectVer1 implements PcepLabelRangeObject { + + /* + * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01, section : 7.2 + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | label type | range size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | label base | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // Optional TLVs // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + LABEL-RANGE Object + */ + protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeObjectVer1.class); + + public static final byte LABEL_RANGE_OBJ_TYPE = 1; + public static final byte LABEL_RANGE_OBJ_CLASS = 60; //to be defined + public static final byte LABEL_RANGE_OBJECT_VERSION = 1; + public static final short LABEL_RANGE_OBJ_MINIMUM_LENGTH = 12; + public static final int MINIMUM_COMMON_HEADER_LENGTH = 4; + //P flag and I flag must be set to 0 + static final PcepObjectHeader DEFAULT_LABELRANGE_OBJECT_HEADER = new PcepObjectHeader(LABEL_RANGE_OBJ_CLASS, + LABEL_RANGE_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, + LABEL_RANGE_OBJ_MINIMUM_LENGTH); + + private PcepObjectHeader labelRangeObjHeader; + private byte labelType; + private int rangeSize; + private int labelBase; + //Optional TLV + private LinkedList llOptionalTlv; + + /** + * Constructor to initialize parameters for PCEP label range object. + * + * @param labelRangeObjHeader label range object header + * @param labelType label type + * @param rangeSize range size + * @param labelBase label base + * @param llOptionalTlv list of optional tlvs + */ + public PcepLabelRangeObjectVer1(PcepObjectHeader labelRangeObjHeader, byte labelType, int rangeSize, int labelBase, + LinkedList llOptionalTlv) { + this.labelRangeObjHeader = labelRangeObjHeader; + this.labelType = labelType; + this.rangeSize = rangeSize; + this.llOptionalTlv = llOptionalTlv; + this.labelBase = labelBase; + } + + @Override + public void setLabelRangeObjHeader(PcepObjectHeader obj) { + this.labelRangeObjHeader = obj; + } + + @Override + public void setLabelType(byte labelType) { + this.labelType = labelType; + } + + @Override + public void setRangeSize(int rangeSize) { + this.rangeSize = rangeSize; + } + + @Override + public void setLabelBase(int labelBase) { + this.labelBase = labelBase; + } + + @Override + public PcepObjectHeader getLabelRangeObjHeader() { + return this.labelRangeObjHeader; + } + + @Override + public byte getLabelType() { + return this.labelType; + } + + @Override + public int getRangeSize() { + return this.rangeSize; + } + + @Override + public int getLabelBase() { + return this.labelBase; + } + + /** + * Reads from the channel buffer and returns object of PcepLabelRangeObject. + * + * @param cb of type channel buffer + * @return object of PcepLabelRangeObject + * @throws PcepParseException when fails to read from channel buffer + */ + public static PcepLabelRangeObject read(ChannelBuffer cb) throws PcepParseException { + + PcepObjectHeader labelRangeObjHeader; + byte labelType; + int rangeSize; + int labelBase; + + LinkedList llOptionalTlv = new LinkedList<>(); + + labelRangeObjHeader = PcepObjectHeader.read(cb); + + //take only LabelRangeObject buffer. + ChannelBuffer tempCb = cb.readBytes(labelRangeObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH); + int temp = 0; + temp = tempCb.readInt(); + rangeSize = temp & 0x00FFFFFF; + labelType = (byte) (temp >> 24); + labelBase = tempCb.readInt(); + llOptionalTlv = parseOptionalTlv(tempCb); + return new PcepLabelRangeObjectVer1(labelRangeObjHeader, labelType, rangeSize, labelBase, llOptionalTlv); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + + int objStartIndex = cb.writerIndex(); + + //write common header + int objLenIndex = labelRangeObjHeader.write(cb); + int temp = 0; + temp = labelType; + temp = temp << 24; + temp = temp | rangeSize; + cb.writeInt(temp); + + // Add optional TLV + if (!packOptionalTlv(cb)) { + throw new PcepParseException("Error while writing Optional tlv."); + } + + //now write LabelRange Object Length + cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex)); + return cb.writerIndex() - objStartIndex; + } + + /** + * Returns list of optional tlvs. + * + * @param cb of type channle buffer + * @return list of optional tlvs + * @throws PcepParseException whne fails to parse list of optional tlvs + */ + public static LinkedList parseOptionalTlv(ChannelBuffer cb) throws PcepParseException { + + LinkedList llOutOptionalTlv = new LinkedList<>(); + + while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) { + + PcepValueType tlv; + int iValue; + short hType = cb.readShort(); + short hLength = cb.readShort(); + + switch (hType) { + + case PathSetupTypeTlv.TYPE: + iValue = cb.readInt(); + tlv = new PathSetupTypeTlv(iValue); + break; + + default: + throw new PcepParseException("Unsupported TLV in LabelRange Object."); + } + + // Check for the padding + int pad = hLength % 4; + if (0 < pad) { + pad = 4 - pad; + if (pad <= cb.readableBytes()) { + cb.skipBytes(pad); + } + } + llOutOptionalTlv.add(tlv); + } + return llOutOptionalTlv; + } + + /** + * Pack optional tlvs. + * + * @param cb of channel buffer + * @return true + */ + protected boolean packOptionalTlv(ChannelBuffer cb) { + + ListIterator listIterator = llOptionalTlv.listIterator(); + + while (listIterator.hasNext()) { + PcepValueType tlv = listIterator.next(); + + if (tlv == null) { + log.debug("tlv is null from OptionalTlv list"); + continue; + } + tlv.write(cb); + + // need to take care of padding + int pad = tlv.getLength() % 4; + if (0 != pad) { + pad = 4 - pad; + for (int i = 0; i < pad; ++i) { + cb.writeByte((byte) 0); + } + } + } + return true; + } + + /** + * Builder class for PCEP label range object. + */ + public static class Builder implements PcepLabelRangeObject.Builder { + private boolean bIsHeaderSet = false; + private boolean bIsLabelType = false; + private boolean bIsRangeSize = false; + private boolean bIsLabelBase = false; + + byte labelType; + int rangeSize; + int labelBase; + private boolean bIsPFlagSet = false; + private boolean bPFlag; + + private boolean bIsIFlagSet = false; + private boolean bIFlag; + private PcepObjectHeader labelRangeObjHeader; + + LinkedList llOptionalTlv = new LinkedList<>(); + + @Override + public PcepLabelRangeObject build() throws PcepParseException { + PcepObjectHeader labelRangeObjHeader = this.bIsHeaderSet ? this.labelRangeObjHeader + : DEFAULT_LABELRANGE_OBJECT_HEADER; + + if (!this.bIsLabelType) { + throw new PcepParseException("LabelType NOT Set while building label range object."); + } + + if (!this.bIsRangeSize) { + throw new PcepParseException("RangeSize NOT Set while building label range object."); + } + + if (!this.bIsLabelBase) { + throw new PcepParseException("LabelBase NOT Set while building label range object."); + } + + if (bIsPFlagSet) { + labelRangeObjHeader.setPFlag(bPFlag); + } + + if (bIsIFlagSet) { + labelRangeObjHeader.setIFlag(bIFlag); + } + return new PcepLabelRangeObjectVer1(labelRangeObjHeader, this.labelType, this.rangeSize, this.labelBase, + this.llOptionalTlv); + } + + @Override + public PcepObjectHeader getLabelRangeObjHeader() { + return this.labelRangeObjHeader; + } + + @Override + public Builder setLabelRangeObjHeader(PcepObjectHeader obj) { + this.labelRangeObjHeader = obj; + this.bIsHeaderSet = true; + return this; + } + + @Override + public byte getLabelType() { + return this.labelType; + } + + @Override + public Builder setLabelType(byte labelType) { + this.labelType = labelType; + this.bIsLabelType = true; + return this; + } + + @Override + public int getRangeSize() { + return this.rangeSize; + } + + @Override + public Builder setRangeSize(int rangeSize) { + this.rangeSize = rangeSize; + this.bIsRangeSize = true; + return this; + } + + @Override + public int getLabelBase() { + return this.labelBase; + } + + @Override + public Builder setLabelBase(int labelBase) { + this.labelBase = labelBase; + this.bIsLabelBase = true; + return this; + } + + @Override + public Builder setPFlag(boolean value) { + this.bPFlag = value; + this.bIsPFlagSet = true; + return this; + } + + @Override + public Builder setIFlag(boolean value) { + this.bIFlag = value; + this.bIsIFlagSet = true; + return this; + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("LabelType", labelType) + .add("rangeSize", rangeSize) + .add("labelBase", labelBase) + .add("optionalTlvList", llOptionalTlv) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeResvMsgVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeResvMsgVer1.java new file mode 100644 index 00000000..6f3648af --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeResvMsgVer1.java @@ -0,0 +1,198 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepLabelRange; +import org.onosproject.pcepio.protocol.PcepLabelRangeResvMsg; +import org.onosproject.pcepio.protocol.PcepMessageReader; +import org.onosproject.pcepio.protocol.PcepMessageWriter; +import org.onosproject.pcepio.protocol.PcepType; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP label range reserve message. + */ +class PcepLabelRangeResvMsgVer1 implements PcepLabelRangeResvMsg { + + // Pcep version: 1 + + /* + The format of a PCLRResv message is as follows: + + PCLRResv Message>::= + + Where: + + ::= + + + Where + ::=[] + */ + protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeResvMsgVer1.class); + + public static final byte PACKET_VERSION = 1; + // LabelRangeResvMsgMinLength = COMMON-HEADER(4)+SrpObjMinLentgh(12)+LABEL-RANGE-MIN-LENGTH(12) + public static final int PACKET_MINIMUM_LENGTH = 28; + public static final PcepType MSG_TYPE = PcepType.LABEL_RANGE_RESERV; + // + PcepLabelRange labelRange; + + public static final PcepLabelRangeResvMsgVer1.Reader READER = new Reader(); + + /** + * Reader reads LabelRangeResv Message from the channel. + */ + static class Reader implements PcepMessageReader { + + @Override + public PcepLabelRangeResvMsg readFrom(ChannelBuffer cb) throws PcepParseException { + + if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) { + throw new PcepParseException("Channel buffer has less readable bytes than Packet minimum length."); + } + // fixed value property version == 1 + byte version = cb.readByte(); + version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG); + if (version != PACKET_VERSION) { + throw new PcepParseException("Wrong version. Expected=PcepVersion.PCEP_1(1), got=" + version); + } + // fixed value property type == 15 + byte type = cb.readByte(); + if (type != MSG_TYPE.getType()) { + throw new PcepParseException("Wrong type. Expected=PcepType.LABEL_RANGE_RESERV(15), got=" + type); + } + short length = cb.readShort(); + if (length < PACKET_MINIMUM_LENGTH) { + throw new PcepParseException("Wrong length.Expected to be >= " + PACKET_MINIMUM_LENGTH + ", is: " + + length); + } + // parse + PcepLabelRange labelRange = PcepLabelRangeVer1.read(cb); + return new PcepLabelRangeResvMsgVer1(labelRange); + } + } + + /** + * Constructor to initialize PCEP label range. + * + * @param labelRange PCEP label range + */ + PcepLabelRangeResvMsgVer1(PcepLabelRange labelRange) { + this.labelRange = labelRange; + } + + /** + * Builder class for PCEP label range reserve message. + */ + static class Builder implements PcepLabelRangeResvMsg.Builder { + + PcepLabelRange labelRange = new PcepLabelRangeVer1(); + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepType getType() { + return PcepType.LABEL_RANGE_RESERV; + } + + @Override + public PcepLabelRangeResvMsg build() { + return new PcepLabelRangeResvMsgVer1(this.labelRange); + } + + @Override + public PcepLabelRange getLabelRange() { + return this.labelRange; + } + + @Override + public Builder setLabelRange(PcepLabelRange labelRange) { + this.labelRange = labelRange; + return this; + } + } + + @Override + public void writeTo(ChannelBuffer cb) throws PcepParseException { + WRITER.write(cb, this); + } + + static final Writer WRITER = new Writer(); + + /** + * Writer writes LabelRangeResv Message to the channel. + */ + static class Writer implements PcepMessageWriter { + + @Override + public void write(ChannelBuffer cb, PcepLabelRangeResvMsgVer1 message) throws PcepParseException { + + int startIndex = cb.writerIndex(); + // first 3 bits set to version + cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG)); + // message type + cb.writeByte(MSG_TYPE.getType()); + // Length will be set after calculating length, but currently set it as 0. + int msgLenIndex = cb.writerIndex(); + + cb.writeShort((short) 0); + //write Label Range + message.labelRange.write(cb); + + // update message length field + int length = cb.writerIndex() - startIndex; + cb.setShort(msgLenIndex, (short) length); + } + } + + @Override + public PcepVersion getVersion() { + return PcepVersion.PCEP_1; + } + + @Override + public PcepType getType() { + return MSG_TYPE; + } + + @Override + public PcepLabelRange getLabelRange() { + return this.labelRange; + } + + @Override + public void setLabelRange(PcepLabelRange lr) { + this.labelRange = lr; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("labelRange", labelRange) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.java new file mode 100644 index 00000000..411c9604 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.java @@ -0,0 +1,168 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepLabelRange; +import org.onosproject.pcepio.protocol.PcepLabelRangeObject; +import org.onosproject.pcepio.protocol.PcepSrpObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP Label Range. + */ +public class PcepLabelRangeVer1 implements PcepLabelRange { + + protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeVer1.class); + + /* + ::= + + Where + ::=[] + */ + + // PCEP SRP Object + private PcepSrpObject srpObject; + // of type PcepLabelRangeObject. + private LinkedList llLabelRangeList; + + /** + * Default Constructor. + */ + public PcepLabelRangeVer1() { + srpObject = null; + llLabelRangeList = null; + } + + /** + * Constructor to initialize objects. + * + * @param srpObj PCEP Srp object. + * @param llLabelRangeList list of PcepLabelRangeObject. + */ + PcepLabelRangeVer1(PcepSrpObject srpObj, LinkedList llLabelRangeList) { + this.srpObject = srpObj; + this.llLabelRangeList = llLabelRangeList; + } + + @Override + public PcepSrpObject getSrpObject() { + return srpObject; + } + + @Override + public void setSrpObject(PcepSrpObject srpObject) { + this.srpObject = srpObject; + + } + + @Override + public LinkedList getLabelRangeList() { + return llLabelRangeList; + } + + @Override + public void setLabelRangeList(LinkedList ll) { + this.llLabelRangeList = ll; + } + + /** + * Reads channel buffer and returns object of PcepLabelRange. + * + * @param cb of type channel buffer. + * @return object of PcepLabelRange + * @throws PcepParseException when fails to read from channel buffer + */ + public static PcepLabelRange read(ChannelBuffer cb) throws PcepParseException { + + //parse and store SRP mandatory object + PcepSrpObject srpObj = null; + srpObj = PcepSrpObjectVer1.read(cb); + if (srpObj == null) { + throw new PcepParseException("Exception while parsing srp object"); + } + + LinkedList llLabelRangeList = new LinkedList<>(); + boolean bFoundLabelRangeObj = false; + while (0 < cb.readableBytes()) { + //parse and store + PcepLabelRangeObject lrObj; + lrObj = PcepLabelRangeObjectVer1.read(cb); + if (lrObj == null) { + throw new PcepParseException("Exception while parsing label range object"); + } else { + llLabelRangeList.add(lrObj); + bFoundLabelRangeObj = true; + } + } + + if (!bFoundLabelRangeObj) { + throw new PcepParseException("At least one LABEL-RANGE MUST be present."); + } + return new PcepLabelRangeVer1(srpObj, llLabelRangeList); + } + + @Override + public int write(ChannelBuffer cb) throws PcepParseException { + //write Object header + int objStartIndex = cb.writerIndex(); + + //write + int objLenIndex = srpObject.write(cb); + + if (objLenIndex <= 0) { + throw new PcepParseException("bjectLength is " + objLenIndex); + } + + //write + ListIterator listIterator = llLabelRangeList.listIterator(); + while (listIterator.hasNext()) { + listIterator.next().write(cb); + } + + //Update object length now + int length = cb.writerIndex() - objStartIndex; + // As per RFC the length of object should be + // multiples of 4 + int pad = length % 4; + if (pad != 0) { + pad = 4 - pad; + for (int i = 0; i < pad; i++) { + cb.writeByte((byte) 0); + } + length = length + pad; + } + cb.setShort(objLenIndex, (short) length); + return length; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("srpObject", srpObject) + .add("LabelRangeList", llLabelRangeList) + .toString(); + } +} diff --git a/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelUpdateMsgVer1.java b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelUpdateMsgVer1.java new file mode 100644 index 00000000..89347f42 --- /dev/null +++ b/framework/src/onos/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelUpdateMsgVer1.java @@ -0,0 +1,239 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.pcepio.protocol.ver1; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.onosproject.pcepio.exceptions.PcepParseException; +import org.onosproject.pcepio.protocol.PcepLabelUpdate; +import org.onosproject.pcepio.protocol.PcepLabelUpdateMsg; +import org.onosproject.pcepio.protocol.PcepMessageReader; +import org.onosproject.pcepio.protocol.PcepMessageWriter; +import org.onosproject.pcepio.protocol.PcepType; +import org.onosproject.pcepio.protocol.PcepVersion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides PCEP lable update message. + */ +class PcepLabelUpdateMsgVer1 implements PcepLabelUpdateMsg { + + // Pcep version: 1 + + /* + The format of the PCLabelUpd message: + + ::= + + Where: + + ::= + [] + ::= (|) + + Where: + ::= + + + + ::= +