From baac58c7c50e6f89eb0520e3f5b0e83a69839bd3 Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Wed, 11 Nov 2015 14:39:51 -0800 Subject: Updating onos src to commit id ec0425c18cbe49d368c600160f033acf9fe344ca Change-Id: Iec2815bf7771080f25272842b852bd9d33f908ff Signed-off-by: Ashlee Young --- .../java/org/onosproject/dhcp/DhcpService.java | 13 +- .../main/java/org/onosproject/dhcp/DhcpStore.java | 21 +- .../java/org/onosproject/dhcp/IpAssignment.java | 103 ++++- .../onosproject/dhcp/cli/DhcpSetStaticMapping.java | 3 +- .../org/onosproject/dhcp/impl/DhcpManager.java | 75 +++- .../dhcp/impl/DistributedDhcpStore.java | 39 +- .../org/onosproject/dhcp/rest/DHCPWebResource.java | 3 +- .../org/onosproject/dhcp/impl/DhcpManagerTest.java | 9 +- framework/src/onos/apps/openstackswitching/pom.xml | 5 + .../openstackswitching/OpenstackArpHandler.java | 73 +++- .../openstackswitching/OpenstackDhcpHandler.java | 45 -- .../openstackswitching/OpenstackNetwork.java | 22 +- .../openstackswitching/OpenstackSubnet.java | 159 +++++++ .../OpenstackSwitchingManager.java | 106 +++-- .../OpenstackSwitchingRulePopulator.java | 1 - .../OpenstackSwitchingService.java | 6 + .../web/OpenstackNetworkCodec.java | 2 + .../web/OpenstackSubnetCodec.java | 72 ++++ .../web/OpenstackSubnetWebResource.java | 64 +++ .../src/main/webapp/WEB-INF/web.xml | 3 +- .../main/java/org/onosproject/vtnrsc/Router.java | 102 +++++ .../java/org/onosproject/vtnrsc/RouterGateway.java | 108 +++++ .../main/java/org/onosproject/vtnrsc/RouterId.java | 77 ++++ .../flowClassifier/FlowClassifierService.java | 72 ---- .../flowClassifier/impl/FlowClassifierManager.java | 124 ------ .../vtnrsc/flowClassifier/impl/package-info.java | 20 - .../vtnrsc/flowClassifier/package-info.java | 20 - .../flowclassifier/FlowClassifierService.java | 72 ++++ .../flowclassifier/impl/FlowClassifierManager.java | 124 ++++++ .../vtnrsc/flowclassifier/impl/package-info.java | 20 + .../vtnrsc/flowclassifier/package-info.java | 20 + .../vtnrsc/portchain/PortChainIdTest.java | 2 +- .../vtnrsc/portpairgroup/PortPairGroupIdTest.java | 2 +- .../vtnrsc/router/RouterGatewayTest.java | 82 ++++ .../onosproject/vtnrsc/router/RouterIdTest.java | 63 +++ .../resources/FlowClassifierWebResource.java | 2 +- .../org/onosproject/bgpio/protocol/BGPLSNlri.java | 4 +- .../onosproject/bgpio/protocol/BGPNodeLSNlri.java | 4 +- .../bgpio/protocol/BGPPrefixLSNlri.java | 4 +- .../protocol/link_state/BGPLinkLSIdentifier.java | 252 ----------- .../protocol/link_state/BGPNodeLSIdentifier.java | 113 ----- .../protocol/link_state/BGPNodeLSNlriVer4.java | 212 ---------- .../link_state/BGPPrefixIPv4LSNlriVer4.java | 205 --------- .../protocol/link_state/BGPPrefixLSIdentifier.java | 228 ---------- .../bgpio/protocol/link_state/NodeDescriptors.java | 225 ---------- .../bgpio/protocol/link_state/package-info.java | 20 - .../protocol/linkstate/BGPLinkLSIdentifier.java | 252 +++++++++++ .../protocol/linkstate/BGPNodeLSIdentifier.java | 113 +++++ .../protocol/linkstate/BGPNodeLSNlriVer4.java | 212 ++++++++++ .../linkstate/BGPPrefixIPv4LSNlriVer4.java | 205 +++++++++ .../protocol/linkstate/BGPPrefixLSIdentifier.java | 228 ++++++++++ .../bgpio/protocol/linkstate/NodeDescriptors.java | 225 ++++++++++ .../bgpio/protocol/linkstate/package-info.java | 20 + .../types/attr/BgpLinkAttrTeDefaultMetric.java | 132 ++++++ .../bgpio/types/attr/BgpPrefixAttrOpaqueData.java | 134 ++++++ .../bgp/BgpLinkAttrTeDefaultMetricTest.java | 42 ++ .../org/onosproject/cli/net/GroupsListCommand.java | 4 +- .../java/org/onosproject/net/host/HostEvent.java | 37 ++ .../net/newresource/ResourceAdminService.java | 8 +- .../onosproject/store/trivial/SimpleHostStore.java | 12 +- .../org/onosproject/net/host/impl/HostManager.java | 20 +- .../net/newresource/impl/ResourceManager.java | 2 +- .../net/proxyarp/impl/ProxyArpManager.java | 92 +++- .../onosproject/net/host/impl/HostManagerTest.java | 17 +- .../net/proxyarp/impl/ProxyArpManagerTest.java | 469 ++++++++++++++------- .../onosproject/store/host/impl/ECHostStore.java | 91 ++-- .../newresource/impl/ConsistentResourceStore.java | 7 +- .../openflow/OpenflowSwitchDriverAdapter.java | 7 +- .../impl/OpenFlowControllerImplTest.java | 283 +++++++++++++ framework/src/onos/openflow/pom.xml | 9 + framework/src/onos/pom.xml | 3 +- .../conf/src/main/resources/onos/checkstyle.xml | 4 +- framework/src/onos/tools/build/onos-build-docs | 4 +- framework/src/onos/tools/dev/bash_profile | 1 - .../src/onos/tools/test/scenarios/net-topo.xml | 2 +- framework/src/onos/utils/catalyst/pom.xml | 64 +++ framework/src/onos/utils/pom.xml | 3 +- .../ui/impl/TopologyViewMessageHandler.java | 1 + .../web/gui/src/main/webapp/app/view/topo/topo.js | 12 +- .../src/main/webapp/app/view/topo/topoDialog.js | 9 +- .../src/main/webapp/app/view/topo/topoToolbar.js | 9 +- 81 files changed, 3810 insertions(+), 1924 deletions(-) delete mode 100644 framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java create mode 100644 framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java create mode 100644 framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java create mode 100644 framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/Router.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterGateway.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterId.java delete mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/FlowClassifierService.java delete mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/FlowClassifierManager.java delete mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java delete mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/package-info.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterGatewayTest.java create mode 100644 framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterIdTest.java delete mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPLinkLSIdentifier.java delete mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSIdentifier.java delete mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSNlriVer4.java delete mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixIPv4LSNlriVer4.java delete mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixLSIdentifier.java delete mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/NodeDescriptors.java delete mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/package-info.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPLinkLSIdentifier.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSIdentifier.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSNlriVer4.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixIPv4LSNlriVer4.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixLSIdentifier.java create mode 100644 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/NodeDescriptors.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/package-info.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetric.java create mode 100755 framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueData.java create mode 100644 framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpLinkAttrTeDefaultMetricTest.java create mode 100644 framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplTest.java create mode 100644 framework/src/onos/utils/catalyst/pom.xml (limited to 'framework') diff --git a/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java index 7c2127f9..e356c38b 100644 --- a/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java @@ -19,8 +19,10 @@ import org.onlab.packet.Ip4Address; import org.onlab.packet.MacAddress; import org.onosproject.net.HostId; +import java.util.List; import java.util.Map; + /** * DHCP Service Interface. */ @@ -56,12 +58,16 @@ public interface DhcpService { /** * Registers a static IP mapping with the DHCP Server. + * Supports the request from OpenStack * - * @param macID macID of the client + * @param macID macID of the client * @param ipAddress IP Address requested for the client - * @return true if the mapping was successfully registered, false otherwise + * @param fromOpenStack true if the request is from OpenStack + * @param addressList subnetMask, DHCP/Router/Domain Server IP Address if the request from OpenStack + * @return true if the mapping was successfully added, false otherwise */ - boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress); + boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean fromOpenStack, + List addressList); /** * Removes a static IP mapping with the DHCP Server. @@ -77,5 +83,4 @@ public interface DhcpService { * @return list of available IPs */ Iterable getAvailableIPs(); - } diff --git a/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java index e263b3a2..bd2e16b3 100644 --- a/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java @@ -19,8 +19,10 @@ import org.onlab.packet.Ip4Address; import org.onlab.packet.MacAddress; import org.onosproject.net.HostId; +import java.util.List; import java.util.Map; + /** * DHCPStore Interface. */ @@ -43,15 +45,21 @@ public interface DhcpStore { */ Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP); + /** * Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message. * * @param hostId Host Id of the client requesting an IP * @param ipAddr IP Address being requested * @param leaseTime Lease time offered by the server for this mapping + * @param fromOpenStack true if the request is from Openstack + * @param addressList subnetMask, DHCP IP Address, Router IP Address, Domain Server IP Address if the request + * from OpenStack * @return returns true if the assignment was successful, false otherwise */ - boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime); + boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack, + List addressList); + /** * Sets the default time for which suggested IP mappings are valid. @@ -87,9 +95,11 @@ public interface DhcpStore { * * @param macID macID of the client * @param ipAddr IP Address requested for the client + * @param fromOpenStack true if the request is from Openstack + * @param addressList subnetMask, DHCP/Router/Domain Server IP Address if the request from OpenStack * @return true if the mapping was successfully registered, false otherwise */ - boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr); + boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack, List addressList); /** * Removes a static IP mapping associated with the given MAC ID from the DHCP Server. @@ -106,4 +116,11 @@ public interface DhcpStore { */ Iterable getAvailableIPs(); + /** + * + * + * @param hostId + * @return + */ + IpAssignment getIpAssignmentFromAllocationMap(HostId hostId); } diff --git a/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java index 9b3aa686..998579e2 100644 --- a/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java @@ -33,6 +33,16 @@ public final class IpAssignment { private final long leasePeriod; + private final Ip4Address subnetMask; + + private final Ip4Address dhcpServer; + + private final Ip4Address routerAddress; + + private final Ip4Address domainServer; + + private final boolean fromOpenStack; + private final AssignmentStatus assignmentStatus; public enum AssignmentStatus { @@ -41,6 +51,10 @@ public final class IpAssignment { */ Option_Requested, + /** + * IP Assignment has been requested by a OpenStack. + */ + Option_Requested_From_OpenStack, /** * IP has been assigned to a host. */ @@ -58,16 +72,28 @@ public final class IpAssignment { * * @param ipAddress * @param leasePeriod + * @param timestamp * @param assignmentStatus + * @param subnetMask + * @param dhcpServer + * @param routerAddress + * @param domainServer + * @param fromOpenStack */ private IpAssignment(Ip4Address ipAddress, long leasePeriod, Date timestamp, - AssignmentStatus assignmentStatus) { + AssignmentStatus assignmentStatus, Ip4Address subnetMask, Ip4Address dhcpServer, + Ip4Address routerAddress, Ip4Address domainServer, boolean fromOpenStack) { this.ipAddress = ipAddress; this.leasePeriod = leasePeriod; this.timestamp = timestamp; this.assignmentStatus = assignmentStatus; + this.subnetMask = subnetMask; + this.dhcpServer = dhcpServer; + this.routerAddress = routerAddress; + this.domainServer = domainServer; + this.fromOpenStack = fromOpenStack; } /** @@ -115,6 +141,26 @@ public final class IpAssignment { return (int) this.leasePeriod * 1000; } + public Ip4Address subnetMask() { + return subnetMask; + } + + public Ip4Address dhcpServer() { + return dhcpServer; + } + + public Ip4Address routerAddress() { + return routerAddress; + } + + public Ip4Address domainServer() { + return domainServer; + } + + public boolean fromOpenStack() { + return fromOpenStack; + } + @Override public String toString() { return MoreObjects.toStringHelper(getClass()) @@ -122,6 +168,11 @@ public final class IpAssignment { .add("timestamp", timestamp) .add("lease", leasePeriod) .add("assignmentStatus", assignmentStatus) + .add("subnetMask", subnetMask) + .add("dhcpServer", dhcpServer) + .add("routerAddress", routerAddress) + .add("domainServer", domainServer) + .add("fromOpenStack", fromOpenStack) .toString(); } @@ -157,6 +208,16 @@ public final class IpAssignment { private AssignmentStatus assignmentStatus; + private Ip4Address subnetMask; + + private Ip4Address dhcpServer; + + private Ip4Address domainServer; + + private Ip4Address routerAddress; + + private boolean fromOpenStack = false; + private Builder() { } @@ -170,10 +231,8 @@ public final class IpAssignment { public IpAssignment build() { validateInputs(); - return new IpAssignment(ipAddress, - leasePeriod, - timeStamp, - assignmentStatus); + return new IpAssignment(ipAddress, leasePeriod, timeStamp, assignmentStatus, subnetMask, + dhcpServer, domainServer, routerAddress, fromOpenStack); } public Builder ipAddress(Ip4Address addr) { @@ -196,14 +255,48 @@ public final class IpAssignment { return this; } + public Builder subnetMask(Ip4Address subnetMask) { + this.subnetMask = subnetMask; + return this; + } + + public Builder dhcpServer(Ip4Address dhcpServer) { + this.dhcpServer = dhcpServer; + return this; + } + + public Builder domainServer(Ip4Address domainServer) { + this.domainServer = domainServer; + return this; + } + + public Builder routerAddress(Ip4Address routerAddress) { + this.routerAddress = routerAddress; + return this; + } + + public Builder fromOpenStack(boolean fromOpenStack) { + this.fromOpenStack = fromOpenStack; + return this; + } + + private void validateInputs() { checkNotNull(ipAddress, "IP Address must be specified"); checkNotNull(assignmentStatus, "Assignment Status must be specified"); checkNotNull(leasePeriod, "Lease Period must be specified"); checkNotNull(timeStamp, "Timestamp must be specified"); + if (fromOpenStack) { + checkNotNull(subnetMask, "subnetMask must be specified in case of OpenStack"); + checkNotNull(dhcpServer, "dhcpServer must be specified in case of OpenStack"); + checkNotNull(domainServer, "domainServer must be specified in case of OpenStack"); + checkNotNull(routerAddress, "routerAddress must be specified in case of OpenStack"); + } + switch (assignmentStatus) { case Option_Requested: + case Option_Requested_From_OpenStack: case Option_Assigned: case Option_Expired: break; diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java index 9f4f6580..e1ce8904 100644 --- a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java @@ -15,6 +15,7 @@ */ package org.onosproject.dhcp.cli; +import com.google.common.collect.Lists; import org.apache.karaf.shell.commands.Argument; import org.apache.karaf.shell.commands.Command; import org.onlab.packet.Ip4Address; @@ -48,7 +49,7 @@ public class DhcpSetStaticMapping extends AbstractShellCommand { try { MacAddress macID = MacAddress.valueOf(macAddr); Ip4Address ipAddress = Ip4Address.valueOf(ipAddr); - if (dhcpService.setStaticMapping(macID, ipAddress)) { + if (dhcpService.setStaticMapping(macID, ipAddress, false, Lists.newArrayList())) { print(DHCP_SUCCESS); } else { print(DHCP_FAILURE); diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java index 96d94a2b..4093f2d2 100644 --- a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java @@ -16,6 +16,7 @@ package org.onosproject.dhcp.impl; 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; @@ -77,7 +78,6 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; - import static org.onlab.packet.MacAddress.valueOf; import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; @@ -168,7 +168,6 @@ public class DhcpManager implements DhcpService { cfgService.addListener(cfgListener); factories.forEach(cfgService::registerConfigFactory); cfgListener.reconfigureNetwork(cfgService.getConfig(appId, DhcpConfig.class)); - hostProviderService = hostProviderRegistry.register(hostProvider); packetService.addProcessor(processor, PacketProcessor.director(0)); requestPackets(); @@ -242,8 +241,12 @@ public class DhcpManager implements DhcpService { } @Override - public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress) { - return dhcpStore.assignStaticIP(macID, ipAddress); + public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean fromOpenStack, + List addressList) { + log.debug("setStaticMapping is called with Mac: {}, Ip: {} addressList: {}", + macID.toString(), ipAddress.toString(), addressList.toString()); + + return dhcpStore.assignStaticIP(macID, ipAddress, fromOpenStack, addressList); } @Override @@ -268,6 +271,26 @@ public class DhcpManager implements DhcpService { */ private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) { + Ip4Address subnetMaskReply; + Ip4Address dhcpServerReply; + Ip4Address routerAddressReply; + Ip4Address domainServerReply; + IpAssignment ipAssignment; + + ipAssignment = dhcpStore.getIpAssignmentFromAllocationMap(HostId.hostId(packet.getSourceMAC())); + + if (ipAssignment != null && ipAssignment.fromOpenStack()) { + subnetMaskReply = ipAssignment.subnetMask(); + dhcpServerReply = ipAssignment.dhcpServer(); + domainServerReply = ipAssignment.domainServer(); + routerAddressReply = ipAssignment.routerAddress(); + } else { + subnetMaskReply = subnetMask; + dhcpServerReply = myIP; + routerAddressReply = routerAddress; + domainServerReply = domainServer; + } + // Ethernet Frame. Ethernet ethReply = new Ethernet(); ethReply.setSourceMACAddress(myMAC); @@ -278,7 +301,7 @@ public class DhcpManager implements DhcpService { // IP Packet IPv4 ipv4Packet = (IPv4) packet.getPayload(); IPv4 ipv4Reply = new IPv4(); - ipv4Reply.setSourceAddress(myIP.toInt()); + ipv4Reply.setSourceAddress(dhcpServerReply.toInt()); ipv4Reply.setDestinationAddress(ipOffered.toInt()); ipv4Reply.setTtl(packetTTL); @@ -299,7 +322,7 @@ public class DhcpManager implements DhcpService { if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { dhcpReply.setYourIPAddress(ipOffered.toInt()); - dhcpReply.setServerIPAddress(myIP.toInt()); + dhcpReply.setServerIPAddress(dhcpServerReply.toInt()); if (dhcpPacket.getGatewayIPAddress() == 0) { ipv4Reply.setDestinationAddress(IP_BROADCAST.toInt()); } @@ -322,7 +345,7 @@ public class DhcpManager implements DhcpService { option = new DHCPOption(); option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()); option.setLength((byte) 4); - option.setData(myIP.toOctets()); + option.setData(dhcpServerReply.toOctets()); optionList.add(option); if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { @@ -352,7 +375,7 @@ public class DhcpManager implements DhcpService { option = new DHCPOption(); option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue()); option.setLength((byte) 4); - option.setData(subnetMask.toOctets()); + option.setData(subnetMaskReply.toOctets()); optionList.add(option); // Broadcast Address. @@ -366,14 +389,14 @@ public class DhcpManager implements DhcpService { option = new DHCPOption(); option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue()); option.setLength((byte) 4); - option.setData(routerAddress.toOctets()); + option.setData(routerAddressReply.toOctets()); optionList.add(option); // DNS Server Address. option = new DHCPOption(); option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue()); option.setLength((byte) 4); - option.setData(domainServer.toOctets()); + option.setData(domainServerReply.toOctets()); optionList.add(option); } @@ -384,7 +407,6 @@ public class DhcpManager implements DhcpService { optionList.add(option); dhcpReply.setOptions(optionList); - udpReply.setPayload(dhcpReply); ipv4Reply.setPayload(udpReply); ethReply.setPayload(ipv4Reply); @@ -449,31 +471,40 @@ public class DhcpManager implements DhcpService { if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) { outgoingPacketType = DHCPPacketType.DHCPOFFER; - Ip4Address ipOffered = dhcpStore.suggestIP(hostId, requestedIP); + Ip4Address ipOffered = null; + ipOffered = dhcpStore.suggestIP(hostId, requestedIP); + if (ipOffered != null) { Ethernet ethReply = buildReply(packet, ipOffered, (byte) outgoingPacketType.getValue()); sendReply(context, ethReply); } - } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPREQUEST.getValue()) { if (flagIfServerIP && flagIfRequestedIP) { // SELECTING state - if (myIP.equals(serverIP)) { - if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) { - outgoingPacketType = DHCPPacketType.DHCPACK; - discoverHost(context, requestedIP); - } else { - outgoingPacketType = DHCPPacketType.DHCPNAK; - } + if (dhcpStore.getIpAssignmentFromAllocationMap(HostId.hostId(clientMAC)) + .fromOpenStack()) { + outgoingPacketType = DHCPPacketType.DHCPACK; Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); sendReply(context, ethReply); + } else { + if (myIP.equals(serverIP)) { + if (dhcpStore.assignIP(hostId, requestedIP, leaseTime, false, Lists.newArrayList())) { + outgoingPacketType = DHCPPacketType.DHCPACK; + discoverHost(context, requestedIP); + } else { + outgoingPacketType = DHCPPacketType.DHCPNAK; + } + Ethernet ethReply = buildReply(packet, requestedIP, + (byte) outgoingPacketType.getValue()); + sendReply(context, ethReply); + } } } else if (flagIfRequestedIP) { // INIT-REBOOT state - if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) { + if (dhcpStore.assignIP(hostId, requestedIP, leaseTime, false, Lists.newArrayList())) { outgoingPacketType = DHCPPacketType.DHCPACK; Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); sendReply(context, ethReply); @@ -485,7 +516,7 @@ public class DhcpManager implements DhcpService { int ciaadr = dhcpPayload.getClientIPAddress(); if (ciaadr != 0) { Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr); - if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime)) { + if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime, false, Lists.newArrayList())) { outgoingPacketType = DHCPPacketType.DHCPACK; discoverHost(context, clientIaddr); } else if (packet.getEtherType() == Ethernet.TYPE_IPV4 && diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java index 63f69d40..0f25495e 100644 --- a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java @@ -38,8 +38,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; -import java.util.HashMap; import java.util.Map; +import java.util.List; +import java.util.HashMap; import java.util.Objects; /** @@ -105,7 +106,9 @@ public class DistributedDhcpStore implements DhcpStore { IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); Ip4Address ipAddr = assignmentInfo.ipAddress(); - if (status == IpAssignment.AssignmentStatus.Option_Assigned || + if (assignmentInfo.fromOpenStack()) { + return assignmentInfo.ipAddress(); + } else if (status == IpAssignment.AssignmentStatus.Option_Assigned || status == IpAssignment.AssignmentStatus.Option_Requested) { // Client has a currently Active Binding. if (ipWithinRange(ipAddr)) { @@ -160,9 +163,11 @@ public class DistributedDhcpStore implements DhcpStore { } @Override - public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) { + public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack, + List addressList) { IpAssignment assignmentInfo; + if (allocationMap.containsKey(hostId)) { assignmentInfo = allocationMap.get(hostId).value(); IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); @@ -207,6 +212,20 @@ public class DistributedDhcpStore implements DhcpStore { allocationMap.put(hostId, assignmentInfo); return true; } + } else if (fromOpenStack) { + assignmentInfo = IpAssignment.builder() + .ipAddress(ipAddr) + .timestamp(new Date()) + .leasePeriod(leaseTime) + .fromOpenStack(true) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested_From_OpenStack) + .subnetMask((Ip4Address) addressList.toArray()[0]) + .dhcpServer((Ip4Address) addressList.toArray()[1]) + .domainServer((Ip4Address) addressList.toArray()[2]) + .routerAddress((Ip4Address) addressList.toArray()[3]) + .build(); + allocationMap.put(hostId, assignmentInfo); + return true; } return false; } @@ -239,7 +258,8 @@ public class DistributedDhcpStore implements DhcpStore { IpAssignment assignment; for (Map.Entry> entry: allocationMap.entrySet()) { assignment = entry.getValue().value(); - if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) { + if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned + || assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Requested_From_OpenStack) { validMapping.put(entry.getKey(), assignment); } } @@ -256,9 +276,10 @@ public class DistributedDhcpStore implements DhcpStore { } @Override - public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { + public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack, + List addressList) { HostId host = HostId.hostId(macID); - return assignIP(host, ipAddr, -1); + return assignIP(host, ipAddr, -1, fromOpenStack, addressList); } @Override @@ -299,6 +320,11 @@ public class DistributedDhcpStore implements DhcpStore { } } + @Override + public IpAssignment getIpAssignmentFromAllocationMap(HostId hostId) { + return allocationMap.get(hostId).value(); + } + /** * Fetches the next available IP from the free pool pf IPs. * @@ -326,3 +352,4 @@ public class DistributedDhcpStore implements DhcpStore { return false; } } + 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 index 646ab7ea..7a078df9 100644 --- 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 @@ -18,6 +18,7 @@ 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; @@ -121,7 +122,7 @@ public class DHCPWebResource extends AbstractWebResource { if (macID != null && ip != null) { if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()), - Ip4Address.valueOf(ip.asText()))) { + Ip4Address.valueOf(ip.asText()), false, Lists.newArrayList())) { throw new IllegalArgumentException("Static Mapping Failed. The IP maybe unavailable."); } } diff --git a/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java b/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java index fd4701c6..bb6b74cc 100644 --- a/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java +++ b/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java @@ -228,7 +228,8 @@ public class DhcpManagerTest { return Ip4Address.valueOf(EXPECTED_IP); } - public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) { + public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack, + List addressList) { return true; } @@ -255,7 +256,8 @@ public class DhcpManagerTest { return map; } - public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { + public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack, + List addressList) { return true; } @@ -268,6 +270,9 @@ public class DhcpManagerTest { ipList.add(Ip4Address.valueOf(EXPECTED_IP)); return ImmutableSet.copyOf(ipList); } + public IpAssignment getIpAssignmentFromAllocationMap(HostId hostId) { + return null; + } } /** diff --git a/framework/src/onos/apps/openstackswitching/pom.xml b/framework/src/onos/apps/openstackswitching/pom.xml index 245b9e80..52129b6f 100644 --- a/framework/src/onos/apps/openstackswitching/pom.xml +++ b/framework/src/onos/apps/openstackswitching/pom.xml @@ -80,6 +80,11 @@ org.osgi org.osgi.core + + org.onosproject + onos-app-dhcp-api + ${project.version} + diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java index afaf7a22..0c139d8d 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java @@ -15,11 +15,20 @@ */ package org.onosproject.openstackswitching; +import org.onlab.packet.ARP; +import org.onlab.packet.Ethernet; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.MacAddress; +import org.onosproject.net.flow.DefaultTrafficTreatment; +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.PacketService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import java.util.HashMap; +import java.nio.ByteBuffer; +import java.util.Map; /** * It handles ARP packet from VMs. @@ -28,16 +37,18 @@ public class OpenstackArpHandler { private static Logger log = LoggerFactory .getLogger(OpenstackArpHandler.class); - - HashMap openstackPortHashMap; + private PacketService packetService; + private Map openstackPortMap; /** - * Constructs an OpenstackArpHandler. + * Returns OpenstackArpHandler reference. * - * @param openstackPortMap port map + * @param openstackPortMap + * @param packetService */ - public OpenstackArpHandler(HashMap openstackPortMap) { - this.openstackPortHashMap = openstackPortMap; + public OpenstackArpHandler(Map openstackPortMap, PacketService packetService) { + this.openstackPortMap = openstackPortMap; + this.packetService = packetService; } /** @@ -46,6 +57,50 @@ public class OpenstackArpHandler { * @param pkt ARP request packet */ public void processPacketIn(InboundPacket pkt) { - log.warn("Received an ARP packet"); + Ethernet ethernet = pkt.parsed(); + ARP arp = (ARP) ethernet.getPayload(); + + if (arp.getOpCode() == ARP.OP_REQUEST) { + byte[] srcMacAddress = arp.getSenderHardwareAddress(); + byte[] srcIPAddress = arp.getSenderProtocolAddress(); + byte[] dstIPAddress = arp.getTargetProtocolAddress(); + + //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); + + if (openstackPort != null) { + macAddress = openstackPort.macAddress(); + log.debug("Found MACAddress: {}", macAddress.toString()); + } else { + return; + } + + //Creates a response packet + ARP arpReply = new ARP(); + arpReply.setOpCode(ARP.OP_REPLY) + .setHardwareAddressLength(arp.getHardwareAddressLength()) + .setHardwareType(arp.getHardwareType()) + .setProtocolAddressLength(arp.getProtocolAddressLength()) + .setProtocolType(arp.getProtocolType()) + .setSenderHardwareAddress(macAddress.toBytes()) + .setSenderProtocolAddress(dstIPAddress) + .setTargetHardwareAddress(srcMacAddress) + .setTargetProtocolAddress(srcIPAddress); + + //Sends a response packet + ethernet.setDestinationMACAddress(srcMacAddress) + .setSourceMACAddress(macAddress) + .setEtherType(Ethernet.TYPE_ARP) + .setPayload(arpReply); + + TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder(); + builder.setOutput(pkt.receivedFrom().port()); + OutboundPacket packet = new DefaultOutboundPacket(pkt.receivedFrom().deviceId(), + builder.build(), ByteBuffer.wrap(ethernet.serialize())); + packetService.emit(packet); + } } } diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java deleted file mode 100644 index 9c3641c1..00000000 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java +++ /dev/null @@ -1,45 +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.onosproject.net.packet.InboundPacket; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * It handles DHCP request packets. - */ -public class OpenstackDhcpHandler { - - private static Logger log = LoggerFactory - .getLogger(OpenstackDhcpHandler.class); - - /** - * Returns OpenstackDhcpHandler reference. - */ - public OpenstackDhcpHandler() { - - } - - /** - * Processes DHCP request packets. - * - * @param pkt DHCP request packet - */ - public void processPacketIn(InboundPacket pkt) { - log.warn("Received a DHCP packet"); - } -} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java index dc7c0263..7bfdf290 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java @@ -26,8 +26,18 @@ public final class OpenstackNetwork { private String name; private String tenantId; private String segmentId; - private String networkType; private String id; + private NetworkType networkType; + + public enum NetworkType { + /** + * Currently only VXLAN moded is supported. + */ + VXLAN, + VLAN, + STT, + LOCAL + } /** * Returns the builder object of the OpenstackNetwork class. @@ -39,12 +49,12 @@ public final class OpenstackNetwork { } private OpenstackNetwork(String name, String tenantId, String id, String sid, - String type) { + NetworkType type) { this.name = checkNotNull(name); this.tenantId = checkNotNull(tenantId); this.segmentId = checkNotNull(sid); this.id = checkNotNull(id); - this.networkType = checkNotNull(type); + this.networkType = type; } public String name() { @@ -63,7 +73,7 @@ public final class OpenstackNetwork { return this.segmentId; } - public String networkType() { + public NetworkType networkType() { return this.networkType; } @@ -72,7 +82,7 @@ public final class OpenstackNetwork { private String tenantId; private String id; private String sid; - private String networkType; + private NetworkType networkType; public Builder name(String name) { this.name = name; @@ -98,7 +108,7 @@ public final class OpenstackNetwork { return this; } - public Builder networkType(String type) { + public Builder networkType(NetworkType type) { this.networkType = type; return this; diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java new file mode 100644 index 00000000..39d783e3 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.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.openstackswitching; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Represents the subnet information given by Neutron. + * + */ +public final class OpenstackSubnet { + private String name; + private boolean enableHhcp; + private String networkId; + private String tenantId; + private String 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 cidr, String id) { + this.name = name; + this.enableHhcp = enableHhcp; + this.networkId = checkNotNull(networkId); + this.tenantId = checkNotNull(tenantId); + this.dnsNameservers = dnsNameservers; + this.gatewayIp = gatewayIp; + this.cidr = checkNotNull(cidr); + this.id = checkNotNull(id); + } + + /** + * Returns OpenstackSubnet builder object. + * + * @return OpenstackSubnet builder + */ + public static OpenstackSubnet.Builder builder() { + return new Builder(); + } + + public String name() { + return name; + } + + public boolean enableHhcp() { + return enableHhcp; + } + + public String networkId() { + return networkId; + } + + public String tenantId() { + return tenantId; + } + + public String dnsNameservers() { + return dnsNameservers; + } + + public String gatewayIp() { + return gatewayIp; + } + + public String cidr() { + return cidr; + } + + public String id() { + return id; + } + + // TODO : Implement the following functions when necessary + + /** + * OpenstackSubnet Builder class. + * + */ + public static final class Builder { + private String name; + private boolean enableDhcp; + private String networkId; + private String tenantId; + private String dnsNameservers; + private String gatewayIp; + private String cidr; + private String id; + + Builder() {} + + public Builder setName(String name) { + this.name = name; + + return this; + } + + public Builder setEnableDhcp(boolean enableDhcp) { + this.enableDhcp = enableDhcp; + + return this; + } + + public Builder setNetworkId(String networkId) { + this.networkId = networkId; + + return this; + } + + public Builder setTenantId(String tenantId) { + this.tenantId = tenantId; + + return this; + } + + public Builder setDnsNameservers(String dnsNameservers) { + this.dnsNameservers = dnsNameservers; + + return this; + } + + public Builder setGatewayIp(String gatewayIp) { + this.gatewayIp = gatewayIp; + + return this; + } + + public Builder setCidr(String cidr) { + this.cidr = cidr; + + return this; + } + + public Builder setId(String id) { + this.id = id; + + return this; + } + + public OpenstackSubnet build() { + return new OpenstackSubnet(name, enableDhcp, networkId, tenantId, + dnsNameservers, gatewayIp, cidr, id); + } + } +} 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 index baae7f80..4be8a50d 100644 --- 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 @@ -24,13 +24,12 @@ 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.IPv4; import org.onlab.packet.Ip4Address; import org.onlab.packet.Ip4Prefix; import org.onlab.packet.MacAddress; -import org.onlab.packet.UDP; 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; @@ -45,8 +44,8 @@ import org.onosproject.net.packet.PacketService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -73,12 +72,14 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { @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 OpenstackDhcpHandler dhcpHandler = new OpenstackDhcpHandler(); + private OpenstackSwitchingRulePopulator rulePopulator; private ExecutorService deviceEventExcutorService = Executors.newFixedThreadPool(10); @@ -86,12 +87,14 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { private InternalDeviceListener internalDeviceListener = new InternalDeviceListener(); // Map - private HashMap openstackPortMap; + private Map openstackPortMap; // Map - private HashMap openstackNetworkMap; + private Map openstackNetworkMap; + // Map + private Map openstackSubnetMap; // Map > - private HashMap> vniPortMap; - private HashMap tunnelPortMap; + private Map> vniPortMap; + private Map tunnelPortMap; @Activate @@ -104,11 +107,11 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { openstackPortMap = Maps.newHashMap(); openstackNetworkMap = Maps.newHashMap(); + openstackSubnetMap = Maps.newHashMap(); + vniPortMap = Maps.newHashMap(); tunnelPortMap = Maps.newHashMap(); - - arpHandler = new OpenstackArpHandler(openstackPortMap); - + arpHandler = new OpenstackArpHandler(openstackPortMap, packetService); log.info("Started"); } @@ -124,9 +127,43 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { @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() { @@ -142,8 +179,15 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { 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.warn("device {} is added", device.id()); + log.debug("device {} is added", device.id()); rulePopulator.populateDefaultRules(device.id()); } @@ -152,7 +196,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { // TODO: Make it stateless // TODO: All the logics need to be processed inside of the rulePopulator class synchronized (vniPortMap) { - log.warn("port {} is updated", port.toString()); + log.debug("port {} is updated", port.toString()); updatePortMaps(device, port); if (!port.annotations().value("portName").equals("vxlan")) { @@ -163,7 +207,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { } private void processPortRemoved(Device device, Port port) { - log.warn("port {} is removed", port.toString()); + log.debug("port {} is removed", port.toString()); // TODO: need to update the vniPortMap } @@ -182,7 +226,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { // TODO: Avoid duplicate flow rule set up for VMs in other Cnode // (possibly avoided by flowrule subsystem?) if (tunnelPortMap.get(hostIpAddress) == null) { - log.warn("There is no tunnel port information"); + log.debug("There is no tunnel port information"); return; } String vni = getVniForPort(portName); @@ -251,20 +295,19 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { .filter(p -> p.id().startsWith(uuid)) .findFirst().get(); if (port == null) { - log.warn("No port information for port {}", portName); + 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.warn("No subnet information for network {}", subnet.id()); - // 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()); - return null; + return Ip4Prefix.valueOf(subnet.cidr()); } /** @@ -280,14 +323,14 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { .filter(p -> p.id().startsWith(uuid)) .findFirst().get(); if (port == null) { - log.warn("No port information for port {}", portName); + 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.warn("No VNI information for network {}", network.id()); + log.debug("No VNI information for network {}", network.id()); return null; } @@ -357,15 +400,6 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { if (ethernet.getEtherType() == Ethernet.TYPE_ARP) { arpHandler.processPacketIn(pkt); - } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) { - IPv4 ipPacket = (IPv4) ethernet.getPayload(); - - if (ipPacket.getProtocol() == IPv4.PROTOCOL_UDP) { - UDP udpPacket = (UDP) ipPacket.getPayload(); - if (udpPacket.getDestinationPort() == DHCP_PORT) { - dhcpHandler.processPacketIn(pkt); - } - } } } } 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 index 9ead05f0..661a873e 100644 --- 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 @@ -87,7 +87,6 @@ public class OpenstackSwitchingRulePopulator { */ public void populateDefaultRules(DeviceId id) { - //setFlowRuleForDHCP(id); setFlowRuleForArp(id); log.warn("Default rule has been set"); diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java index d97b39c8..3d40d51d 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java @@ -46,4 +46,10 @@ public interface OpenstackSwitchingService { */ void createNetwork(OpenstackNetwork openstackNetwork); + /** + * Store the subnet information created by openstack. + * + * @param openstackSubnet subnet information + */ + void createSubnet(OpenstackSubnet openstackSubnet); } diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java index 43bd1583..fc1509d4 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java @@ -54,6 +54,8 @@ public class OpenstackNetworkCodec extends JsonCodec { .id(id); if (!networkInfo.path(NETWORK_TYPE).isMissingNode()) { + onb.networkType(OpenstackNetwork.NetworkType.valueOf(networkInfo.path(NETWORK_TYPE). + asText().toUpperCase())); onb.name(networkInfo.path(NETWORK_TYPE).asText()); onb.segmentId(networkInfo.path(SEGMENTATION_ID).asText()); } diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java new file mode 100644 index 00000000..a643057a --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.web; + +import com.fasterxml.jackson.databind.JsonNode; + + +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.openstackswitching.OpenstackSubnet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * It encodes and decodes the OpenstackSubnet. + */ + +public class OpenstackSubnetCodec extends JsonCodec { + private static Logger log = LoggerFactory + .getLogger(OpenstackSubnetCodec.class); + + // JSON Field names + private static final String SUBNET = "subnet"; + private static final String NAME = "name"; + private static final String ENABLE_DHCP = "enable_dhcp"; + private static final String NETWORK_ID = "network_id"; + private static final String TENANT_ID = "tenant_id"; + private static final String DNS_NAMESERVERS = "dns_nameservers"; + private static final String GATEWAY_IP = "gateway_ip"; + private static final String CIDR = "cidr"; + private static final String ID = "id"; + + @Override + public OpenstackSubnet decode(ObjectNode json, CodecContext context) { + JsonNode subnetInfo = json.get(SUBNET); + + 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(); + String gatewayIp = subnetInfo.path(GATEWAY_IP).asText(); + String cidr = subnetInfo.path(CIDR).asText(); + String id = subnetInfo.path(ID).asText(); + + OpenstackSubnet openstackSubnet = OpenstackSubnet.builder() + .setName(name) + .setEnableDhcp(enableDhcp) + .setNetworkId(networkId) + .setTenantId(tenantId) + .setDnsNameservers(dnsNameservsers) + .setGatewayIp(gatewayIp) + .setCidr(cidr) + .setId(id) + .build(); + return openstackSubnet; + } +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java new file mode 100644 index 00000000..af1ae9dd --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.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.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; +import org.onosproject.rest.AbstractWebResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +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; + +@Path("subnets") +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); + + 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(); + } + } + +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml index 53b0e2e9..4f50ef72 100644 --- a/framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml +++ b/framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml @@ -31,7 +31,8 @@ com.sun.jersey.config.property.classnames org.onosproject.openstackswitching.web.OpenstackPortWebResource, - org.onosproject.openstackswitching.web.OpenstackNetworkWebResource + org.onosproject.openstackswitching.web.OpenstackNetworkWebResource, + org.onosproject.openstackswitching.web.OpenstackSubnetWebResource 1 diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/Router.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/Router.java new file mode 100644 index 00000000..e853ec2f --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/Router.java @@ -0,0 +1,102 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.List; + +/** + * Representation of a Router. + */ +public interface Router { + + /** + * Coarse classification of the type of the Router. + */ + public enum Status { + /** + * Signifies that a router is currently active. + */ + ACTIVE, + /** + * Signifies that a router is currently inactive. + */ + INACTIVE + } + + /** + * Returns the router identifier. + * + * @return identifier + */ + RouterId id(); + + /** + * Returns the router Name. + * + * @return routerName + */ + String name(); + + /** + * Returns the router admin state. + * + * @return true or false + */ + boolean adminStateUp(); + + /** + * Returns the status of router. + * + * @return RouterStatus + */ + Status status(); + + /** + * Returns the distributed status of this router. + * If true, indicates a distributed router. + * + * @return true or false + */ + boolean distributed(); + + /** + * Returns the RouterGateway of router. + * + * @return routerGateway + */ + RouterGateway externalGatewayInfo(); + + /** + * Returns the gatewayPortid of router. + * + * @return virtualPortId + */ + VirtualPortId gatewayPortid(); + + /** + * Returns the owner(tenant) of this router. + * + * @return tenantId + */ + TenantId tenantId(); + + /** + * Returns the router list of router. + * + * @return routes + */ + List routes(); +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterGateway.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterGateway.java new file mode 100644 index 00000000..9a755561 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterGateway.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; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Collection; +import java.util.Objects; + +/** + * Representation of a Router gateway. + */ +public final class RouterGateway { + + private final TenantNetworkId networkId; + private final boolean enableSnat; + private final Collection externalFixedIps; + + // Public construction is prohibited + private RouterGateway(TenantNetworkId networkId, boolean enableSnat, + Collection externalFixedIps) { + this.networkId = checkNotNull(networkId, "networkId cannot be null"); + this.enableSnat = checkNotNull(enableSnat, "enableSnat cannot be null"); + this.externalFixedIps = checkNotNull(externalFixedIps, "externalFixedIps cannot be null"); + } + + /** + * Creates router gateway object. + * + * @param networkId network identifier + * @param enableSnat SNAT enable or not + * @param externalFixedIps external fixed IP + * @return RouterGateway + */ + public static RouterGateway routerGateway(TenantNetworkId networkId, boolean enableSnat, + Collection externalFixedIps) { + return new RouterGateway(networkId, enableSnat, externalFixedIps); + } + + /** + * Returns network identifier. + * + * @return networkId + */ + public TenantNetworkId networkId() { + return networkId; + } + + /** + * Return SNAT enable or not. + * + * @return enableSnat + */ + public boolean enableSnat() { + return enableSnat; + } + + /** + * Return external fixed Ip. + * + * @return externalFixedIps + */ + public Collection externalFixedIps() { + return externalFixedIps; + } + + @Override + public int hashCode() { + return Objects.hash(networkId, enableSnat, externalFixedIps); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof RouterGateway) { + final RouterGateway that = (RouterGateway) obj; + return Objects.equals(this.networkId, that.networkId) + && Objects.equals(this.enableSnat, that.enableSnat) + && Objects.equals(this.externalFixedIps, that.externalFixedIps); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("networkId", networkId) + .add("enableSnat", enableSnat) + .add("externalFixedIps", externalFixedIps) + .toString(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterId.java new file mode 100644 index 00000000..d396c0d1 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterId.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 static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; + +/** + * Immutable representation of a router identifier. + */ +public final class RouterId { + + private final String routerId; + + // Public construction is prohibited + private RouterId(String routerId) { + checkNotNull(routerId, "routerId cannot be null"); + this.routerId = routerId; + } + + /** + * Creates a router identifier. + * + * @param routerId the router identifier + * @return the router identifier + */ + public static RouterId valueOf(String routerId) { + return new RouterId(routerId); + } + + /** + * Returns the router identifier. + * + * @return the router identifier + */ + public String routerId() { + return routerId; + } + + @Override + public int hashCode() { + return routerId.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof RouterId) { + final RouterId that = (RouterId) obj; + return Objects.equals(this.routerId, that.routerId); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("routerId", routerId).toString(); + } +} + 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 deleted file mode 100644 index e379be81..00000000 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/FlowClassifierService.java +++ /dev/null @@ -1,72 +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.vtnrsc.flowClassifier; - -import org.onosproject.vtnrsc.FlowClassifier; -import org.onosproject.vtnrsc.FlowClassifierId; - -/** - * Provides Services for Flow Classifier. - */ -public interface FlowClassifierService { - - /** - * Store Flow Classifier. - * - * @param flowClassifier Flow Classifier - * @return true if adding Flow Classifier into store is success otherwise return false. - */ - boolean createFlowClassifier(FlowClassifier flowClassifier); - - /** - * Return the existing collection of Flow Classifier. - * - * @return Flow Classifier collections. - */ - Iterable getFlowClassifiers(); - - /** - * Check whether Flow Classifier is present based on given Flow Classifier Id. - * - * @param id Flow Classifier. - * @return true if Flow Classifier is present otherwise return false. - */ - boolean hasFlowClassifier(FlowClassifierId id); - - /** - * Retrieve the Flow Classifier based on given Flow Classifier id. - * - * @param id Flow Classifier Id. - * @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. - */ - 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. - */ - boolean removeFlowClassifier(FlowClassifierId id); -} \ No newline at end of file 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 deleted file mode 100644 index ca01c434..00000000 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/FlowClassifierManager.java +++ /dev/null @@ -1,124 +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.vtnrsc.flowClassifier.impl; - -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.store.serializers.KryoNamespaces; -import org.onosproject.store.service.EventuallyConsistentMap; -import org.onosproject.store.service.MultiValuedTimestamp; -import org.onosproject.store.service.StorageService; -import org.onosproject.store.service.WallClockTimestamp; -import org.onosproject.vtnrsc.FlowClassifierId; -import org.onosproject.vtnrsc.FlowClassifier; -import org.onosproject.vtnrsc.flowClassifier.FlowClassifierService; -import org.slf4j.Logger; - -import static org.slf4j.LoggerFactory.getLogger; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.collect.ImmutableList; - -/** - * Provides implementation of the Flow Classifier Service. - */ -@Component(immediate = true) -@Service -public class FlowClassifierManager implements FlowClassifierService { - - private final Logger log = getLogger(FlowClassifierManager.class); - - private static final String FLOW_CLASSIFIER_NOT_NULL = "Flow Classifier cannot be null"; - private static final String FLOW_CLASSIFIER_ID_NOT_NULL = "Flow Classifier Id cannot be null"; - - private EventuallyConsistentMap flowClassifierStore; - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected StorageService storageService; - - @Activate - private void activate() { - KryoNamespace.Builder serializer = KryoNamespace.newBuilder() - .register(KryoNamespaces.API) - .register(MultiValuedTimestamp.class) - .register(FlowClassifier.class); - flowClassifierStore = storageService - .eventuallyConsistentMapBuilder() - .withName("flowclassifierstore").withSerializer(serializer) - .withTimestampProvider((k, v) -> new WallClockTimestamp()).build(); - log.info("Flow Classifier service activated"); - } - - @Deactivate - private 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; - } - - @Override - public Iterable getFlowClassifiers() { - return ImmutableList.copyOf(flowClassifierStore.values()); - } - - @Override - public boolean hasFlowClassifier(FlowClassifierId id) { - checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); - return flowClassifierStore.containsKey(id); - } - - @Override - public FlowClassifier getFlowClassifier(FlowClassifierId id) { - checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); - return flowClassifierStore.get(id); - } - - @Override - public boolean updateFlowClassifier(FlowClassifier flowClassifier) { - checkNotNull(flowClassifier, FLOW_CLASSIFIER_NOT_NULL); - FlowClassifierId id = flowClassifier.flowClassifierId(); - flowClassifierStore.put(id, flowClassifier); - return true; - } - - @Override - public boolean removeFlowClassifier(FlowClassifierId id) { - checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); - flowClassifierStore.remove(id); - if (flowClassifierStore.containsKey(id)) { - log.debug("The Flow Classifier removal is failed whose identifier is {}", id.toString()); - return false; - } - return true; - } -} \ No newline at end of file diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java deleted file mode 100644 index 4ea050b3..00000000 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java +++ /dev/null @@ -1,20 +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. - */ - -/** - * Provides implementation of the flow Classifier service. - */ -package org.onosproject.vtnrsc.flowClassifier.impl; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java deleted file mode 100644 index 07584170..00000000 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java +++ /dev/null @@ -1,20 +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. - */ - -/** - * Service for interacting with flow Classifier of SFC. - */ -package org.onosproject.vtnrsc.flowClassifier; 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 new file mode 100644 index 00000000..c160d221 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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; + +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.FlowClassifierId; + +/** + * Provides Services for Flow Classifier. + */ +public interface FlowClassifierService { + + /** + * Store Flow Classifier. + * + * @param flowClassifier Flow Classifier + * @return true if adding Flow Classifier into store is success otherwise return false. + */ + boolean createFlowClassifier(FlowClassifier flowClassifier); + + /** + * Return the existing collection of Flow Classifier. + * + * @return Flow Classifier collections. + */ + Iterable getFlowClassifiers(); + + /** + * Check whether Flow Classifier is present based on given Flow Classifier Id. + * + * @param id Flow Classifier. + * @return true if Flow Classifier is present otherwise return false. + */ + boolean hasFlowClassifier(FlowClassifierId id); + + /** + * Retrieve the Flow Classifier based on given Flow Classifier id. + * + * @param id Flow Classifier Id. + * @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. + */ + 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. + */ + 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 new file mode 100644 index 00000000..ee5873d6 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.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.vtnrsc.flowclassifier.impl; + +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.store.serializers.KryoNamespaces; +import org.onosproject.store.service.EventuallyConsistentMap; +import org.onosproject.store.service.MultiValuedTimestamp; +import org.onosproject.store.service.StorageService; +import org.onosproject.store.service.WallClockTimestamp; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; +import org.slf4j.Logger; + +import static org.slf4j.LoggerFactory.getLogger; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.ImmutableList; + +/** + * Provides implementation of the Flow Classifier Service. + */ +@Component(immediate = true) +@Service +public class FlowClassifierManager implements FlowClassifierService { + + private final Logger log = getLogger(FlowClassifierManager.class); + + private static final String FLOW_CLASSIFIER_NOT_NULL = "Flow Classifier cannot be null"; + private static final String FLOW_CLASSIFIER_ID_NOT_NULL = "Flow Classifier Id cannot be null"; + + private EventuallyConsistentMap flowClassifierStore; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + @Activate + private void activate() { + KryoNamespace.Builder serializer = KryoNamespace.newBuilder() + .register(KryoNamespaces.API) + .register(MultiValuedTimestamp.class) + .register(FlowClassifier.class); + flowClassifierStore = storageService + .eventuallyConsistentMapBuilder() + .withName("flowclassifierstore").withSerializer(serializer) + .withTimestampProvider((k, v) -> new WallClockTimestamp()).build(); + log.info("Flow Classifier service activated"); + } + + @Deactivate + private 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; + } + + @Override + public Iterable getFlowClassifiers() { + return ImmutableList.copyOf(flowClassifierStore.values()); + } + + @Override + public boolean hasFlowClassifier(FlowClassifierId id) { + checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); + return flowClassifierStore.containsKey(id); + } + + @Override + public FlowClassifier getFlowClassifier(FlowClassifierId id) { + checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); + return flowClassifierStore.get(id); + } + + @Override + public boolean updateFlowClassifier(FlowClassifier flowClassifier) { + checkNotNull(flowClassifier, FLOW_CLASSIFIER_NOT_NULL); + FlowClassifierId id = flowClassifier.flowClassifierId(); + flowClassifierStore.put(id, flowClassifier); + return true; + } + + @Override + public boolean removeFlowClassifier(FlowClassifierId id) { + checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); + flowClassifierStore.remove(id); + if (flowClassifierStore.containsKey(id)) { + log.debug("The Flow Classifier removal is failed whose identifier is {}", id.toString()); + return false; + } + return true; + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/package-info.java new file mode 100644 index 00000000..62b5603d --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/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 flow Classifier service. + */ +package org.onosproject.vtnrsc.flowclassifier.impl; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/package-info.java new file mode 100644 index 00000000..c8c75bf3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/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 flow Classifier of SFC. + */ +package org.onosproject.vtnrsc.flowclassifier; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portchain/PortChainIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portchain/PortChainIdTest.java index 88fecf8d..a87bdb99 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portchain/PortChainIdTest.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portchain/PortChainIdTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.vtnrsc.portpair; +package org.onosproject.vtnrsc.portchain; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupIdTest.java index 7da4c489..25db9d2e 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupIdTest.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupIdTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.vtnrsc.portpair; +package org.onosproject.vtnrsc.portpairgroup; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterGatewayTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterGatewayTest.java new file mode 100644 index 00000000..ce6b6c00 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterGatewayTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.HashSet; +import java.util.Set; + +import org.junit.Test; +import org.onosproject.vtnrsc.RouterGateway; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.FixedIp; + +import com.google.common.testing.EqualsTester; + +/** + * 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/router/RouterIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterIdTest.java new file mode 100644 index 00000000..3751c11a --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterIdTest.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.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 com.google.common.testing.EqualsTester; + +/** + * 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/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 b5b8252b..7a57c0ab 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 @@ -39,7 +39,7 @@ import javax.ws.rs.core.Response; import org.onosproject.vtnrsc.FlowClassifier; import org.onosproject.vtnrsc.FlowClassifierId; import org.onosproject.rest.AbstractWebResource; -import org.onosproject.vtnrsc.flowClassifier.FlowClassifierService; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; import org.onosproject.vtnweb.web.FlowClassifierCodec; import com.fasterxml.jackson.databind.ObjectMapper; 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 index 572e2aeb..189edb88 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 @@ -16,7 +16,7 @@ package org.onosproject.bgpio.protocol; import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.link_state.BGPNodeLSNlriVer4.PROTOCOLTYPE; +import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSNlriVer4.PROTOCOLTYPE; import org.onosproject.bgpio.types.RouteDistinguisher; /** @@ -51,4 +51,4 @@ public interface BGPLSNlri { * @return Route distinguisher in Nlri */ RouteDistinguisher getRouteDistinguisher(); -} \ 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 index fd5b8056..b6e4a3a0 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,7 +15,7 @@ */ package org.onosproject.bgpio.protocol; -import org.onosproject.bgpio.protocol.link_state.BGPNodeLSIdentifier; +import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSIdentifier; /** * Abstraction of an entity providing BGP-LS Node NLRI. @@ -27,4 +27,4 @@ public interface BGPNodeLSNlri extends BGPLSNlri { * @return local node descriptors */ BGPNodeLSIdentifier getLocalNodeDescriptors(); -} \ No newline at end of file +} 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 index 7e849f48..2c331a2e 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 @@ -18,7 +18,7 @@ package org.onosproject.bgpio.protocol; import java.util.LinkedList; import org.onosproject.bgpio.types.BGPValueType; -import org.onosproject.bgpio.protocol.link_state.NodeDescriptors; +import org.onosproject.bgpio.protocol.linkstate.NodeDescriptors; /** * Abstraction of an entity providing BGP-LS Prefix NLRI. @@ -37,4 +37,4 @@ public interface BGPPrefixLSNlri extends BGPLSNlri { * @return list of Prefix descriptor */ LinkedList getPrefixdescriptor(); -} \ No newline at end of file +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPLinkLSIdentifier.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPLinkLSIdentifier.java deleted file mode 100755 index 3229cc11..00000000 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPLinkLSIdentifier.java +++ /dev/null @@ -1,252 +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.link_state; - -import java.util.Iterator; -import java.util.LinkedList; -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.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.UnSupportedAttribute; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.MoreObjects; -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 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; - - /** - * Initialize fields. - */ - public BGPLinkLSIdentifier() { - this.localNodeDescriptors = null; - this.remoteNodeDescriptors = null; - this.linkDescriptor = null; - } - - /** - * Constructors to initialize parameters. - * - * @param localNodeDescriptors local node descriptors - * @param remoteNodeDescriptors remote node descriptors - * @param linkDescriptor link descriptors - */ - public BGPLinkLSIdentifier(NodeDescriptors localNodeDescriptors, NodeDescriptors remoteNodeDescriptors, - LinkedList linkDescriptor) { - this.localNodeDescriptors = Preconditions.checkNotNull(localNodeDescriptors); - this.remoteNodeDescriptors = Preconditions.checkNotNull(remoteNodeDescriptors); - this.linkDescriptor = Preconditions.checkNotNull(linkDescriptor); - } - - /** - * Reads channel buffer and parses link identifier. - * - * @param cb ChannelBuffer - * @param protocolId in linkstate nlri - * @return object of BGPLinkLSIdentifier - * @throws BGPParseException while parsing link identifier - */ - 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); - - //Parse remote node descriptor - NodeDescriptors remoteNodeDescriptors = new NodeDescriptors(); - remoteNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.REMOTE_NODE_DES_TYPE, protocolId); - - //Parse link descriptor - LinkedList linkDescriptor = new LinkedList<>(); - linkDescriptor = parseLinkDescriptors(cb); - return new BGPLinkLSIdentifier(localNodeDescriptors, remoteNodeDescriptors, linkDescriptor); - } - - /** - * Parses Local/Remote node descriptors. - * - * @param cb ChannelBuffer - * @param desType descriptor type - * @param protocolId protocol identifier - * @return object of NodeDescriptors - * @throws BGPParseException while parsing Local/Remote node descriptors - */ - public static NodeDescriptors parseNodeDescriptors(ChannelBuffer cb, short desType, byte protocolId) - throws BGPParseException { - ChannelBuffer tempBuf = cb; - 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)); - } - NodeDescriptors nodeIdentifier = new NodeDescriptors(); - ChannelBuffer tempCb = cb.readBytes(length); - - if (type == desType) { - nodeIdentifier = NodeDescriptors.read(tempCb, length, desType, protocolId); - } else { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null); - } - return nodeIdentifier; - } - - /** - * Parses link descriptors. - * - * @param cb ChannelBuffer - * @return list of link descriptors - * @throws BGPParseException while parsing link descriptors - */ - 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; - 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)); - } - ChannelBuffer tempCb = cb.readBytes(length); - switch (type) { - case LinkLocalRemoteIdentifiersTlv.TYPE: - tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb); - break; - case IPV4_INTERFACE_ADDRESS_TYPE: - tlv = IPv4AddressTlv.read(tempCb, IPV4_INTERFACE_ADDRESS_TYPE); - break; - case IPV4_NEIGHBOR_ADDRESS_TYPE: - tlv = IPv4AddressTlv.read(tempCb, IPV4_NEIGHBOR_ADDRESS_TYPE); - break; - case IPV6_INTERFACE_ADDRESS_TYPE: - tlv = IPv6AddressTlv.read(tempCb, IPV6_INTERFACE_ADDRESS_TYPE); - break; - case IPV6_NEIGHBOR_ADDRESS_TYPE: - tlv = IPv6AddressTlv.read(tempCb, IPV6_NEIGHBOR_ADDRESS_TYPE); - break; - case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY: - tlv = BgpAttrNodeMultiTopologyId.read(tempCb); - count = count++; - //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)); - } - break; - default: - UnSupportedAttribute.skipBytes(tempCb, length); - } - linkDescriptor.add(tlv); - } - return linkDescriptor; - } - - /** - * Returns local node descriptors. - * - * @return local node descriptors - */ - public NodeDescriptors localNodeDescriptors() { - return this.localNodeDescriptors; - } - - /** - * Returns remote node descriptors. - * - * @return remote node descriptors - */ - public NodeDescriptors remoteNodeDescriptors() { - return this.remoteNodeDescriptors; - } - - /** - * Returns link descriptors. - * - * @return link descriptors - */ - public List linkDescriptors() { - return this.linkDescriptor; - } - - @Override - public int hashCode() { - return Objects.hash(linkDescriptor, localNodeDescriptors, remoteNodeDescriptors); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof BGPLinkLSIdentifier) { - int countObjSubTlv = 0; - int countOtherSubTlv = 0; - boolean isCommonSubTlv = true; - 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)); - } - return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors) - && Objects.equals(this.remoteNodeDescriptors, other.remoteNodeDescriptors); - } - } - return false; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()) - .add("localNodeDescriptors", localNodeDescriptors) - .add("remoteNodeDescriptors", remoteNodeDescriptors) - .add("linkDescriptor", linkDescriptor) - .toString(); - } -} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSIdentifier.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSIdentifier.java deleted file mode 100644 index cd2422a7..00000000 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSIdentifier.java +++ /dev/null @@ -1,113 +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.link_state; - -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.util.Constants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.MoreObjects; - -/** - * Implementation of Node Identifier which includes local node descriptor/remote node descriptors. - */ -public class BGPNodeLSIdentifier { - - protected static final Logger log = LoggerFactory.getLogger(BGPNodeLSIdentifier.class); - private NodeDescriptors nodeDescriptors; - - /** - * Resets fields. - */ - public BGPNodeLSIdentifier() { - this.nodeDescriptors = null; - } - - /** - * Constructor to initialize fields. - * - * @param nodeDescriptors local/remote node descriptor - */ - public BGPNodeLSIdentifier(NodeDescriptors nodeDescriptors) { - this.nodeDescriptors = nodeDescriptors; - } - - /** - * Parse local node descriptors. - * - * @param cb ChannelBuffer - * @param protocolId protocol identifier - * @return object of this BGPNodeLSIdentifier - * @throws BGPParseException while parsing local node descriptors - */ - public static BGPNodeLSIdentifier parseLocalNodeDescriptors(ChannelBuffer cb, byte protocolId) - throws BGPParseException { - ChannelBuffer tempBuf = cb; - 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() + Constants.TYPE_AND_LEN)); - } - NodeDescriptors nodeDescriptors = new NodeDescriptors(); - ChannelBuffer tempCb = cb.readBytes(length); - - 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); - } - return new BGPNodeLSIdentifier(nodeDescriptors); - } - - /** - * Returns node descriptors. - * - * @return node descriptors - */ - public NodeDescriptors getNodedescriptors() { - return this.nodeDescriptors; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof BGPNodeLSIdentifier) { - BGPNodeLSIdentifier other = (BGPNodeLSIdentifier) obj; - return Objects.equals(nodeDescriptors, other.nodeDescriptors); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hash(nodeDescriptors); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()) - .add("NodeDescriptors", nodeDescriptors) - .toString(); - } -} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSNlriVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSNlriVer4.java deleted file mode 100644 index 04780d82..00000000 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSNlriVer4.java +++ /dev/null @@ -1,212 +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.link_state; - -import org.jboss.netty.buffer.ChannelBuffer; -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.RouteDistinguisher; -import org.onosproject.bgpio.util.Constants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.MoreObjects; - -/** - * Implementation of Node LS NLRI. - */ -public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { - - /* - *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) // - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Figure : The Node NLRI format - */ - - 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 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); - int value; - - /** - * Assign val with the value as the protocol type. - * - * @param val protocol type - */ - PROTOCOLTYPE(int val) { - value = val; - } - - /** - * Returns value of protocol type. - * - * @return protocol type - */ - public byte getType() { - return (byte) value; - } - } - - /** - * Reset fields. - */ - public BGPNodeLSNlriVer4() { - this.identifier = 0; - this.protocolId = 0; - this.localNodeDescriptors = null; - this.routeDistinguisher = null; - this.isVpn = false; - } - - /** - * Constructors to initialize its parameters. - * - * @param identifier of LinkState Nlri - * @param protocolId of LinkState Nlri - * @param localNodeDescriptors local node descriptors - * @param isVpn true if VPN info is present - * @param routeDistinguisher unique for each VPN - */ - BGPNodeLSNlriVer4(long identifier, byte protocolId, BGPNodeLSIdentifier localNodeDescriptors, boolean isVpn, - RouteDistinguisher routeDistinguisher) { - this.identifier = identifier; - this.protocolId = protocolId; - this.localNodeDescriptors = localNodeDescriptors; - this.routeDistinguisher = routeDistinguisher; - this.isVpn = isVpn; - } - - /** - * Reads from channelBuffer and parses Node 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 node descriptors - */ - 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)) { - routeDistinguisher = new RouteDistinguisher(); - routeDistinguisher = RouteDistinguisher.read(cb); - isVpn = true; - } else { - isVpn = false; - } - byte protocolId = cb.readByte(); - 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); - } - - @Override - public NlriType getNlriType() { - return NlriType.NODE; - } - - @Override - public BGPNodeLSIdentifier getLocalNodeDescriptors() { - return this.localNodeDescriptors; - } - - /** - * 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; - } - - @Override - public long getIdentifier() { - return this.identifier; - } - - /** - * Set the node LS identifier. - * - * @param localNodeDescriptors node LS identifier to set - */ - public void setNodeLSIdentifier(BGPNodeLSIdentifier localNodeDescriptors) { - this.localNodeDescriptors = localNodeDescriptors; - } - - @Override - public PROTOCOLTYPE getProtocolId() throws BGPParseException { - switch (protocolId) { - case Constants.ISIS_LEVELONE: - return PROTOCOLTYPE.ISIS_LevelOne; - case Constants.ISIS_LEVELTWO: - return PROTOCOLTYPE.ISIS_LevelTwo; - case Constants.OSPFV2: - return PROTOCOLTYPE.OSPFv2; - case Constants.DIRECT: - return PROTOCOLTYPE.Direct; - case Constants.STATIC_CONFIGURATION: - return PROTOCOLTYPE.Static_Configuration; - case Constants.OSPFV3: - return PROTOCOLTYPE.OSPFv3; - default: - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); - } - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()) - .omitNullValues() - .add("protocolId", protocolId) - .add("identifier", identifier) - .add("RouteDistinguisher ", routeDistinguisher) - .add("localNodeDescriptors", localNodeDescriptors) - .toString(); - } -} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixIPv4LSNlriVer4.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixIPv4LSNlriVer4.java deleted file mode 100644 index 0f18c757..00000000 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixIPv4LSNlriVer4.java +++ /dev/null @@ -1,205 +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.link_state; - -import java.util.LinkedList; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.onosproject.bgpio.exceptions.BGPParseException; -import org.onosproject.bgpio.protocol.BGPPrefixLSNlri; -import org.onosproject.bgpio.protocol.NlriType; -import org.onosproject.bgpio.protocol.link_state.BGPNodeLSNlriVer4.PROTOCOLTYPE; -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 Prefix IPV4 LS NLRI. - */ -public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { - - /* - * 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 Descriptor (variable) // - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // Prefix Descriptors (variable) // - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Figure : The IPv4/IPv6 Topology Prefix NLRI format - */ - - protected static final Logger log = LoggerFactory.getLogger(BGPPrefixIPv4LSNlriVer4.class); - - public static final int PREFIX_IPV4_NLRITYPE = 3; - public static final int IDENTIFIER_LENGTH = 16; - private long identifier; - private byte protocolId; - private RouteDistinguisher routeDistinguisher; - private boolean isVpn; - private BGPPrefixLSIdentifier bgpPrefixLSIdentifier; - - /** - * Resets parameters. - */ - public BGPPrefixIPv4LSNlriVer4() { - this.identifier = 0; - this.protocolId = 0; - this.bgpPrefixLSIdentifier = null; - this.routeDistinguisher = null; - this.isVpn = false; - } - - /** - * Constructor to initialize parameters for BGP PrefixLSNlri. - * - * @param identifier field in BGP PrefixLSNlri - * @param protocolId protocol Id - * @param bgpPrefixLSIdentifier prefix LS Identifier - * @param routeDistinguisher RouteDistinguisher - * @param isVpn vpn availability in message - */ - public BGPPrefixIPv4LSNlriVer4(long identifier, byte protocolId, BGPPrefixLSIdentifier bgpPrefixLSIdentifier, - RouteDistinguisher routeDistinguisher, boolean isVpn) { - this.identifier = identifier; - this.protocolId = protocolId; - this.bgpPrefixLSIdentifier = bgpPrefixLSIdentifier; - this.routeDistinguisher = routeDistinguisher; - this.isVpn = isVpn; - } - - /** - * Reads from channelBuffer and parses Prefix LS Nlri. - * - * @param cb ChannelBuffer - * @param afi Address family identifier - * @param safi Subsequent address family identifier - * @return object of BGPPrefixIPv4LSNlriVer4 - * @throws BGPParseException while parsing Prefix LS Nlri - */ - public static BGPPrefixIPv4LSNlriVer4 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(); - - BGPPrefixLSIdentifier bgpPrefixLSIdentifier = new BGPPrefixLSIdentifier(); - bgpPrefixLSIdentifier = BGPPrefixLSIdentifier.parsePrefixIdendifier(cb, protocolId); - return new BGPPrefixIPv4LSNlriVer4(identifier, protocolId, bgpPrefixLSIdentifier, routeDistinguisher, isVpn); - } - - @Override - public NlriType getNlriType() { - return NlriType.PREFIX_IPV4; - } - - @Override - public NodeDescriptors getLocalNodeDescriptors() { - return this.bgpPrefixLSIdentifier.getLocalNodeDescriptors(); - } - - @Override - public long getIdentifier() { - return this.identifier; - } - - /** - * Set the prefix LS identifier. - * - * @param bgpPrefixLSIdentifier prefix identifier to set - */ - public void setPrefixLSIdentifier(BGPPrefixLSIdentifier bgpPrefixLSIdentifier) { - this.bgpPrefixLSIdentifier = bgpPrefixLSIdentifier; - } - - @Override - public PROTOCOLTYPE getProtocolId() throws BGPParseException { - switch (protocolId) { - case Constants.ISIS_LEVELONE: - return PROTOCOLTYPE.ISIS_LevelOne; - case Constants.ISIS_LEVELTWO: - return PROTOCOLTYPE.ISIS_LevelTwo; - case Constants.OSPFV2: - return PROTOCOLTYPE.OSPFv2; - case Constants.DIRECT: - return PROTOCOLTYPE.Direct; - case Constants.STATIC_CONFIGURATION: - return PROTOCOLTYPE.Static_Configuration; - case Constants.OSPFV3: - return PROTOCOLTYPE.OSPFv3; - default: - throw new BGPParseException("protocol id not valid"); - } - } - - /** - * Returns whether VPN is present or not. - * - * @return whether VPN is present or not - */ - public boolean isVpnPresent() { - return this.isVpn; - } - - /** - * Returns Prefix Identifier. - * - * @return Prefix Identifier - */ - public BGPPrefixLSIdentifier getPrefixIdentifier() { - return this.bgpPrefixLSIdentifier; - } - - @Override - public RouteDistinguisher getRouteDistinguisher() { - return this.routeDistinguisher; - } - - @Override - public LinkedList getPrefixdescriptor() { - return this.bgpPrefixLSIdentifier.getPrefixdescriptor(); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()) - .omitNullValues() - .add("protocolId", protocolId) - .add("identifier", identifier) - .add("RouteDistinguisher ", routeDistinguisher) - .add("bgpPrefixLSIdentifier", bgpPrefixLSIdentifier) - .toString(); - } -} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixLSIdentifier.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixLSIdentifier.java deleted file mode 100644 index 4fef47ff..00000000 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixLSIdentifier.java +++ /dev/null @@ -1,228 +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.link_state; - -import java.util.Iterator; -import java.util.LinkedList; -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.types.IPReachabilityInformationTlv; -import org.onosproject.bgpio.types.OSPFRouteTypeTlv; -import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId; -import org.onosproject.bgpio.util.UnSupportedAttribute; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.MoreObjects; - -/** - * Provides Implementation of Local node descriptors and prefix descriptors. - */ -public class BGPPrefixLSIdentifier { - - protected static final Logger log = LoggerFactory.getLogger(BGPPrefixLSIdentifier.class); - public static final int TYPE_AND_LEN = 4; - private NodeDescriptors localNodeDescriptors; - private LinkedList prefixDescriptor; - - /** - * Resets parameters. - */ - public BGPPrefixLSIdentifier() { - this.localNodeDescriptors = null; - this.prefixDescriptor = null; - } - - /** - * Constructor to initialize parameters. - * - * @param localNodeDescriptors Local node descriptors - * @param prefixDescriptor Prefix Descriptors - */ - public BGPPrefixLSIdentifier(NodeDescriptors localNodeDescriptors, LinkedList prefixDescriptor) { - this.localNodeDescriptors = localNodeDescriptors; - this.prefixDescriptor = prefixDescriptor; - } - - /** - * Reads the channel buffer and parses Prefix Identifier. - * - * @param cb ChannelBuffer - * @param protocolId protocol ID - * @return object of this class - * @throws BGPParseException while parsing Prefix Identifier - */ - 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<>(); - prefixDescriptor = parsePrefixDescriptors(cb); - return new BGPPrefixLSIdentifier(localNodeDescriptors, prefixDescriptor); - } - - /** - * Parse local node descriptors. - * - * @param cb ChannelBuffer - * @param protocolId protocol identifier - * @return LocalNodeDescriptors - * @throws BGPParseException while parsing local node descriptors - */ - public static NodeDescriptors parseLocalNodeDescriptors(ChannelBuffer cb, byte protocolId) - throws BGPParseException { - ChannelBuffer tempBuf = cb; - 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, - tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); - } - NodeDescriptors localNodeDescriptors = new NodeDescriptors(); - ChannelBuffer tempCb = cb.readBytes(length); - - 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); - } - return localNodeDescriptors; - } - - /** - * Parse list of prefix descriptors. - * - * @param cb ChannelBuffer - * @return 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; - boolean isIpReachInfo = false; - ChannelBuffer tempCb; - int count = 0; - - while (cb.readableBytes() > 0) { - ChannelBuffer tempBuf = cb; - 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, - tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); - } - tempCb = cb.readBytes(length); - switch (type) { - case OSPFRouteTypeTlv.TYPE: - tlv = OSPFRouteTypeTlv.read(tempCb); - break; - case IPReachabilityInformationTlv.TYPE: - tlv = IPReachabilityInformationTlv.read(tempCb, length); - isIpReachInfo = true; - break; - case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY: - tlv = BgpAttrNodeMultiTopologyId.read(tempCb); - 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)); - } - break; - default: - UnSupportedAttribute.skipBytes(tempCb, length); - } - prefixDescriptor.add(tlv); - } - - if (!isIpReachInfo) { - throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, - null); - } - return prefixDescriptor; - } - - /** - * Returns local node descriptors. - * - * @return local node descriptors - */ - public NodeDescriptors getLocalNodeDescriptors() { - return this.localNodeDescriptors; - } - - /** - * Returns Prefix descriptors. - * - * @return Prefix descriptors - */ - public LinkedList getPrefixdescriptor() { - return this.prefixDescriptor; - } - - @Override - public int hashCode() { - return Objects.hash(prefixDescriptor.hashCode(), localNodeDescriptors); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj instanceof BGPPrefixLSIdentifier) { - int countObjSubTlv = 0; - int countOtherSubTlv = 0; - boolean isCommonSubTlv = true; - BGPPrefixLSIdentifier other = (BGPPrefixLSIdentifier) obj; - - 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)); - } - return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors); - } - } - return false; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()) - .add("localNodeDescriptors", localNodeDescriptors) - .add("prefixDescriptor", prefixDescriptor) - .toString(); - } -} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/NodeDescriptors.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/NodeDescriptors.java deleted file mode 100644 index a03b2bae..00000000 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/NodeDescriptors.java +++ /dev/null @@ -1,225 +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.link_state; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Objects; - -import org.jboss.netty.buffer.ChannelBuffer; -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.IsIsNonPseudonode; -import org.onosproject.bgpio.types.IsIsPseudonode; -import org.onosproject.bgpio.types.OSPFNonPseudonode; -import org.onosproject.bgpio.types.OSPFPseudonode; -import org.onosproject.bgpio.util.UnSupportedAttribute; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.MoreObjects; - -/** - * Provides Local and Remote NodeDescriptors which contains Node Descriptor Sub-TLVs. - */ -public class NodeDescriptors { - - /* - *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 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Type | Length | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - // Node Descriptor Sub-TLVs (variable) // - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Figure : Local or Remote Node Descriptors TLV format - */ - - protected 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; - public static final short IGP_ROUTERID_TYPE = 515; - public static final short IS_IS_LEVEL_1_PROTOCOL_ID = 1; - public static final short IS_IS_LEVEL_2_PROTOCOL_ID = 2; - public static final short OSPF_V2_PROTOCOL_ID = 3; - public static final short OSPF_V3_PROTOCOL_ID = 6; - public static final int TYPE_AND_LEN = 4; - public static final int ISISNONPSEUDONODE_LEN = 6; - 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 short deslength; - private short desType; - - /** - * Resets parameters. - */ - public NodeDescriptors() { - this.subTlvs = null; - this.deslength = 0; - this.desType = 0; - } - - /** - * Constructor to initialize parameters. - * - * @param subTlvs list of subTlvs - * @param deslength Descriptors length - * @param desType local node descriptor or remote node descriptor type - */ - public NodeDescriptors(LinkedList subTlvs, short deslength, short desType) { - this.subTlvs = subTlvs; - this.deslength = deslength; - this.desType = desType; - } - - /** - * Returns list of subTlvs. - * - * @return subTlvs list of subTlvs - */ - public LinkedList getSubTlvs() { - return subTlvs; - } - - @Override - public int hashCode() { - return Objects.hash(subTlvs.hashCode()); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj instanceof NodeDescriptors) { - int countObjSubTlv = 0; - int countOtherSubTlv = 0; - boolean isCommonSubTlv = true; - NodeDescriptors other = (NodeDescriptors) obj; - 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)); - } - return isCommonSubTlv; - } - } - return false; - } - - /** - * Reads node descriptors Sub-TLVs. - * - * @param cb ChannelBuffer - * @param desLength node descriptor length - * @param desType local node descriptor or remote node descriptor type - * @param protocolId protocol ID - * @return object of NodeDescriptors - * @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; - - while (cb.readableBytes() > 0) { - ChannelBuffer tempBuf = cb; - 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)); - } - ChannelBuffer tempCb = cb.readBytes(length); - switch (type) { - case AutonomousSystemTlv.TYPE: - tlv = AutonomousSystemTlv.read(tempCb); - break; - case BGPLSIdentifierTlv.TYPE: - tlv = BGPLSIdentifierTlv.read(tempCb); - break; - case AreaIDTlv.TYPE: - tlv = AreaIDTlv.read(tempCb); - break; - case IGP_ROUTERID_TYPE: - if (protocolId == IS_IS_LEVEL_1_PROTOCOL_ID || protocolId == IS_IS_LEVEL_2_PROTOCOL_ID) { - if (length == ISISNONPSEUDONODE_LEN) { - tlv = IsIsNonPseudonode.read(tempCb); - } else if (length == ISISPSEUDONODE_LEN) { - tlv = IsIsPseudonode.read(tempCb); - } - } else if (protocolId == OSPF_V2_PROTOCOL_ID || protocolId == OSPF_V3_PROTOCOL_ID) { - if (length == OSPFNONPSEUDONODE_LEN) { - tlv = OSPFNonPseudonode.read(tempCb); - } else if (length == OSPFPSEUDONODE_LEN) { - tlv = OSPFPseudonode.read(tempCb); - } - } - break; - default: - UnSupportedAttribute.skipBytes(tempCb, length); - } - subTlvs.add(tlv); - } - return new NodeDescriptors(subTlvs, desLength, desType); - } - - /** - * Returns node descriptors length. - * - * @return node descriptors length - */ - public short getLength() { - return this.deslength; - } - - /** - * Returns node descriptors type. - * - * @return node descriptors type - */ - public short getType() { - return this.desType; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()) - .add("desType", desType) - .add("deslength", deslength) - .add("subTlvs", subTlvs) - .toString(); - } -} \ No newline at end of file diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/package-info.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/package-info.java deleted file mode 100755 index d2a2ccf3..00000000 --- a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/package-info.java +++ /dev/null @@ -1,20 +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. - */ - -/** - * BGP Protocol specific link state details. - */ -package org.onosproject.bgpio.protocol.link_state; \ 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 new file mode 100755 index 00000000..ffea74db --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPLinkLSIdentifier.java @@ -0,0 +1,252 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.LinkedList; +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.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.UnSupportedAttribute; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; +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 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; + + /** + * Initialize fields. + */ + public BGPLinkLSIdentifier() { + this.localNodeDescriptors = null; + this.remoteNodeDescriptors = null; + this.linkDescriptor = null; + } + + /** + * Constructors to initialize parameters. + * + * @param localNodeDescriptors local node descriptors + * @param remoteNodeDescriptors remote node descriptors + * @param linkDescriptor link descriptors + */ + public BGPLinkLSIdentifier(NodeDescriptors localNodeDescriptors, NodeDescriptors remoteNodeDescriptors, + LinkedList linkDescriptor) { + this.localNodeDescriptors = Preconditions.checkNotNull(localNodeDescriptors); + this.remoteNodeDescriptors = Preconditions.checkNotNull(remoteNodeDescriptors); + this.linkDescriptor = Preconditions.checkNotNull(linkDescriptor); + } + + /** + * Reads channel buffer and parses link identifier. + * + * @param cb ChannelBuffer + * @param protocolId in linkstate nlri + * @return object of BGPLinkLSIdentifier + * @throws BGPParseException while parsing link identifier + */ + 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); + + //Parse remote node descriptor + NodeDescriptors remoteNodeDescriptors = new NodeDescriptors(); + remoteNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.REMOTE_NODE_DES_TYPE, protocolId); + + //Parse link descriptor + LinkedList linkDescriptor = new LinkedList<>(); + linkDescriptor = parseLinkDescriptors(cb); + return new BGPLinkLSIdentifier(localNodeDescriptors, remoteNodeDescriptors, linkDescriptor); + } + + /** + * Parses Local/Remote node descriptors. + * + * @param cb ChannelBuffer + * @param desType descriptor type + * @param protocolId protocol identifier + * @return object of NodeDescriptors + * @throws BGPParseException while parsing Local/Remote node descriptors + */ + public static NodeDescriptors parseNodeDescriptors(ChannelBuffer cb, short desType, byte protocolId) + throws BGPParseException { + ChannelBuffer tempBuf = cb; + 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)); + } + NodeDescriptors nodeIdentifier = new NodeDescriptors(); + ChannelBuffer tempCb = cb.readBytes(length); + + if (type == desType) { + nodeIdentifier = NodeDescriptors.read(tempCb, length, desType, protocolId); + } else { + throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null); + } + return nodeIdentifier; + } + + /** + * Parses link descriptors. + * + * @param cb ChannelBuffer + * @return list of link descriptors + * @throws BGPParseException while parsing link descriptors + */ + 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; + 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)); + } + ChannelBuffer tempCb = cb.readBytes(length); + switch (type) { + case LinkLocalRemoteIdentifiersTlv.TYPE: + tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb); + break; + case IPV4_INTERFACE_ADDRESS_TYPE: + tlv = IPv4AddressTlv.read(tempCb, IPV4_INTERFACE_ADDRESS_TYPE); + break; + case IPV4_NEIGHBOR_ADDRESS_TYPE: + tlv = IPv4AddressTlv.read(tempCb, IPV4_NEIGHBOR_ADDRESS_TYPE); + break; + case IPV6_INTERFACE_ADDRESS_TYPE: + tlv = IPv6AddressTlv.read(tempCb, IPV6_INTERFACE_ADDRESS_TYPE); + break; + case IPV6_NEIGHBOR_ADDRESS_TYPE: + tlv = IPv6AddressTlv.read(tempCb, IPV6_NEIGHBOR_ADDRESS_TYPE); + break; + case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY: + tlv = BgpAttrNodeMultiTopologyId.read(tempCb); + count = count++; + //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)); + } + break; + default: + UnSupportedAttribute.skipBytes(tempCb, length); + } + linkDescriptor.add(tlv); + } + return linkDescriptor; + } + + /** + * Returns local node descriptors. + * + * @return local node descriptors + */ + public NodeDescriptors localNodeDescriptors() { + return this.localNodeDescriptors; + } + + /** + * Returns remote node descriptors. + * + * @return remote node descriptors + */ + public NodeDescriptors remoteNodeDescriptors() { + return this.remoteNodeDescriptors; + } + + /** + * Returns link descriptors. + * + * @return link descriptors + */ + public List linkDescriptors() { + return this.linkDescriptor; + } + + @Override + public int hashCode() { + return Objects.hash(linkDescriptor, localNodeDescriptors, remoteNodeDescriptors); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof BGPLinkLSIdentifier) { + int countObjSubTlv = 0; + int countOtherSubTlv = 0; + boolean isCommonSubTlv = true; + 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)); + } + return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors) + && Objects.equals(this.remoteNodeDescriptors, other.remoteNodeDescriptors); + } + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("localNodeDescriptors", localNodeDescriptors) + .add("remoteNodeDescriptors", remoteNodeDescriptors) + .add("linkDescriptor", linkDescriptor) + .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 new file mode 100644 index 00000000..603bf6ec --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSIdentifier.java @@ -0,0 +1,113 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.jboss.netty.buffer.ChannelBuffer; +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; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of Node Identifier which includes local node descriptor/remote node descriptors. + */ +public class BGPNodeLSIdentifier { + + protected static final Logger log = LoggerFactory.getLogger(BGPNodeLSIdentifier.class); + private NodeDescriptors nodeDescriptors; + + /** + * Resets fields. + */ + public BGPNodeLSIdentifier() { + this.nodeDescriptors = null; + } + + /** + * Constructor to initialize fields. + * + * @param nodeDescriptors local/remote node descriptor + */ + public BGPNodeLSIdentifier(NodeDescriptors nodeDescriptors) { + this.nodeDescriptors = nodeDescriptors; + } + + /** + * Parse local node descriptors. + * + * @param cb ChannelBuffer + * @param protocolId protocol identifier + * @return object of this BGPNodeLSIdentifier + * @throws BGPParseException while parsing local node descriptors + */ + public static BGPNodeLSIdentifier parseLocalNodeDescriptors(ChannelBuffer cb, byte protocolId) + throws BGPParseException { + ChannelBuffer tempBuf = cb; + 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() + Constants.TYPE_AND_LEN)); + } + NodeDescriptors nodeDescriptors = new NodeDescriptors(); + ChannelBuffer tempCb = cb.readBytes(length); + + 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); + } + return new BGPNodeLSIdentifier(nodeDescriptors); + } + + /** + * Returns node descriptors. + * + * @return node descriptors + */ + public NodeDescriptors getNodedescriptors() { + return this.nodeDescriptors; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof BGPNodeLSIdentifier) { + BGPNodeLSIdentifier other = (BGPNodeLSIdentifier) obj; + return Objects.equals(nodeDescriptors, other.nodeDescriptors); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(nodeDescriptors); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("NodeDescriptors", nodeDescriptors) + .toString(); + } +} 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 new file mode 100644 index 00000000..54837ee8 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSNlriVer4.java @@ -0,0 +1,212 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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 org.jboss.netty.buffer.ChannelBuffer; +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.RouteDistinguisher; +import org.onosproject.bgpio.util.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of Node LS NLRI. + */ +public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri { + + /* + *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) // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure : The Node NLRI format + */ + + 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 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); + int value; + + /** + * Assign val with the value as the protocol type. + * + * @param val protocol type + */ + PROTOCOLTYPE(int val) { + value = val; + } + + /** + * Returns value of protocol type. + * + * @return protocol type + */ + public byte getType() { + return (byte) value; + } + } + + /** + * Reset fields. + */ + public BGPNodeLSNlriVer4() { + this.identifier = 0; + this.protocolId = 0; + this.localNodeDescriptors = null; + this.routeDistinguisher = null; + this.isVpn = false; + } + + /** + * Constructors to initialize its parameters. + * + * @param identifier of LinkState Nlri + * @param protocolId of LinkState Nlri + * @param localNodeDescriptors local node descriptors + * @param isVpn true if VPN info is present + * @param routeDistinguisher unique for each VPN + */ + BGPNodeLSNlriVer4(long identifier, byte protocolId, BGPNodeLSIdentifier localNodeDescriptors, boolean isVpn, + RouteDistinguisher routeDistinguisher) { + this.identifier = identifier; + this.protocolId = protocolId; + this.localNodeDescriptors = localNodeDescriptors; + this.routeDistinguisher = routeDistinguisher; + this.isVpn = isVpn; + } + + /** + * Reads from channelBuffer and parses Node 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 node descriptors + */ + 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)) { + routeDistinguisher = new RouteDistinguisher(); + routeDistinguisher = RouteDistinguisher.read(cb); + isVpn = true; + } else { + isVpn = false; + } + byte protocolId = cb.readByte(); + 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); + } + + @Override + public NlriType getNlriType() { + return NlriType.NODE; + } + + @Override + public BGPNodeLSIdentifier getLocalNodeDescriptors() { + return this.localNodeDescriptors; + } + + /** + * 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; + } + + @Override + public long getIdentifier() { + return this.identifier; + } + + /** + * Set the node LS identifier. + * + * @param localNodeDescriptors node LS identifier to set + */ + public void setNodeLSIdentifier(BGPNodeLSIdentifier localNodeDescriptors) { + this.localNodeDescriptors = localNodeDescriptors; + } + + @Override + public PROTOCOLTYPE getProtocolId() throws BGPParseException { + switch (protocolId) { + case Constants.ISIS_LEVELONE: + return PROTOCOLTYPE.ISIS_LevelOne; + case Constants.ISIS_LEVELTWO: + return PROTOCOLTYPE.ISIS_LevelTwo; + case Constants.OSPFV2: + return PROTOCOLTYPE.OSPFv2; + case Constants.DIRECT: + return PROTOCOLTYPE.Direct; + case Constants.STATIC_CONFIGURATION: + return PROTOCOLTYPE.Static_Configuration; + case Constants.OSPFV3: + return PROTOCOLTYPE.OSPFv3; + default: + throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null); + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues() + .add("protocolId", protocolId) + .add("identifier", identifier) + .add("RouteDistinguisher ", routeDistinguisher) + .add("localNodeDescriptors", localNodeDescriptors) + .toString(); + } +} 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 new file mode 100644 index 00000000..6d6f48b1 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixIPv4LSNlriVer4.java @@ -0,0 +1,205 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.LinkedList; + +import org.jboss.netty.buffer.ChannelBuffer; +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.types.RouteDistinguisher; +import org.onosproject.bgpio.util.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of Prefix IPV4 LS NLRI. + */ +public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri { + + /* + * 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 Descriptor (variable) // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Prefix Descriptors (variable) // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure : The IPv4/IPv6 Topology Prefix NLRI format + */ + + protected static final Logger log = LoggerFactory.getLogger(BGPPrefixIPv4LSNlriVer4.class); + + public static final int PREFIX_IPV4_NLRITYPE = 3; + public static final int IDENTIFIER_LENGTH = 16; + private long identifier; + private byte protocolId; + private RouteDistinguisher routeDistinguisher; + private boolean isVpn; + private BGPPrefixLSIdentifier bgpPrefixLSIdentifier; + + /** + * Resets parameters. + */ + public BGPPrefixIPv4LSNlriVer4() { + this.identifier = 0; + this.protocolId = 0; + this.bgpPrefixLSIdentifier = null; + this.routeDistinguisher = null; + this.isVpn = false; + } + + /** + * Constructor to initialize parameters for BGP PrefixLSNlri. + * + * @param identifier field in BGP PrefixLSNlri + * @param protocolId protocol Id + * @param bgpPrefixLSIdentifier prefix LS Identifier + * @param routeDistinguisher RouteDistinguisher + * @param isVpn vpn availability in message + */ + public BGPPrefixIPv4LSNlriVer4(long identifier, byte protocolId, BGPPrefixLSIdentifier bgpPrefixLSIdentifier, + RouteDistinguisher routeDistinguisher, boolean isVpn) { + this.identifier = identifier; + this.protocolId = protocolId; + this.bgpPrefixLSIdentifier = bgpPrefixLSIdentifier; + this.routeDistinguisher = routeDistinguisher; + this.isVpn = isVpn; + } + + /** + * Reads from channelBuffer and parses Prefix LS Nlri. + * + * @param cb ChannelBuffer + * @param afi Address family identifier + * @param safi Subsequent address family identifier + * @return object of BGPPrefixIPv4LSNlriVer4 + * @throws BGPParseException while parsing Prefix LS Nlri + */ + public static BGPPrefixIPv4LSNlriVer4 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(); + + BGPPrefixLSIdentifier bgpPrefixLSIdentifier = new BGPPrefixLSIdentifier(); + bgpPrefixLSIdentifier = BGPPrefixLSIdentifier.parsePrefixIdendifier(cb, protocolId); + return new BGPPrefixIPv4LSNlriVer4(identifier, protocolId, bgpPrefixLSIdentifier, routeDistinguisher, isVpn); + } + + @Override + public NlriType getNlriType() { + return NlriType.PREFIX_IPV4; + } + + @Override + public NodeDescriptors getLocalNodeDescriptors() { + return this.bgpPrefixLSIdentifier.getLocalNodeDescriptors(); + } + + @Override + public long getIdentifier() { + return this.identifier; + } + + /** + * Set the prefix LS identifier. + * + * @param bgpPrefixLSIdentifier prefix identifier to set + */ + public void setPrefixLSIdentifier(BGPPrefixLSIdentifier bgpPrefixLSIdentifier) { + this.bgpPrefixLSIdentifier = bgpPrefixLSIdentifier; + } + + @Override + public PROTOCOLTYPE getProtocolId() throws BGPParseException { + switch (protocolId) { + case Constants.ISIS_LEVELONE: + return PROTOCOLTYPE.ISIS_LevelOne; + case Constants.ISIS_LEVELTWO: + return PROTOCOLTYPE.ISIS_LevelTwo; + case Constants.OSPFV2: + return PROTOCOLTYPE.OSPFv2; + case Constants.DIRECT: + return PROTOCOLTYPE.Direct; + case Constants.STATIC_CONFIGURATION: + return PROTOCOLTYPE.Static_Configuration; + case Constants.OSPFV3: + return PROTOCOLTYPE.OSPFv3; + default: + throw new BGPParseException("protocol id not valid"); + } + } + + /** + * Returns whether VPN is present or not. + * + * @return whether VPN is present or not + */ + public boolean isVpnPresent() { + return this.isVpn; + } + + /** + * Returns Prefix Identifier. + * + * @return Prefix Identifier + */ + public BGPPrefixLSIdentifier getPrefixIdentifier() { + return this.bgpPrefixLSIdentifier; + } + + @Override + public RouteDistinguisher getRouteDistinguisher() { + return this.routeDistinguisher; + } + + @Override + public LinkedList getPrefixdescriptor() { + return this.bgpPrefixLSIdentifier.getPrefixdescriptor(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .omitNullValues() + .add("protocolId", protocolId) + .add("identifier", identifier) + .add("RouteDistinguisher ", routeDistinguisher) + .add("bgpPrefixLSIdentifier", bgpPrefixLSIdentifier) + .toString(); + } +} 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 new file mode 100644 index 00000000..23f41794 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixLSIdentifier.java @@ -0,0 +1,228 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.LinkedList; +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.types.IPReachabilityInformationTlv; +import org.onosproject.bgpio.types.OSPFRouteTypeTlv; +import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId; +import org.onosproject.bgpio.util.UnSupportedAttribute; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides Implementation of Local node descriptors and prefix descriptors. + */ +public class BGPPrefixLSIdentifier { + + protected static final Logger log = LoggerFactory.getLogger(BGPPrefixLSIdentifier.class); + public static final int TYPE_AND_LEN = 4; + private NodeDescriptors localNodeDescriptors; + private LinkedList prefixDescriptor; + + /** + * Resets parameters. + */ + public BGPPrefixLSIdentifier() { + this.localNodeDescriptors = null; + this.prefixDescriptor = null; + } + + /** + * Constructor to initialize parameters. + * + * @param localNodeDescriptors Local node descriptors + * @param prefixDescriptor Prefix Descriptors + */ + public BGPPrefixLSIdentifier(NodeDescriptors localNodeDescriptors, LinkedList prefixDescriptor) { + this.localNodeDescriptors = localNodeDescriptors; + this.prefixDescriptor = prefixDescriptor; + } + + /** + * Reads the channel buffer and parses Prefix Identifier. + * + * @param cb ChannelBuffer + * @param protocolId protocol ID + * @return object of this class + * @throws BGPParseException while parsing Prefix Identifier + */ + 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<>(); + prefixDescriptor = parsePrefixDescriptors(cb); + return new BGPPrefixLSIdentifier(localNodeDescriptors, prefixDescriptor); + } + + /** + * Parse local node descriptors. + * + * @param cb ChannelBuffer + * @param protocolId protocol identifier + * @return LocalNodeDescriptors + * @throws BGPParseException while parsing local node descriptors + */ + public static NodeDescriptors parseLocalNodeDescriptors(ChannelBuffer cb, byte protocolId) + throws BGPParseException { + ChannelBuffer tempBuf = cb; + 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, + tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); + } + NodeDescriptors localNodeDescriptors = new NodeDescriptors(); + ChannelBuffer tempCb = cb.readBytes(length); + + 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); + } + return localNodeDescriptors; + } + + /** + * Parse list of prefix descriptors. + * + * @param cb ChannelBuffer + * @return 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; + boolean isIpReachInfo = false; + ChannelBuffer tempCb; + int count = 0; + + while (cb.readableBytes() > 0) { + ChannelBuffer tempBuf = cb; + 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, + tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); + } + tempCb = cb.readBytes(length); + switch (type) { + case OSPFRouteTypeTlv.TYPE: + tlv = OSPFRouteTypeTlv.read(tempCb); + break; + case IPReachabilityInformationTlv.TYPE: + tlv = IPReachabilityInformationTlv.read(tempCb, length); + isIpReachInfo = true; + break; + case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY: + tlv = BgpAttrNodeMultiTopologyId.read(tempCb); + 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)); + } + break; + default: + UnSupportedAttribute.skipBytes(tempCb, length); + } + prefixDescriptor.add(tlv); + } + + if (!isIpReachInfo) { + throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, + null); + } + return prefixDescriptor; + } + + /** + * Returns local node descriptors. + * + * @return local node descriptors + */ + public NodeDescriptors getLocalNodeDescriptors() { + return this.localNodeDescriptors; + } + + /** + * Returns Prefix descriptors. + * + * @return Prefix descriptors + */ + public LinkedList getPrefixdescriptor() { + return this.prefixDescriptor; + } + + @Override + public int hashCode() { + return Objects.hash(prefixDescriptor.hashCode(), localNodeDescriptors); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BGPPrefixLSIdentifier) { + int countObjSubTlv = 0; + int countOtherSubTlv = 0; + boolean isCommonSubTlv = true; + BGPPrefixLSIdentifier other = (BGPPrefixLSIdentifier) obj; + + 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)); + } + return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors); + } + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("localNodeDescriptors", localNodeDescriptors) + .add("prefixDescriptor", prefixDescriptor) + .toString(); + } +} 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 new file mode 100644 index 00000000..74637c7e --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/NodeDescriptors.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.bgpio.protocol.linkstate; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Objects; + +import org.jboss.netty.buffer.ChannelBuffer; +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.IsIsNonPseudonode; +import org.onosproject.bgpio.types.IsIsPseudonode; +import org.onosproject.bgpio.types.OSPFNonPseudonode; +import org.onosproject.bgpio.types.OSPFPseudonode; +import org.onosproject.bgpio.util.UnSupportedAttribute; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Provides Local and Remote NodeDescriptors which contains Node Descriptor Sub-TLVs. + */ +public class NodeDescriptors { + + /* + *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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + // Node Descriptor Sub-TLVs (variable) // + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure : Local or Remote Node Descriptors TLV format + */ + + protected 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; + public static final short IGP_ROUTERID_TYPE = 515; + public static final short IS_IS_LEVEL_1_PROTOCOL_ID = 1; + public static final short IS_IS_LEVEL_2_PROTOCOL_ID = 2; + public static final short OSPF_V2_PROTOCOL_ID = 3; + public static final short OSPF_V3_PROTOCOL_ID = 6; + public static final int TYPE_AND_LEN = 4; + public static final int ISISNONPSEUDONODE_LEN = 6; + 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 short deslength; + private short desType; + + /** + * Resets parameters. + */ + public NodeDescriptors() { + this.subTlvs = null; + this.deslength = 0; + this.desType = 0; + } + + /** + * Constructor to initialize parameters. + * + * @param subTlvs list of subTlvs + * @param deslength Descriptors length + * @param desType local node descriptor or remote node descriptor type + */ + public NodeDescriptors(LinkedList subTlvs, short deslength, short desType) { + this.subTlvs = subTlvs; + this.deslength = deslength; + this.desType = desType; + } + + /** + * Returns list of subTlvs. + * + * @return subTlvs list of subTlvs + */ + public LinkedList getSubTlvs() { + return subTlvs; + } + + @Override + public int hashCode() { + return Objects.hash(subTlvs.hashCode()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof NodeDescriptors) { + int countObjSubTlv = 0; + int countOtherSubTlv = 0; + boolean isCommonSubTlv = true; + NodeDescriptors other = (NodeDescriptors) obj; + 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)); + } + return isCommonSubTlv; + } + } + return false; + } + + /** + * Reads node descriptors Sub-TLVs. + * + * @param cb ChannelBuffer + * @param desLength node descriptor length + * @param desType local node descriptor or remote node descriptor type + * @param protocolId protocol ID + * @return object of NodeDescriptors + * @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; + + while (cb.readableBytes() > 0) { + ChannelBuffer tempBuf = cb; + 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)); + } + ChannelBuffer tempCb = cb.readBytes(length); + switch (type) { + case AutonomousSystemTlv.TYPE: + tlv = AutonomousSystemTlv.read(tempCb); + break; + case BGPLSIdentifierTlv.TYPE: + tlv = BGPLSIdentifierTlv.read(tempCb); + break; + case AreaIDTlv.TYPE: + tlv = AreaIDTlv.read(tempCb); + break; + case IGP_ROUTERID_TYPE: + if (protocolId == IS_IS_LEVEL_1_PROTOCOL_ID || protocolId == IS_IS_LEVEL_2_PROTOCOL_ID) { + if (length == ISISNONPSEUDONODE_LEN) { + tlv = IsIsNonPseudonode.read(tempCb); + } else if (length == ISISPSEUDONODE_LEN) { + tlv = IsIsPseudonode.read(tempCb); + } + } else if (protocolId == OSPF_V2_PROTOCOL_ID || protocolId == OSPF_V3_PROTOCOL_ID) { + if (length == OSPFNONPSEUDONODE_LEN) { + tlv = OSPFNonPseudonode.read(tempCb); + } else if (length == OSPFPSEUDONODE_LEN) { + tlv = OSPFPseudonode.read(tempCb); + } + } + break; + default: + UnSupportedAttribute.skipBytes(tempCb, length); + } + subTlvs.add(tlv); + } + return new NodeDescriptors(subTlvs, desLength, desType); + } + + /** + * Returns node descriptors length. + * + * @return node descriptors length + */ + public short getLength() { + return this.deslength; + } + + /** + * Returns node descriptors type. + * + * @return node descriptors type + */ + public short getType() { + return this.desType; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("desType", desType) + .add("deslength", deslength) + .add("subTlvs", subTlvs) + .toString(); + } +} diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/package-info.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/package-info.java new file mode 100755 index 00000000..87ba60f0 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/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. + */ + +/** + * BGP Protocol specific link state details. + */ +package org.onosproject.bgpio.protocol.linkstate; 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 new file mode 100755 index 00000000..7febe3c3 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetric.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.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.util.Validation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.MoreObjects; + +/** + * Implements BGP link state Default TE metric link attribute. + */ +public class BgpLinkAttrTeDefaultMetric implements BGPValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpLinkAttrTeDefaultMetric.class); + + public static final int ATTRLINK_TEDEFAULTMETRIC = 1092; + public static final int TE_DATA_LEN = 4; + + /* TE Default Metric */ + private int linkTeMetric; + + /** + * Constructor to initialize the value. + * + * @param linkTeMetric TE default metric + * + */ + public BgpLinkAttrTeDefaultMetric(int linkTeMetric) { + this.linkTeMetric = linkTeMetric; + } + + /** + * Returns object of this class with specified values. + * + * @param linkTeMetric TE default metric + * @return object of BgpLinkAttrTeDefaultMetric + */ + public static BgpLinkAttrTeDefaultMetric of(final int linkTeMetric) { + return new BgpLinkAttrTeDefaultMetric(linkTeMetric); + } + + /** + * Reads the BGP link attributes of TE default metric. + * + * @param cb Channel buffer + * @return object of type BgpLinkAttrTeDefaultMetric + * @throws BGPParseException while parsing BgpLinkAttrTeDefaultMetric + */ + public static BgpLinkAttrTeDefaultMetric read(ChannelBuffer cb) + 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, + lsAttrLength); + } + + linkTeMetric = cb.readInt(); + + return new BgpLinkAttrTeDefaultMetric(linkTeMetric); + } + + /** + * Returns the TE default metrics. + * + * @return link default metric + */ + public int attrLinkDefTeMetric() { + return linkTeMetric; + } + + @Override + public short getType() { + return ATTRLINK_TEDEFAULTMETRIC; + } + + @Override + public int hashCode() { + return Objects.hash(linkTeMetric); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpLinkAttrTeDefaultMetric) { + BgpLinkAttrTeDefaultMetric other = (BgpLinkAttrTeDefaultMetric) obj; + return Objects.equals(linkTeMetric, other.linkTeMetric); + } + 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()) + .add("linkTEMetric", linkTeMetric).toString(); + } +} 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 new file mode 100755 index 00000000..c7008ca1 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueData.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.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 prefix opaque data attribute. + */ +public final class BgpPrefixAttrOpaqueData implements BGPValueType { + + protected static final Logger log = LoggerFactory + .getLogger(BgpPrefixAttrOpaqueData.class); + + public static final int ATTR_PREFIX_OPAQUEDATA = 1157; + + /* Opaque Node Attribute */ + private final byte[] opaquePrefixAttribute; + + /** + * Constructor to initialize the values. + * + * @param opaquePrefixAttribute opaque prefix data + */ + public BgpPrefixAttrOpaqueData(byte[] opaquePrefixAttribute) { + this.opaquePrefixAttribute = Arrays + .copyOf(opaquePrefixAttribute, opaquePrefixAttribute.length); + } + + /** + * Returns object of this class with specified values. + * + * @param opaquePrefixAttribute opaque prefix data + * @return object of BgpPrefixAttrOpaqueData + */ + public static BgpPrefixAttrOpaqueData of(final byte[] opaquePrefixAttribute) { + return new BgpPrefixAttrOpaqueData(opaquePrefixAttribute); + } + + /** + * Reads the Opaque Prefix Attribute. + * + * @param cb ChannelBuffer + * @return object of BgpPrefixAttrOpaqueData + * @throws BGPParseException while parsing BgpPrefixAttrOpaqueData + */ + public static BgpPrefixAttrOpaqueData read(ChannelBuffer cb) + 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, + lsAttrLength); + } + + cb.readBytes(opaquePrefixAttribute); + + return BgpPrefixAttrOpaqueData.of(opaquePrefixAttribute); + } + + /** + * Returns the Opaque prefix attribute name. + * + * @return opaque prefix name + */ + public byte[] getOpaquePrefixAttribute() { + return opaquePrefixAttribute; + } + + @Override + public short getType() { + return ATTR_PREFIX_OPAQUEDATA; + } + + @Override + public int hashCode() { + return Arrays.hashCode(opaquePrefixAttribute); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof BgpPrefixAttrOpaqueData) { + BgpPrefixAttrOpaqueData other = (BgpPrefixAttrOpaqueData) obj; + return Arrays.equals(opaquePrefixAttribute, + other.opaquePrefixAttribute); + } + 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("opaquePrefixAttribute", getOpaquePrefixAttribute()) + .toString(); + } + +} diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpLinkAttrTeDefaultMetricTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpLinkAttrTeDefaultMetricTest.java new file mode 100644 index 00000000..b6453c45 --- /dev/null +++ b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpLinkAttrTeDefaultMetricTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS 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.junit.Test; +import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric; + +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/cli/src/main/java/org/onosproject/cli/net/GroupsListCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/GroupsListCommand.java index 8e30fa4c..ee6d31b8 100644 --- a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/GroupsListCommand.java +++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/GroupsListCommand.java @@ -46,9 +46,9 @@ import static com.google.common.collect.Lists.newArrayList; public class GroupsListCommand extends AbstractShellCommand { private static final String FORMAT = - " id=%s, state=%s, type=%s, bytes=%s, packets=%s, appId=%s"; + " id=0x%s, state=%s, type=%s, bytes=%s, packets=%s, appId=%s"; private static final String BUCKET_FORMAT = - " id=%s, bucket=%s, bytes=%s, packets=%s, actions=%s"; + " id=0x%s, bucket=%s, bytes=%s, packets=%s, actions=%s"; @Argument(index = 1, name = "uri", description = "Device ID", required = false, multiValued = false) diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java index 98329df0..58ac0bb8 100644 --- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java @@ -15,8 +15,12 @@ */ package org.onosproject.net.host; +import org.joda.time.LocalDateTime; import org.onosproject.event.AbstractEvent; import org.onosproject.net.Host; +import org.onosproject.net.HostLocation; + +import static com.google.common.base.MoreObjects.toStringHelper; /** * Describes end-station host event. @@ -48,6 +52,8 @@ public class HostEvent extends AbstractEvent { HOST_MOVED } + private HostLocation prevLocation; + /** * Creates an event of a given type and for the specified host and the * current time. @@ -70,4 +76,35 @@ public class HostEvent extends AbstractEvent { super(type, host, time); } + /** + * Creates an event with HOST_MOVED type along with the previous location + * of the host. + * + * @param host event host subject + * @param prevLocation previous location of the host + */ + public HostEvent(Host host, HostLocation prevLocation) { + super(Type.HOST_MOVED, host); + this.prevLocation = prevLocation; + } + + /** + * Gets the previous location information in this host event. + * + * @return the previous location, or null if previous location is not + * specified. + */ + public HostLocation prevLocation() { + return this.prevLocation; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("time", new LocalDateTime(time())) + .add("type", type()) + .add("subject", subject()) + .add("prevLocation", prevLocation()) + .toString(); + } } 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 e94ee452..cdcd4072 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 @@ -26,7 +26,7 @@ import java.util.List; @Beta public interface ResourceAdminService { /** - * Register resources as the children of the parent resource path. + * Registers resources as the children of the parent resource path. * * @param parent parent resource path under which the resource are registered * @param children resources to be registered as the children of the parent @@ -39,7 +39,7 @@ public interface ResourceAdminService { } /** - * Register resources as the children of the parent resource path. + * Registers resources as the children of the parent resource path. * * @param parent parent resource path under which the resource are registered * @param children resources to be registered as the children of the parent @@ -50,7 +50,7 @@ public interface ResourceAdminService { boolean registerResources(ResourcePath parent, List children); /** - * Unregister resources as the children of the parent resource path. + * Unregisters resources as the children of the parent resource path. * * @param parent parent resource path under which the resource are unregistered * @param children resources to be unregistered as the children of the parent @@ -63,7 +63,7 @@ public interface ResourceAdminService { } /** - * Unregister resources as the children of the parent resource path. + * Unregisters resources as the children of the parent resource path. * * @param parent parent resource path under which the resource are unregistered * @param children resources to be unregistered as the children of the parent diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java index 72ec98ca..a56daab1 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java @@ -88,10 +88,14 @@ public class SimpleHostStore boolean replaceIps) { //TODO We need a way to detect conflicting changes and abort update. StoredHost host = hosts.get(hostId); + HostEvent hostEvent; if (host == null) { - return createHost(providerId, hostId, hostDescription); + hostEvent = createHost(providerId, hostId, hostDescription); + } else { + hostEvent = updateHost(providerId, host, hostDescription, replaceIps); } - return updateHost(providerId, host, hostDescription, replaceIps); + notifyDelegate(hostEvent); + return hostEvent; } // creates a new host and sends HOST_ADDED @@ -153,7 +157,9 @@ public class SimpleHostStore Host host = hosts.remove(hostId); if (host != null) { locations.remove((host.location()), host); - return new HostEvent(HOST_REMOVED, host); + HostEvent hostEvent = new HostEvent(HOST_REMOVED, host); + notifyDelegate(hostEvent); + return hostEvent; } return null; } diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java index 1473f33f..f48b8366 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java @@ -192,10 +192,7 @@ public class HostManager @Override public void removeHost(HostId hostId) { checkNotNull(hostId, HOST_ID_NULL); - HostEvent event = store.removeHost(hostId); - if (event != null) { - post(event); - } + store.removeHost(hostId); } // Personalized host provider service issued to the supplied provider. @@ -211,11 +208,8 @@ public class HostManager checkNotNull(hostId, HOST_ID_NULL); checkValidity(); hostDescription = validateHost(hostDescription, hostId); - HostEvent event = store.createOrUpdateHost(provider().id(), hostId, + store.createOrUpdateHost(provider().id(), hostId, hostDescription, replaceIps); - if (event != null) { - post(event); - } } // returns a HostDescription made from the union of the BasicHostConfig @@ -231,20 +225,14 @@ public class HostManager public void hostVanished(HostId hostId) { checkNotNull(hostId, HOST_ID_NULL); checkValidity(); - HostEvent event = store.removeHost(hostId); - if (event != null) { - post(event); - } + store.removeHost(hostId); } @Override public void removeIpFromHost(HostId hostId, IpAddress ipAddress) { checkNotNull(hostId, HOST_ID_NULL); checkValidity(); - HostEvent event = store.removeIp(hostId, ipAddress); - if (event != null) { - post(event); - } + store.removeIp(hostId, ipAddress); } } 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 db3f6552..77a32f45 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 @@ -67,7 +67,7 @@ public final class ResourceManager extends AbstractListenerManager filteredVlanInterfaces = + filterVlanInterfacesNoIp(interfaceService.getInterfacesByVlan(vlanId)); + + if (vlanId != null + && !vlanId.equals(VlanId.NONE) + && confContainsVlans(vlanId, context.inPort())) { + vlanFlood(context.packet(), filteredVlanInterfaces, context.inPort); + return; + } + // The request couldn't be resolved. // Flood the request on all ports except the incoming port. flood(context.packet(), context.inPort()); } + private Set filterVlanInterfacesNoIp(Set vlanInterfaces) { + return vlanInterfaces + .stream() + .filter(intf -> intf.ipAddresses().isEmpty()) + .collect(Collectors.toSet()); + } + + /** + * States if the interface configuration contains more than one interface configured + * on a specific vlan, including the interface passed as argument. + * + * @param vlanId the vlanid to look for in the interface configuration + * @param connectPoint the connect point to exclude from the search + * @return true if interfaces are found. False otherwise + */ + private boolean confContainsVlans(VlanId vlanId, ConnectPoint connectPoint) { + Set vlanInterfaces = interfaceService.getInterfacesByVlan(vlanId); + return interfaceService.getInterfacesByVlan(vlanId) + .stream() + .anyMatch(intf -> intf.connectPoint().equals(connectPoint) && intf.ipAddresses().isEmpty()) + && vlanInterfaces.size() > 1; + } + /** * Builds and sends a reply message given a request context and the resolved * MAC address to answer with. @@ -259,14 +298,29 @@ public class ProxyArpManager implements ProxyArpService { /** * Returns whether the given port has any IP addresses configured or not. * - * @param port the port to check + * @param connectPoint the port to check * @return true if the port has at least one IP address configured, - * otherwise false + * false otherwise + */ + private boolean hasIpAddress(ConnectPoint connectPoint) { + return interfaceService.getInterfacesByPort(connectPoint) + .stream() + .flatMap(intf -> intf.ipAddresses().stream()) + .findAny() + .isPresent(); + } + + /** + * Returns whether the given port has any VLAN configured or not. + * + * @param connectPoint the port to check + * @return true if the port has at least one VLAN configured, + * false otherwise */ - private boolean hasIpAddress(ConnectPoint port) { - return interfaceService.getInterfacesByPort(port) + private boolean hasVlan(ConnectPoint connectPoint) { + return interfaceService.getInterfacesByPort(connectPoint) .stream() - .map(intf -> intf.ipAddresses()) + .filter(intf -> !intf.vlan().equals(VlanId.NONE)) .findAny() .isPresent(); } @@ -321,6 +375,30 @@ public class ProxyArpManager implements ProxyArpService { return true; } + /** + * Flood the arp request at all edges on a specifc VLAN. + * + * @param request the arp request + * @param dsts the destination interfaces + * @param inPort the connect point the arp request was received on + */ + private void vlanFlood(Ethernet request, Set dsts, ConnectPoint inPort) { + TrafficTreatment.Builder builder = null; + ByteBuffer buf = ByteBuffer.wrap(request.serialize()); + + for (Interface intf : dsts) { + ConnectPoint cPoint = intf.connectPoint(); + if (cPoint.equals(inPort)) { + continue; + } + + builder = DefaultTrafficTreatment.builder(); + builder.setOutput(cPoint.port()); + packetService.emit(new DefaultOutboundPacket(cPoint.deviceId(), + builder.build(), buf)); + } + } + /** * Flood the arp request at all edges in the network. * @@ -332,7 +410,9 @@ public class ProxyArpManager implements ProxyArpService { ByteBuffer buf = ByteBuffer.wrap(request.serialize()); for (ConnectPoint connectPoint : edgeService.getEdgePoints()) { - if (hasIpAddress(connectPoint) || connectPoint.equals(inPort)) { + if (hasIpAddress(connectPoint) + || hasVlan(connectPoint) + || connectPoint.equals(inPort)) { continue; } diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java index 92c6c931..c5a6cabd 100644 --- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java +++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java @@ -20,6 +20,7 @@ import com.google.common.collect.Sets; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.onlab.junit.TestTools; import org.onlab.packet.IpAddress; import org.onlab.packet.MacAddress; import org.onlab.packet.VlanId; @@ -129,13 +130,15 @@ public class HostManagerTest { } private void validateEvents(Enum... types) { - int i = 0; - assertEquals("wrong events received", types.length, listener.events.size()); - for (Event event : listener.events) { - assertEquals("incorrect event type", types[i], event.type()); - i++; - } - listener.events.clear(); + TestTools.assertAfter(100, () -> { + int i = 0; + assertEquals("wrong events received", types.length, listener.events.size()); + for (Event event : listener.events) { + assertEquals("incorrect event type", types[i], event.type()); + i++; + } + listener.events.clear(); + }); } @Test diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java index 3e806a73..ee9dc8fb 100644 --- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java +++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java @@ -15,7 +15,6 @@ */ package org.onosproject.net.proxyarp.impl; -import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.junit.Before; import org.junit.Test; @@ -48,7 +47,7 @@ import org.onosproject.net.Port; import org.onosproject.net.PortNumber; import org.onosproject.net.device.DeviceListener; import org.onosproject.net.device.DeviceService; -import org.onosproject.net.edgeservice.impl.EdgeManager; +import org.onosproject.net.edge.EdgePortService; import org.onosproject.net.flow.DefaultTrafficTreatment; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flow.instructions.Instruction; @@ -67,6 +66,7 @@ import org.onosproject.net.proxyarp.ProxyArpStoreDelegate; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -88,47 +88,65 @@ import static org.junit.Assert.assertTrue; */ public class ProxyArpManagerTest { - private static final int NUM_DEVICES = 6; + private static final int NUM_DEVICES = 10; private static final int NUM_PORTS_PER_DEVICE = 3; - private static final int NUM_ADDRESS_PORTS = NUM_DEVICES / 2; - private static final int NUM_FLOOD_PORTS = 3; + private static final int LAST_CONF_DEVICE_INTF_VLAN_IP = 3; + private static final int LAST_CONF_DEVICE_INTF_VLAN = 6; private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1"); private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2"); - private static final Ip6Address IP3 = Ip6Address.valueOf("1000::1"); - private static final Ip6Address IP4 = Ip6Address.valueOf("1000::2"); + private static final Ip6Address IP3 = Ip6Address.valueOf("1000:ffff::1"); + private static final Ip6Address IP4 = Ip6Address.valueOf("1000:ffff::2"); private static final ProviderId PID = new ProviderId("of", "foo"); private static final VlanId VLAN1 = VlanId.vlanId((short) 1); private static final VlanId VLAN2 = VlanId.vlanId((short) 2); - private static final MacAddress MAC1 = MacAddress.valueOf("00:00:11:00:00:01"); - private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02"); - private static final MacAddress MAC3 = MacAddress.valueOf("00:00:33:00:00:03"); - private static final MacAddress MAC4 = MacAddress.valueOf("00:00:44:00:00:04"); + private static final VlanId VLAN10 = VlanId.vlanId((short) 10); + + private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01"); + private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02"); + private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03"); + private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04"); + private static final MacAddress MAC10 = MacAddress.valueOf("00:00:00:00:00:0A"); + private static final MacAddress SOLICITED_MAC3 = MacAddress.valueOf("33:33:FF:00:00:01"); + private static final HostId HID1 = HostId.hostId(MAC1, VLAN1); private static final HostId HID2 = HostId.hostId(MAC2, VLAN1); private static final HostId HID3 = HostId.hostId(MAC3, VLAN1); private static final HostId HID4 = HostId.hostId(MAC4, VLAN1); + private static final HostId HID10 = HostId.hostId(MAC10, VLAN10); + private static final HostId SOLICITED_HID3 = HostId.hostId(SOLICITED_MAC3, VLAN1); private static final DeviceId DID1 = getDeviceId(1); private static final DeviceId DID2 = getDeviceId(2); + private static final PortNumber P1 = PortNumber.portNumber(1); + private static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L); private static final HostLocation LOC2 = new HostLocation(DID2, P1, 123L); - private static final byte[] ZERO_MAC_ADDRESS = MacAddress.ZERO.toBytes(); - //Return values used for various functions of the TestPacketService inner class. - private boolean isEdgePointReturn; - private List getEdgePointsNoArg; + private final byte[] zeroMacAddress = MacAddress.ZERO.toBytes(); + + // The first three devices in the topology have interfaces configured + // with VLANs and IPs + private final List configIpCPoints = new ArrayList<>(); + // Other three devices in the topology (from 4 to 6) have interfaces + // configured only with VLANs + private final List configVlanCPoints = new ArrayList<>(); + + // Remaining devices in the network (id > 6) don't have any interface + // configured. + private final List noConfigCPoints = new ArrayList<>(); private ProxyArpManager proxyArp; private TestPacketService packetService; private DeviceService deviceService; + private EdgePortService edgePortService; private LinkService linkService; private HostService hostService; private InterfaceService interfaceService; @@ -140,20 +158,27 @@ public class ProxyArpManagerTest { proxyArp.packetService = packetService; proxyArp.store = new TestProxyArpStoreAdapter(); - proxyArp.edgeService = new TestEdgePortService(); - - // Create a host service mock here. Must be replayed by tests once the - // expectations have been set up + // Create a host service mock here. hostService = createMock(HostService.class); proxyArp.hostService = hostService; + // Create an edge port service. + edgePortService = createMock(EdgePortService.class); + proxyArp.edgeService = edgePortService; + + // Create interface service interfaceService = createMock(InterfaceService.class); proxyArp.interfaceService = interfaceService; + // Create the topology createTopology(); proxyArp.deviceService = deviceService; proxyArp.linkService = linkService; + setupNoConfigCPoints(); + setupconfigIpCPoints(); + setupconfigVlanCPoints(); + proxyArp.activate(); } @@ -176,7 +201,8 @@ public class ProxyArpManagerTest { createDevices(NUM_DEVICES, NUM_PORTS_PER_DEVICE); createLinks(NUM_DEVICES); - addAddressBindings(); + addIntfConfig(); + popluateEdgePortService(); } /** @@ -237,13 +263,22 @@ public class ProxyArpManagerTest { replay(linkService); } - private void addAddressBindings() { + /** + * On the first three devices two config interfaces are binded on port 1. + * The first one with VLAN1, the second one with VLAN equals to none. + * Both interfaces have an IP. + * On devices 4, 5 and 6 it's binded a config interface on port 1. + * The interface is configured with VLAN 1 and no IP. + */ + private void addIntfConfig() { Set interfaces = Sets.newHashSet(); - for (int i = 1; i <= NUM_ADDRESS_PORTS; i++) { + Set vlanOneSet = new HashSet<>(); + + for (int i = 1; i <= LAST_CONF_DEVICE_INTF_VLAN_IP; i++) { ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1); - // Interface address for IPv4 + // Interface addresses for IPv4 Ip4Prefix prefix1 = Ip4Prefix.valueOf("10.0." + (2 * i - 1) + ".0/24"); Ip4Address addr1 = Ip4Address.valueOf("10.0." + (2 * i - 1) + ".1"); Ip4Prefix prefix2 = Ip4Prefix.valueOf("10.0." + (2 * i) + ".0/24"); @@ -251,38 +286,130 @@ public class ProxyArpManagerTest { InterfaceIpAddress ia1 = new InterfaceIpAddress(addr1, prefix1); InterfaceIpAddress ia2 = new InterfaceIpAddress(addr2, prefix2); - // Interface address for IPv6 + // Interface addresses for IPv6 Ip6Prefix prefix3 = Ip6Prefix.valueOf((2 * i - 1) + "000::0/64"); Ip6Address addr3 = Ip6Address.valueOf((2 * i - 1) + "000::1"); Ip6Prefix prefix4 = Ip6Prefix.valueOf((2 * i) + "000::0/64"); - Ip6Address addr4 = Ip6Address.valueOf((2 * i) + "000::1"); + Ip6Address addr4 = Ip6Address.valueOf((2 * i) + "000::2"); InterfaceIpAddress ia3 = new InterfaceIpAddress(addr3, prefix3); InterfaceIpAddress ia4 = new InterfaceIpAddress(addr4, prefix4); + // Setting up interfaces Interface intf1 = new Interface(cp, Sets.newHashSet(ia1, ia3), MacAddress.valueOf(2 * i - 1), VlanId.vlanId((short) 1)); Interface intf2 = new Interface(cp, Sets.newHashSet(ia2, ia4), MacAddress.valueOf(2 * i), VlanId.NONE); + interfaces.add(intf1); interfaces.add(intf2); + vlanOneSet.add(intf1); + expect(interfaceService.getInterfacesByPort(cp)) .andReturn(Sets.newHashSet(intf1, intf2)).anyTimes(); } + for (int i = LAST_CONF_DEVICE_INTF_VLAN_IP + 1; i <= LAST_CONF_DEVICE_INTF_VLAN; i++) { + ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1); + Interface intf1 = new Interface(cp, null, + MacAddress.NONE, + VlanId.vlanId((short) 1)); + interfaces.add(intf1); + vlanOneSet.add(intf1); + + expect(interfaceService.getInterfacesByPort(cp)) + .andReturn(Sets.newHashSet(intf1)).anyTimes(); + } + expect(interfaceService.getInterfacesByVlan(VLAN1)) + .andReturn(vlanOneSet).anyTimes(); + expect(interfaceService.getInterfacesByVlan(VLAN10)) + .andReturn(Collections.emptySet()).anyTimes(); expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes(); - for (int i = 1; i <= NUM_FLOOD_PORTS; i++) { - ConnectPoint cp = new ConnectPoint(getDeviceId(i + NUM_ADDRESS_PORTS), + for (int i = LAST_CONF_DEVICE_INTF_VLAN + 1; i <= NUM_DEVICES; i++) { + ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1); - expect(interfaceService.getInterfacesByPort(cp)) .andReturn(Collections.emptySet()).anyTimes(); } } + /** + * Populates edge ports in the EdgePortService to return all port 1 + * as edge ports. + */ + private void popluateEdgePortService() { + Set edgeConnectPoints = new HashSet<>(); + + for (int i = 1; i <= NUM_DEVICES; i++) { + for (int j = 1; j <= NUM_PORTS_PER_DEVICE; j++) { + ConnectPoint edgeConnectPoint = new ConnectPoint( + getDeviceId(i), + PortNumber.portNumber(1)); + ConnectPoint noEdgeConnectPointOne = new ConnectPoint( + getDeviceId(i), + PortNumber.portNumber(2)); + ConnectPoint noEdgeConnectPointTwo = new ConnectPoint( + getDeviceId(i), + PortNumber.portNumber(3)); + + edgeConnectPoints.add(edgeConnectPoint); + + expect(edgePortService.isEdgePoint(edgeConnectPoint)) + .andReturn(true).anyTimes(); + expect(edgePortService.isEdgePoint(noEdgeConnectPointOne)) + .andReturn(false).anyTimes(); + expect(edgePortService.isEdgePoint(noEdgeConnectPointTwo)) + .andReturn(false).anyTimes(); + } + } + expect(edgePortService.getEdgePoints()) + .andReturn(edgeConnectPoints).anyTimes(); + + replay(edgePortService); + } + + /** + * Creates a list of connect points used to verify floodling on ports + * with no interfaces configured (all ports without interface config). + */ + private void setupNoConfigCPoints() { + for (int i = NUM_DEVICES / 2 + 2; i <= NUM_DEVICES; i++) { + ConnectPoint connectPoint = new ConnectPoint( + getDeviceId(i), + PortNumber.portNumber(1)); + noConfigCPoints.add(connectPoint); + } + } + + /** + * Creates a list of connect points used to verify floodling on ports + * with interfaces configured (both VLAN and IP). + */ + private void setupconfigIpCPoints() { + for (int i = 1; i <= 3; i++) { + ConnectPoint connectPoint = new ConnectPoint( + getDeviceId(i), + PortNumber.portNumber(1)); + configIpCPoints.add(connectPoint); + } + } + + /** + * Creates a list of connect points used to verify floodling on ports + * with interfaces configured (both VLAN and IP). + */ + private void setupconfigVlanCPoints() { + for (int i = LAST_CONF_DEVICE_INTF_VLAN_IP + 1; i <= LAST_CONF_DEVICE_INTF_VLAN; i++) { + ConnectPoint connectPoint = new ConnectPoint( + getDeviceId(i), + PortNumber.portNumber(1)); + configVlanCPoints.add(connectPoint); + } + } + /** * Tests {@link ProxyArpManager#isKnown(org.onlab.packet.IpAddress)} in the * case where the IP address is not known. @@ -318,33 +445,34 @@ public class ProxyArpManagerTest { /** * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the * destination host is known. - * Verifies the correct ARP reply is sent out the correct port. + * Two host using the same VLAN are registered on the host service on devices 5 and 6. + * Host on port 6 asks for the MAC of the device on port 5. + * Since the destination mac address is known, the request is not flooded to anywhere + * and ONOS directly builds an ARP reply, sended back to the requester on device 6. + * It's verified that a proper ARP reply is received on port 1 of device 6. */ @Test public void testReplyKnown() { - //Set the return value of isEdgePoint from the edgemanager. - isEdgePointReturn = true; - - Host replyer = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(4), + Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(NUM_DEVICES), Collections.singleton(IP1)); - Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5), + Host replyer = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(NUM_DEVICES - 1), Collections.singleton(IP2)); - expect(hostService.getHostsByIp(IP1)) + expect(hostService.getHostsByIp(IP2)) .andReturn(Collections.singleton(replyer)); - expect(hostService.getHost(HID2)).andReturn(requestor); + expect(hostService.getHost(HID1)).andReturn(requestor); replay(hostService); replay(interfaceService); - Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1); + Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, IP1, IP2); - proxyArp.reply(arpRequest, getLocation(5)); + proxyArp.reply(arpRequest, getLocation(NUM_DEVICES)); assertEquals(1, packetService.packets.size()); - Ethernet arpReply = buildArp(ARP.OP_REPLY, MAC1, MAC2, IP1, IP2); - verifyPacketOut(arpReply, getLocation(5), packetService.packets.get(0)); + Ethernet arpReply = buildArp(ARP.OP_REPLY, VLAN1, MAC2, MAC1, IP2, IP1); + verifyPacketOut(arpReply, getLocation(NUM_DEVICES), packetService.packets.get(0)); } /** @@ -354,9 +482,6 @@ public class ProxyArpManagerTest { */ @Test public void testReplyKnownIpv6() { - //Set the return value of isEdgePoint from the edgemanager. - isEdgePointReturn = true; - Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN1, getLocation(4), Collections.singleton(IP3)); @@ -385,34 +510,31 @@ public class ProxyArpManagerTest { /** * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the * destination host is not known. + * Only a requestor is present (on device 6, port 1). The device has a VLAN configured + * which is not configured anywhere in the system. + * Since the destination is not known, and since the ARP request can't be sent out of + * interfaces configured, the ARP request is flooded out of ports 4 and 5. * Verifies the ARP request is flooded out the correct edge ports. */ @Test public void testReplyUnknown() { - isEdgePointReturn = true; - - Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5), - Collections.singleton(IP2)); + Host requestor = new DefaultHost(PID, HID10, MAC10, VLAN10, getLocation(NUM_DEVICES), + Collections.singleton(IP1)); - expect(hostService.getHostsByIp(IP1)) + expect(hostService.getHostsByIp(IP2)) .andReturn(Collections.emptySet()); - expect(interfaceService.getInterfacesByIp(IP2)) + expect(interfaceService.getInterfacesByIp(IP1)) .andReturn(Collections.emptySet()); - expect(hostService.getHost(HID2)).andReturn(requestor); + expect(hostService.getHost(HID10)).andReturn(requestor); replay(hostService); replay(interfaceService); - Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1); + Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN10, MAC10, null, IP1, IP2); - //Setup the set of edge ports to be used in the reply method - getEdgePointsNoArg = Lists.newLinkedList(); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); + proxyArp.reply(arpRequest, getLocation(NUM_DEVICES)); - proxyArp.reply(arpRequest, getLocation(6)); - - verifyFlood(arpRequest); + verifyFlood(arpRequest, noConfigCPoints); } /** @@ -422,9 +544,7 @@ public class ProxyArpManagerTest { */ @Test public void testReplyUnknownIpv6() { - isEdgePointReturn = true; - - Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5), + Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(NUM_DEVICES), Collections.singleton(IP4)); expect(hostService.getHostsByIp(IP3)) @@ -440,49 +560,107 @@ public class ProxyArpManagerTest { MAC4, SOLICITED_MAC3, IP4, IP3); - //Setup the set of edge ports to be used in the reply method - getEdgePointsNoArg = Lists.newLinkedList(); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); + proxyArp.reply(ndpRequest, getLocation(NUM_DEVICES)); - proxyArp.reply(ndpRequest, getLocation(6)); - - verifyFlood(ndpRequest); + verifyFlood(ndpRequest, noConfigCPoints); } /** * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the * destination host is known for that IP address, but is not on the same * VLAN as the source host. + * An host is connected on device 6, port 1 where no interfaces are defined. It sends + * ARP requests from VLAN10, not configured anywhere in the network. Another host with + * the IP address requested lives on device 5, port 1 in the network. Anyway, since the + * host uses another VLAN it's not found and the ARP packet is flooded out of port + * 4 and 5. + * * Verifies the ARP request is flooded out the correct edge ports. */ @Test public void testReplyDifferentVlan() { - - Host replyer = new DefaultHost(PID, HID1, MAC1, VLAN2, getLocation(4), + Host requestor = new DefaultHost(PID, HID10, MAC10, VLAN10, getLocation(NUM_DEVICES), Collections.singleton(IP1)); - Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5), + Host replyer = new DefaultHost(PID, HID2, MAC2, VLAN2, getLocation(NUM_DEVICES - 1), Collections.singleton(IP2)); - expect(hostService.getHostsByIp(IP1)) + expect(hostService.getHostsByIp(IP2)) .andReturn(Collections.singleton(replyer)); - expect(interfaceService.getInterfacesByIp(IP2)) + expect(interfaceService.getInterfacesByIp(IP1)) .andReturn(Collections.emptySet()); - expect(hostService.getHost(HID2)).andReturn(requestor); + expect(hostService.getHost(HID10)).andReturn(requestor); replay(hostService); replay(interfaceService); - Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1); + Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN10, MAC10, null, IP1, IP2); + + proxyArp.reply(arpRequest, getLocation(NUM_DEVICES)); + + verifyFlood(arpRequest, noConfigCPoints); + } + + /** + * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the + * a vlan packet comes in from a port without interfaces configured. The destination + * host is unknown for that IP address and there are some interfaces configured on + * the same vlan. + * It's expected to see the ARP request going out through ports with no interfaces + * configured, devices 4 and 5, port 1. + * + * Verifies the ARP request is flooded out the correct edge ports. + */ + @Test + public void testConfiguredVlan() { + Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(NUM_DEVICES), + Collections.singleton(IP1)); + + expect(hostService.getHostsByIp(IP2)) + .andReturn(Collections.emptySet()); + expect(interfaceService.getInterfacesByIp(IP1)) + .andReturn(Collections.emptySet()); + expect(hostService.getHost(HID1)).andReturn(requestor); + + replay(hostService); + replay(interfaceService); + + Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, IP1, IP2); + + proxyArp.reply(arpRequest, getLocation(NUM_DEVICES)); + + verifyFlood(arpRequest, noConfigCPoints); + } + + /** + * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the + * a vlan packet comes in from a port without interfaces configured. The destination + * host is not known for that IP address and there are some interfaces configured on + * the same vlan. + * It's expected to see the ARP request going out through ports with no interfaces + * configured, devices 4 and 5, port 1. + * + * Verifies the ARP request is flooded out the correct edge ports. + */ + @Test + public void testConfiguredVlanOnInterfaces() { + Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(6), + Collections.singleton(IP1)); + + expect(hostService.getHostsByIp(IP2)) + .andReturn(Collections.emptySet()); + expect(interfaceService.getInterfacesByIp(IP1)) + .andReturn(Collections.emptySet()); + expect(hostService.getHost(HID1)).andReturn(requestor); + + replay(hostService); + replay(interfaceService); + + Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, IP1, IP2); - //Setup for flood test - getEdgePointsNoArg = Lists.newLinkedList(); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); proxyArp.reply(arpRequest, getLocation(6)); - verifyFlood(arpRequest); + verifyFlood(arpRequest, configVlanCPoints); } /** @@ -493,13 +671,12 @@ public class ProxyArpManagerTest { */ @Test public void testReplyDifferentVlanIpv6() { - - Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN2, getLocation(4), - Collections.singleton(IP3)); - - Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5), + Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(NUM_DEVICES), Collections.singleton(IP4)); + Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN2, getLocation(NUM_DEVICES - 1), + Collections.singleton(IP3)); + expect(hostService.getHostsByIp(IP3)) .andReturn(Collections.singleton(replyer)); expect(interfaceService.getInterfacesByIp(IP4)) @@ -513,13 +690,9 @@ public class ProxyArpManagerTest { MAC4, SOLICITED_MAC3, IP4, IP3); - //Setup for flood test - getEdgePointsNoArg = Lists.newLinkedList(); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); - proxyArp.reply(ndpRequest, getLocation(6)); + proxyArp.reply(ndpRequest, getLocation(NUM_DEVICES)); - verifyFlood(ndpRequest); + verifyFlood(ndpRequest, noConfigCPoints); } /** @@ -533,29 +706,29 @@ public class ProxyArpManagerTest { MacAddress firstMac = MacAddress.valueOf(1L); MacAddress secondMac = MacAddress.valueOf(2L); - Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC1, + Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, LOC1, Collections.singleton(theirIp)); - expect(hostService.getHost(HID2)).andReturn(requestor); + expect(hostService.getHost(HID1)).andReturn(requestor); replay(hostService); replay(interfaceService); - Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, theirIp, ourFirstIp); - isEdgePointReturn = true; + Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp, ourFirstIp); + proxyArp.reply(arpRequest, LOC1); assertEquals(1, packetService.packets.size()); - Ethernet arpReply = buildArp(ARP.OP_REPLY, firstMac, MAC2, ourFirstIp, theirIp); + Ethernet arpReply = buildArp(ARP.OP_REPLY, VLAN1, firstMac, MAC1, ourFirstIp, theirIp); verifyPacketOut(arpReply, LOC1, packetService.packets.get(0)); // Test a request for the second address on that port packetService.packets.clear(); - arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, theirIp, ourSecondIp); + arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp, ourSecondIp); proxyArp.reply(arpRequest, LOC1); assertEquals(1, packetService.packets.size()); - arpReply = buildArp(ARP.OP_REPLY, secondMac, MAC2, ourSecondIp, theirIp); + arpReply = buildArp(ARP.OP_REPLY, VLAN1, secondMac, MAC1, ourSecondIp, theirIp); verifyPacketOut(arpReply, LOC1, packetService.packets.get(0)); } @@ -566,7 +739,7 @@ public class ProxyArpManagerTest { public void testReplyToRequestForUsIpv6() { Ip6Address theirIp = Ip6Address.valueOf("1000::ffff"); Ip6Address ourFirstIp = Ip6Address.valueOf("1000::1"); - Ip6Address ourSecondIp = Ip6Address.valueOf("2000::1"); + Ip6Address ourSecondIp = Ip6Address.valueOf("2000::2"); MacAddress firstMac = MacAddress.valueOf(1L); MacAddress secondMac = MacAddress.valueOf(2L); @@ -584,7 +757,7 @@ public class ProxyArpManagerTest { MacAddress.valueOf("33:33:ff:00:00:01"), theirIp, ourFirstIp); - isEdgePointReturn = true; + proxyArp.reply(ndpRequest, LOC1); assertEquals(1, packetService.packets.size()); @@ -599,9 +772,9 @@ public class ProxyArpManagerTest { packetService.packets.clear(); ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, MAC2, - MacAddress.valueOf("33:33:ff:00:00:01"), - theirIp, - ourSecondIp); + MacAddress.valueOf("33:33:ff:00:00:01"), + theirIp, + ourSecondIp); proxyArp.reply(ndpRequest, LOC1); assertEquals(1, packetService.packets.size()); @@ -624,14 +797,14 @@ public class ProxyArpManagerTest { Ip4Address theirIp = Ip4Address.valueOf("10.0.1.254"); // Request for a valid external IP address but coming in the wrong port - Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC1, null, theirIp, + Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp, Ip4Address.valueOf("10.0.3.1")); proxyArp.reply(arpRequest, LOC1); assertEquals(0, packetService.packets.size()); // Request for a valid internal IP address but coming in an external port packetService.packets.clear(); - arpRequest = buildArp(ARP.OP_REQUEST, MAC1, null, theirIp, IP1); + arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp, IP1); proxyArp.reply(arpRequest, LOC1); assertEquals(0, packetService.packets.size()); } @@ -647,20 +820,20 @@ public class ProxyArpManagerTest { Ip6Address theirIp = Ip6Address.valueOf("1000::ffff"); Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, - MAC1, - MacAddress.valueOf("33:33:ff:00:00:01"), - theirIp, - Ip6Address.valueOf("3000::1")); + MAC1, + MacAddress.valueOf("33:33:ff:00:00:01"), + theirIp, + Ip6Address.valueOf("3000::1")); proxyArp.reply(ndpRequest, LOC1); assertEquals(0, packetService.packets.size()); // Request for a valid internal IP address but coming in an external port packetService.packets.clear(); ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION, - MAC1, - MacAddress.valueOf("33:33:ff:00:00:01"), - theirIp, - IP3); + MAC1, + MacAddress.valueOf("33:33:ff:00:00:01"), + theirIp, + IP3); proxyArp.reply(ndpRequest, LOC1); assertEquals(0, packetService.packets.size()); } @@ -685,9 +858,8 @@ public class ProxyArpManagerTest { // This is a request from something inside our network (like a BGP // daemon) to an external host. - Ethernet arpRequest = buildArp(ARP.OP_REQUEST, ourMac, null, ourIp, theirIp); + Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, ourMac, null, ourIp, theirIp); //Ensure the packet is allowed through (it is not to an internal port) - isEdgePointReturn = true; proxyArp.reply(arpRequest, getLocation(5)); assertEquals(1, packetService.packets.size()); @@ -728,9 +900,6 @@ public class ProxyArpManagerTest { ourIp, theirIp); - //Ensure the packet is allowed through (it is not to an internal port) - isEdgePointReturn = true; - proxyArp.reply(ndpRequest, getLocation(5)); assertEquals(1, packetService.packets.size()); verifyPacketOut(ndpRequest, getLocation(1), packetService.packets.get(0)); @@ -758,7 +927,7 @@ public class ProxyArpManagerTest { replay(hostService); replay(interfaceService); - Ethernet arpRequest = buildArp(ARP.OP_REPLY, MAC2, MAC1, IP2, IP1); + Ethernet arpRequest = buildArp(ARP.OP_REPLY, VLAN1, MAC2, MAC1, IP2, IP1); proxyArp.forward(arpRequest, LOC2); @@ -804,22 +973,15 @@ public class ProxyArpManagerTest { */ @Test public void testForwardFlood() { - expect(hostService.getHost(HID1)).andReturn(null); + expect(hostService.getHost(HID2)).andReturn(null); replay(hostService); replay(interfaceService); - Ethernet arpRequest = buildArp(ARP.OP_REPLY, MAC2, MAC1, IP2, IP1); - - //populate the list of edges when so that when forward hits flood in the manager it contains the values - //that should continue on - getEdgePointsNoArg = Lists.newLinkedList(); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("3"), PortNumber.portNumber(1))); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); + Ethernet arpRequest = buildArp(ARP.OP_REPLY, VLAN1, MAC1, MAC2, IP1, IP2); - proxyArp.forward(arpRequest, getLocation(6)); + proxyArp.forward(arpRequest, getLocation(NUM_DEVICES)); - verifyFlood(arpRequest); + verifyFlood(arpRequest, noConfigCPoints); } /** @@ -837,16 +999,9 @@ public class ProxyArpManagerTest { MAC4, SOLICITED_MAC3, IP4, IP3); - //populate the list of edges when so that when forward hits flood in the manager it contains the values - //that should continue on - getEdgePointsNoArg = Lists.newLinkedList(); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("3"), PortNumber.portNumber(1))); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1))); - getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1))); + proxyArp.forward(ndpRequest, getLocation(NUM_DEVICES)); - proxyArp.forward(ndpRequest, getLocation(6)); - - verifyFlood(ndpRequest); + verifyFlood(ndpRequest, noConfigCPoints); } /** @@ -854,21 +1009,20 @@ public class ProxyArpManagerTest { * except for the input port. * * @param packet the packet that was expected to be flooded + * @param connectPoints the connectPoints where the outpacket should be + * observed */ - private void verifyFlood(Ethernet packet) { + private void verifyFlood(Ethernet packet, List connectPoints) { + // There should be 1 less than NUM_FLOOD_PORTS; the inPort should be excluded. - assertEquals(NUM_FLOOD_PORTS - 1, packetService.packets.size()); + assertEquals(connectPoints.size() - 1, packetService.packets.size()); Collections.sort(packetService.packets, (o1, o2) -> o1.sendThrough().uri().compareTo(o2.sendThrough().uri())); - - for (int i = 0; i < NUM_FLOOD_PORTS - 1; i++) { - ConnectPoint cp = new ConnectPoint(getDeviceId(NUM_ADDRESS_PORTS + i + 1), - PortNumber.portNumber(1)); - + for (int i = 0; i < connectPoints.size() - 1; i++) { OutboundPacket outboundPacket = packetService.packets.get(i); - verifyPacketOut(packet, cp, outboundPacket); + verifyPacketOut(packet, connectPoints.get(i), outboundPacket); } } @@ -913,8 +1067,8 @@ public class ProxyArpManagerTest { * @param dstIp destination IP address * @return the ARP packet */ - private Ethernet buildArp(short opcode, MacAddress srcMac, MacAddress dstMac, - Ip4Address srcIp, Ip4Address dstIp) { + private Ethernet buildArp(short opcode, VlanId vlanId, MacAddress srcMac, + MacAddress dstMac, Ip4Address srcIp, Ip4Address dstIp) { Ethernet eth = new Ethernet(); if (dstMac == null) { @@ -925,7 +1079,7 @@ public class ProxyArpManagerTest { eth.setSourceMACAddress(srcMac); eth.setEtherType(Ethernet.TYPE_ARP); - eth.setVlanID(VLAN1.toShort()); + eth.setVlanID(vlanId.toShort()); ARP arp = new ARP(); arp.setOpCode(opcode); @@ -937,7 +1091,7 @@ public class ProxyArpManagerTest { arp.setSenderHardwareAddress(srcMac.toBytes()); if (dstMac == null) { - arp.setTargetHardwareAddress(ZERO_MAC_ADDRESS); + arp.setTargetHardwareAddress(zeroMacAddress); } else { arp.setTargetHardwareAddress(dstMac.toBytes()); } @@ -1019,19 +1173,6 @@ public class ProxyArpManagerTest { } - class TestEdgePortService extends EdgeManager { - - @Override - public boolean isEdgePoint(ConnectPoint connectPoint) { - return isEdgePointReturn; - } - - @Override - public Iterable getEdgePoints() { - return getEdgePointsNoArg; - } - } - private class TestProxyArpStoreAdapter implements ProxyArpStore { @Override public void forward(ConnectPoint outPort, Host subject, ByteBuffer packet) { diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java index f9c96891..391a88f7 100644 --- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java +++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java @@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkState; import static org.onosproject.net.DefaultAnnotations.merge; import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED; import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED; -import static org.onosproject.net.host.HostEvent.Type.HOST_MOVED; import static org.onosproject.net.host.HostEvent.Type.HOST_UPDATED; import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT; import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE; @@ -28,9 +27,10 @@ import static org.slf4j.LoggerFactory.getLogger; import java.util.Collection; import java.util.HashSet; +import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -56,7 +56,6 @@ import org.onosproject.net.host.HostDescription; import org.onosproject.net.host.HostEvent; import org.onosproject.net.host.HostStore; import org.onosproject.net.host.HostStoreDelegate; -import org.onosproject.net.host.HostEvent.Type; import org.onosproject.net.provider.ProviderId; import org.onosproject.store.AbstractStore; import org.onosproject.store.serializers.KryoNamespaces; @@ -67,10 +66,7 @@ import org.onosproject.store.service.LogicalClockService; import org.onosproject.store.service.StorageService; import org.slf4j.Logger; -import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Multimaps; -import com.google.common.collect.SetMultimap; import com.google.common.collect.Sets; /** @@ -90,13 +86,11 @@ public class ECHostStore @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected LogicalClockService clockService; - // Hosts tracked by their location - private final SetMultimap locations = - Multimaps.synchronizedSetMultimap( - HashMultimap.create()); - private EventuallyConsistentMap hosts; + private final ConcurrentHashMap locations = + new ConcurrentHashMap<>(); + private EventuallyConsistentMapListener hostLocationTracker = new HostLocationTracker(); @@ -125,6 +119,7 @@ public class ECHostStore log.info("Stopped"); } + // TODO No longer need to return HostEvent @Override public HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId, @@ -133,18 +128,7 @@ public class ECHostStore // TODO: We need a way to detect conflicting changes and abort update. // (BOC) Compute might do this for us. - final AtomicReference eventType = new AtomicReference<>(); - final AtomicReference oldHost = new AtomicReference<>(); - DefaultHost host = hosts.compute(hostId, (id, existingHost) -> { - if (existingHost != null) { - oldHost.set(existingHost); - checkState(Objects.equals(hostDescription.hwAddress(), existingHost.mac()), - "Existing and new MAC addresses differ."); - checkState(Objects.equals(hostDescription.vlan(), existingHost.vlan()), - "Existing and new VLANs differ."); - } - - // TODO do we ever want the existing location? + hosts.compute(hostId, (id, existingHost) -> { HostLocation location = hostDescription.location(); final Set addresses; @@ -163,15 +147,6 @@ public class ECHostStore annotations = hostDescription.annotations(); } - if (existingHost == null) { - eventType.set(HOST_ADDED); - } else if (!Objects.equals(existingHost.location(), hostDescription.location())) { - eventType.set(HOST_MOVED); - } else if (!existingHost.ipAddresses().containsAll(hostDescription.ipAddress()) || - !hostDescription.annotations().keys().isEmpty()) { - eventType.set(HOST_UPDATED); - } // else, eventType == null; this means we don't send an event - return new DefaultHost(providerId, hostId, hostDescription.hwAddress(), @@ -181,24 +156,20 @@ public class ECHostStore annotations); }); - if (oldHost.get() != null) { - DefaultHost old = oldHost.get(); - locations.remove(old.location(), old); - } - locations.put(host.location(), host); - - return eventType.get() != null ? new HostEvent(eventType.get(), host) : null; + return null; } + // TODO No longer need to return HostEvent @Override public HostEvent removeHost(HostId hostId) { - Host host = hosts.remove(hostId); - return host != null ? new HostEvent(HOST_REMOVED, host) : null; + hosts.remove(hostId); + return null; } + // TODO No longer need to return HostEvent @Override public HostEvent removeIp(HostId hostId, IpAddress ipAddress) { - DefaultHost host = hosts.compute(hostId, (id, existingHost) -> { + hosts.compute(hostId, (id, existingHost) -> { if (existingHost != null) { checkState(Objects.equals(hostId.mac(), existingHost.mac()), "Existing and new MAC addresses differ."); @@ -222,7 +193,7 @@ public class ECHostStore } return null; }); - return host != null ? new HostEvent(HOST_UPDATED, host) : null; + return null; } @Override @@ -257,22 +228,19 @@ public class ECHostStore @Override public Set getConnectedHosts(ConnectPoint connectPoint) { - synchronized (locations) { - return ImmutableSet.copyOf(locations.get(connectPoint)); - } + Set filtered = hosts.entrySet().stream() + .filter(entry -> entry.getValue().location().equals(connectPoint)) + .map(Map.Entry::getValue) + .collect(Collectors.toSet()); + return ImmutableSet.copyOf(filtered); } @Override public Set getConnectedHosts(DeviceId deviceId) { - Set filtered; - synchronized (locations) { - filtered = locations - .entries() - .stream() - .filter(entry -> entry.getKey().deviceId().equals(deviceId)) - .map(entry -> entry.getValue()) - .collect(Collectors.toSet()); - } + Set filtered = hosts.entrySet().stream() + .filter(entry -> entry.getValue().location().deviceId().equals(deviceId)) + .map(Map.Entry::getValue) + .collect(Collectors.toSet()); return ImmutableSet.copyOf(filtered); } @@ -285,13 +253,18 @@ public class ECHostStore public void event(EventuallyConsistentMapEvent event) { DefaultHost host = checkNotNull(event.value()); if (event.type() == PUT) { - boolean isNew = locations.put(host.location(), host); - notifyDelegate(new HostEvent(isNew ? HOST_ADDED : HOST_UPDATED, host)); + HostLocation prevLocation = locations.put(host.id(), host.location()); + if (prevLocation == null) { + notifyDelegate(new HostEvent(HOST_ADDED, host)); + } else if (!Objects.equals(prevLocation, host.location())) { + notifyDelegate(new HostEvent(host, prevLocation)); + } else { + notifyDelegate(new HostEvent(HOST_UPDATED, host)); + } } else if (event.type() == REMOVE) { - if (locations.remove(host.location(), host)) { + if (locations.remove(host.id()) != null) { notifyDelegate(new HostEvent(HOST_REMOVED, host)); } - } } } diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java index 82dfe32f..4d9e3cbf 100644 --- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java +++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java @@ -292,9 +292,9 @@ public class ConsistentResourceStore extends AbstractStore boolean appendValues(TransactionalMap> map, K key, List values) { - List oldValues = map.get(key); + List oldValues = map.putIfAbsent(key, new ArrayList<>(values)); if (oldValues == null) { - return map.replace(key, oldValues, new ArrayList<>(values)); + return true; } LinkedHashSet oldSet = new LinkedHashSet<>(oldValues); @@ -321,7 +321,8 @@ public class ConsistentResourceStore extends AbstractStore boolean removeValues(TransactionalMap> map, K key, List values) { List oldValues = map.get(key); if (oldValues == null) { - return map.replace(key, oldValues, new ArrayList<>()); + map.put(key, new ArrayList<>()); + return true; } LinkedHashSet oldSet = new LinkedHashSet<>(oldValues); diff --git a/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java b/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java index 25ea6412..9b899a67 100644 --- a/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java +++ b/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java @@ -41,6 +41,9 @@ 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) { @@ -218,12 +221,12 @@ public class OpenflowSwitchDriverAdapter implements OpenFlowSwitchDriver { @Override public void setRole(RoleState role) { - + this.role = role; } @Override public RoleState getRole() { - return null; + return role; } @Override diff --git a/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplTest.java b/framework/src/onos/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/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/openflow/pom.xml b/framework/src/onos/openflow/pom.xml index 91fe2f69..3672e469 100644 --- a/framework/src/onos/openflow/pom.xml +++ b/framework/src/onos/openflow/pom.xml @@ -63,6 +63,15 @@ 1.3 test + + org.easymock + easymock + test + + + org.osgi + org.osgi.core + diff --git a/framework/src/onos/pom.xml b/framework/src/onos/pom.xml index 4686e3f3..89930f59 100644 --- a/framework/src/onos/pom.xml +++ b/framework/src/onos/pom.xml @@ -48,6 +48,7 @@ ovsdb netconf pcep + bgp providers drivers @@ -59,7 +60,6 @@ tools/package/archetypes tools/package/branding tools/build/conf - bgp http://onosproject.org/ @@ -536,6 +536,7 @@ maven-surefire-plugin 2.18.1 + -Duser.language=en -Duser.region=US true true diff --git a/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml b/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml index e04479c5..fc6757a5 100644 --- a/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml +++ b/framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml @@ -160,7 +160,9 @@ - + + + diff --git a/framework/src/onos/tools/build/onos-build-docs b/framework/src/onos/tools/build/onos-build-docs index 93a73c14..f7d0a0b8 100755 --- a/framework/src/onos/tools/build/onos-build-docs +++ b/framework/src/onos/tools/build/onos-build-docs @@ -34,11 +34,11 @@ rm -fr $ONOS_ROOT/docs/target cd $ONOS_ROOT/docs processPom external.xml -mvn -f aux-external.xml javadoc:aggregate +mvn -f aux-external.xml javadoc:aggregate "$@" cd target && mv site/apidocs $apidocs tar zcf $apidocs.tar.gz $apidocs && cp $apidocs.tar.gz /tmp cd $ONOS_ROOT/docs processPom internal.xml -mvn -f aux-internal.xml javadoc:aggregate +mvn -f aux-internal.xml javadoc:aggregate "$@" diff --git a/framework/src/onos/tools/dev/bash_profile b/framework/src/onos/tools/dev/bash_profile index a0f040a5..b8244a77 100644 --- a/framework/src/onos/tools/dev/bash_profile +++ b/framework/src/onos/tools/dev/bash_profile @@ -67,7 +67,6 @@ alias pub='onos-push-update-bundle' # Short-hand for tailing and searching the ONOS (karaf) log alias tl='$ONOS_ROOT/tools/dev/bin/onos-local-log' -alias ll='less $KARAF_LOG' alias gl='grep $KARAF_LOG --colour=auto -E -e ' function filterLocalLog { diff --git a/framework/src/onos/tools/test/scenarios/net-topo.xml b/framework/src/onos/tools/test/scenarios/net-topo.xml index abcf8642..cd720888 100644 --- a/framework/src/onos/tools/test/scenarios/net-topo.xml +++ b/framework/src/onos/tools/test/scenarios/net-topo.xml @@ -38,7 +38,7 @@ + exec="test '${clusterTopo0Root}' == 'of:000000000000000a' -o '${clusterTopo0Root}' == 'of:000000000000000c'"/> + + + onlab-utils + org.onosproject + 1.4.0-SNAPSHOT + + 4.0.0 + + utils.catalyst + bundle + + ONLab catalyst dependency + + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + true + + + io.atomix.catalyst.* + + + + + + package + + shade + + + + + + + org.apache.felix + maven-bundle-plugin + + + + io.atomix.catalyst.serializer;version="1.0.0-rc4", + io.atomix.catalyst.buffer;version="1.0.0-rc4", + io.atomix.catalyst.transport;version="1.0.0-rc4", + + + io.atomix.catalyst.*;version="1.0.0-rc4" + + + + + + + + + \ No newline at end of file diff --git a/framework/src/onos/utils/pom.xml b/framework/src/onos/utils/pom.xml index c2fa5dc6..2129c85d 100644 --- a/framework/src/onos/utils/pom.xml +++ b/framework/src/onos/utils/pom.xml @@ -41,7 +41,8 @@ thirdparty stc jdvue - jnc + jnc + catalyst diff --git a/framework/src/onos/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java b/framework/src/onos/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java index 82b7a782..700e57e3 100644 --- a/framework/src/onos/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java +++ b/framework/src/onos/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java @@ -289,6 +289,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { @Override public void process(long sid, ObjectNode payload) { + removeListeners(); stopSummaryMonitoring(); traffic.stopMonitoring(); } diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.js index 7ddfd136..702584af 100644 --- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.js +++ b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.js @@ -30,7 +30,7 @@ // references to injected services etc. var $scope, $log, $cookies, fs, ks, zs, gs, ms, sus, flash, wss, ps, - tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs, ttip, tov; + tds, tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs, ttip, tov; // DOM elements var ovtopo, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer; @@ -425,7 +425,7 @@ .controller('OvTopoCtrl', ['$scope', '$log', '$location', '$timeout', '$cookies', 'FnService', 'MastService', 'KeyService', 'ZoomService', 'GlyphService', 'MapService', 'SvgUtilService', 'FlashService', - 'WebSocketService', 'PrefsService', + 'WebSocketService', 'PrefsService', 'TopoDialogService', 'TopoEventService', 'TopoForceService', 'TopoPanelService', 'TopoInstService', 'TopoSelectService', 'TopoLinkService', 'TopoTrafficService', 'TopoObliqueService', 'TopoFilterService', @@ -433,9 +433,9 @@ 'TopoOverlayService', function (_$scope_, _$log_, $loc, $timeout, _$cookies_, _fs_, mast, _ks_, - _zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _tes_, _tfs_, - _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_, _ttbs_, tspr, - _ttip_, _tov_) { + _zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _tds_, _tes_, + _tfs_, _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_, + _ttbs_, tspr, _ttip_, _tov_) { var params = $loc.search(), projection, dim, @@ -461,6 +461,7 @@ flash = _flash_; wss = _wss_; ps = _ps_; + tds = _tds_; tes = _tes_; tfs = _tfs_; // TODO: consider funnelling actions through TopoForceService... @@ -495,6 +496,7 @@ tes.stop(); ks.unbindKeys(); tps.destroyPanels(); + tds.closeDialog(); tis.destroyInst(); tfs.destroyForce(); ttbs.destroyToolbar(); diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoDialog.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoDialog.js index 93079183..0c47511b 100644 --- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoDialog.js +++ b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoDialog.js @@ -106,6 +106,13 @@ .on('click', invoke); } + function setTitle(title) { + if (pApi) { + pApi.appendHeader('h2').text(title); + } + return dApi; + } + function addContent(content) { if (pApi) { pApi.appendBody(content); @@ -127,11 +134,11 @@ pApi = createDialog(); } pApi.reset(); - pApi.appendHeader('h2').text('=dialog='); panel.show(); // return the dialog object API dApi = { + setTitle: setTitle, addContent: addContent, addButton: addButton }; diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoToolbar.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoToolbar.js index 06285442..804e2a3c 100644 --- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoToolbar.js +++ b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoToolbar.js @@ -23,7 +23,7 @@ 'use strict'; // injected references - var $log, fs, tbs, ps, tov, api; + var $log, fs, tbs, ps, tov, tds, api; // API: // getActionEntry @@ -192,6 +192,8 @@ }); } + // ensure dialog has closed (if opened by outgoing overlay) + tds.closeDialog(); thirdRow.clear(); if (!order.length) { @@ -271,14 +273,15 @@ angular.module('ovTopo') .factory('TopoToolbarService', ['$log', 'FnService', 'ToolbarService', 'PrefsService', - 'TopoOverlayService', + 'TopoOverlayService', 'TopoDialogService', - function (_$log_, _fs_, _tbs_, _ps_, _tov_) { + function (_$log_, _fs_, _tbs_, _ps_, _tov_, _tds_) { $log = _$log_; fs = _fs_; tbs = _tbs_; ps = _ps_; tov = _tov_; + tds = _tds_; return { init: init, -- cgit 1.2.3-korg