diff options
author | CNlucius <lukai1@huawei.com> | 2016-09-13 11:40:12 +0800 |
---|---|---|
committer | CNlucius <lukai1@huawei.com> | 2016-09-13 11:41:53 +0800 |
commit | b731e2f1dd0972409b136aebc7b463dd72c9cfad (patch) | |
tree | 5107d7d80c19ad8076c2c97c2b5ef8d1cf3ab903 /framework/src/onos/apps/segmentrouting | |
parent | ee93993458266114c29271a481ef9ce7ce621b2a (diff) |
ONOSFW-171
O/S-SFC-ONOS scenario documentation
Change-Id: I51ae1cf736ea24ab6680f8edca1b2bf5dd598365
Signed-off-by: CNlucius <lukai1@huawei.com>
Diffstat (limited to 'framework/src/onos/apps/segmentrouting')
49 files changed, 0 insertions, 8559 deletions
diff --git a/framework/src/onos/apps/segmentrouting/pom.xml b/framework/src/onos/apps/segmentrouting/pom.xml deleted file mode 100644 index 76d90490..00000000 --- a/framework/src/onos/apps/segmentrouting/pom.xml +++ /dev/null @@ -1,142 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ Copyright 2014 Open Networking Laboratory - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <artifactId>onos-apps</artifactId> - <groupId>org.onosproject</groupId> - <version>1.4.0-rc1</version> - <relativePath>../pom.xml</relativePath> - </parent> - - <artifactId>onos-app-segmentrouting</artifactId> - <packaging>bundle</packaging> - - <description>Segment routing application</description> - - <properties> - <onos.app.name>org.onosproject.segmentrouting</onos.app.name> - <web.context>/onos/segmentrouting</web.context> - <api.version>1.0.0</api.version> - <api.title>ONOS Segment Routing REST API</api.title> - <api.description> - APIs for interacting with the Segment Routing application. - </api.description> - <api.package>org.onosproject.segmentrouting.web</api.package> - </properties> - - <dependencies> - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-cli</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.apache.karaf.shell</groupId> - <artifactId>org.apache.karaf.shell.console</artifactId> - </dependency> - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-rest</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onlab-rest</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>javax.ws.rs</groupId> - <artifactId>jsr311-api</artifactId> - <version>1.1.1</version> - </dependency> - <dependency> - <groupId>com.sun.jersey</groupId> - <artifactId>jersey-servlet</artifactId> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </dependency> - - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-annotations</artifactId> - </dependency> - - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.compendium</artifactId> - </dependency> - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.core</artifactId> - </dependency> - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onlab-junit</artifactId> - <scope>test</scope> - </dependency> - </dependencies> - - <build> - <plugins> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - <extensions>true</extensions> - <configuration> - <instructions> - <_wab>src/main/webapp/</_wab> - <Include-Resource> - WEB-INF/classes/apidoc/swagger.json=target/swagger.json, - {maven-resources} - </Include-Resource> - <Bundle-SymbolicName> - ${project.groupId}.${project.artifactId} - </Bundle-SymbolicName> - <Import-Package> - org.slf4j, - org.osgi.framework, - javax.ws.rs, - javax.ws.rs.core, - com.sun.jersey.api.core, - com.sun.jersey.spi.container.servlet, - com.sun.jersey.server.impl.container.servlet, - com.fasterxml.jackson.databind, - com.fasterxml.jackson.databind.node, - com.fasterxml.jackson.core, - org.apache.karaf.shell.commands, - org.apache.commons.lang.math.*, - com.google.common.*, - org.onlab.packet.*, - org.onlab.rest.*, - org.onosproject.*, - org.onlab.util.*, - org.jboss.netty.util.* - </Import-Package> - <Web-ContextPath>${web.context}</Web-ContextPath> - </instructions> - </configuration> - </plugin> - </plugins> - </build> - -</project> diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java deleted file mode 100644 index 7f4bcb15..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java +++ /dev/null @@ -1,295 +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.segmentrouting; - -import org.onlab.packet.ARP; -import org.onlab.packet.Ethernet; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.IpAddress; -import org.onlab.packet.MacAddress; -import org.onlab.packet.VlanId; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Host; -import org.onosproject.net.PortNumber; -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.HostId; -import org.onosproject.net.packet.OutboundPacket; -import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; -import org.onosproject.segmentrouting.config.DeviceConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.Set; - -import static com.google.common.base.Preconditions.checkNotNull; - -public class ArpHandler { - - private static Logger log = LoggerFactory.getLogger(ArpHandler.class); - - private SegmentRoutingManager srManager; - private DeviceConfiguration config; - - /** - * Creates an ArpHandler object. - * - * @param srManager SegmentRoutingManager object - */ - public ArpHandler(SegmentRoutingManager srManager) { - this.srManager = srManager; - this.config = checkNotNull(srManager.deviceConfiguration); - } - - /** - * Processes incoming ARP packets. - * - * If it is an ARP request to router itself or known hosts, - * then it sends ARP response. - * If it is an ARP request to unknown hosts in its own subnet, - * then it flood the ARP request to the ports. - * If it is an ARP response, then set a flow rule for the host - * and forward any IP packets to the host in the packet buffer to the host. - * <p> - * Note: We handles all ARP packet in, even for those ARP packets between - * hosts in the same subnet. - * For an ARP packet with broadcast destination MAC, - * some switches pipelines will send it to the controller due to table miss, - * other swithches will flood the packets directly in the data plane without - * packet in. - * We can deal with both cases. - * - * @param pkt incoming packet - */ - public void processPacketIn(InboundPacket pkt) { - - Ethernet ethernet = pkt.parsed(); - ARP arp = (ARP) ethernet.getPayload(); - - ConnectPoint connectPoint = pkt.receivedFrom(); - PortNumber inPort = connectPoint.port(); - DeviceId deviceId = connectPoint.deviceId(); - byte[] senderMacAddressByte = arp.getSenderHardwareAddress(); - Ip4Address hostIpAddress = Ip4Address.valueOf(arp.getSenderProtocolAddress()); - - srManager.routingRulePopulator.populateIpRuleForHost(deviceId, hostIpAddress, MacAddress. - valueOf(senderMacAddressByte), inPort); - - if (arp.getOpCode() == ARP.OP_REQUEST) { - handleArpRequest(deviceId, connectPoint, ethernet); - } else { - handleArpReply(deviceId, connectPoint, ethernet); - } - } - - private void handleArpRequest(DeviceId deviceId, ConnectPoint inPort, Ethernet payload) { - ARP arpRequest = (ARP) payload.getPayload(); - VlanId vlanId = VlanId.vlanId(payload.getVlanID()); - HostId targetHostId = HostId.hostId(MacAddress.valueOf( - arpRequest.getTargetHardwareAddress()), - vlanId); - - // ARP request for router. Send ARP reply. - if (isArpForRouter(deviceId, arpRequest)) { - Ip4Address targetAddress = Ip4Address.valueOf(arpRequest.getTargetProtocolAddress()); - sendArpResponse(arpRequest, config.getRouterMacForAGatewayIp(targetAddress), vlanId); - } else { - Host targetHost = srManager.hostService.getHost(targetHostId); - // ARP request for known hosts. Send proxy ARP reply on behalf of the target. - if (targetHost != null) { - removeVlanAndForward(payload, targetHost.location()); - // ARP request for unknown host in the subnet. Flood in the subnet. - } else { - removeVlanAndFlood(payload, inPort); - } - } - } - - private void handleArpReply(DeviceId deviceId, ConnectPoint inPort, Ethernet payload) { - ARP arpReply = (ARP) payload.getPayload(); - VlanId vlanId = VlanId.vlanId(payload.getVlanID()); - HostId targetHostId = HostId.hostId(MacAddress.valueOf( - arpReply.getTargetHardwareAddress()), - vlanId); - - // ARP reply for router. Process all pending IP packets. - if (isArpForRouter(deviceId, arpReply)) { - Ip4Address hostIpAddress = Ip4Address.valueOf(arpReply.getSenderProtocolAddress()); - srManager.ipHandler.forwardPackets(deviceId, hostIpAddress); - } else { - Host targetHost = srManager.hostService.getHost(targetHostId); - // ARP reply for known hosts. Forward to the host. - if (targetHost != null) { - removeVlanAndForward(payload, targetHost.location()); - // ARP reply for unknown host, Flood in the subnet. - } else { - // Don't flood to non-edge ports - if (vlanId.equals( - VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET))) { - return; - } - removeVlanAndFlood(payload, inPort); - } - } - } - - - private boolean isArpForRouter(DeviceId deviceId, ARP arpMsg) { - Ip4Address targetProtocolAddress = Ip4Address.valueOf( - arpMsg.getTargetProtocolAddress()); - Set<Ip4Address> gatewayIpAddresses = null; - try { - if (targetProtocolAddress.equals(config.getRouterIp(deviceId))) { - return true; - } - gatewayIpAddresses = config.getPortIPs(deviceId); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting check for router IP in processing arp"); - } - if (gatewayIpAddresses != null && - gatewayIpAddresses.contains(targetProtocolAddress)) { - return true; - } - return false; - } - - /** - * Sends an APR request for the target IP address to all ports except in-port. - * - * @param deviceId Switch device ID - * @param targetAddress target IP address for ARP - * @param inPort in-port - */ - public void sendArpRequest(DeviceId deviceId, IpAddress targetAddress, ConnectPoint inPort) { - byte[] senderMacAddress; - byte[] senderIpAddress; - - try { - senderMacAddress = config.getDeviceMac(deviceId).toBytes(); - senderIpAddress = config.getRouterIp(deviceId).toOctets(); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting sendArpRequest."); - return; - } - - ARP arpRequest = new ARP(); - arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET) - .setProtocolType(ARP.PROTO_TYPE_IP) - .setHardwareAddressLength( - (byte) Ethernet.DATALAYER_ADDRESS_LENGTH) - .setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH) - .setOpCode(ARP.OP_REQUEST) - .setSenderHardwareAddress(senderMacAddress) - .setTargetHardwareAddress(MacAddress.ZERO.toBytes()) - .setSenderProtocolAddress(senderIpAddress) - .setTargetProtocolAddress(targetAddress.toOctets()); - - Ethernet eth = new Ethernet(); - eth.setDestinationMACAddress(MacAddress.BROADCAST.toBytes()) - .setSourceMACAddress(senderMacAddress) - .setEtherType(Ethernet.TYPE_ARP).setPayload(arpRequest); - - removeVlanAndFlood(eth, inPort); - } - - private void sendArpResponse(ARP arpRequest, MacAddress targetMac, VlanId vlanId) { - ARP arpReply = new ARP(); - arpReply.setHardwareType(ARP.HW_TYPE_ETHERNET) - .setProtocolType(ARP.PROTO_TYPE_IP) - .setHardwareAddressLength( - (byte) Ethernet.DATALAYER_ADDRESS_LENGTH) - .setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH) - .setOpCode(ARP.OP_REPLY) - .setSenderHardwareAddress(targetMac.toBytes()) - .setSenderProtocolAddress(arpRequest.getTargetProtocolAddress()) - .setTargetHardwareAddress(arpRequest.getSenderHardwareAddress()) - .setTargetProtocolAddress(arpRequest.getSenderProtocolAddress()); - - Ethernet eth = new Ethernet(); - eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress()) - .setSourceMACAddress(targetMac.toBytes()) - .setEtherType(Ethernet.TYPE_ARP).setPayload(arpReply); - - - HostId dstId = HostId.hostId( - MacAddress.valueOf(arpReply.getTargetHardwareAddress()), - vlanId); - Host dst = srManager.hostService.getHost(dstId); - if (dst == null) { - log.warn("Cannot send ARP response to unknown device"); - return; - } - - TrafficTreatment treatment = DefaultTrafficTreatment.builder(). - setOutput(dst.location().port()).build(); - OutboundPacket packet = new DefaultOutboundPacket(dst.location().deviceId(), - treatment, ByteBuffer.wrap(eth.serialize())); - - srManager.packetService.emit(packet); - } - - /** - * Remove VLAN tag and flood to all ports in the same subnet. - * - * @param packet packet to be flooded - * @param inPort where the packet comes from - */ - private void removeVlanAndFlood(Ethernet packet, ConnectPoint inPort) { - Ip4Address targetProtocolAddress = Ip4Address.valueOf( - ((ARP) packet.getPayload()).getTargetProtocolAddress() - ); - - srManager.deviceConfiguration.getSubnetPortsMap(inPort.deviceId()).forEach((subnet, ports) -> { - if (subnet.contains(targetProtocolAddress)) { - ports.stream() - .filter(port -> port != inPort.port()) - .forEach(port -> { - removeVlanAndForward(packet, new ConnectPoint(inPort.deviceId(), port)); - }); - } - }); - } - - /** - * Remove VLAN tag and packet out to given port. - * - * Note: In current implementation, we expect all communication with - * end hosts within a subnet to be untagged. - * <p> - * For those pipelines that internally assigns a VLAN, the VLAN tag will be - * removed before egress. - * <p> - * For those pipelines that do not assign internal VLAN, the packet remains - * untagged. - * - * @param packet packet to be forwarded - * @param outPort where the packet should be forwarded - */ - private void removeVlanAndForward(Ethernet packet, ConnectPoint outPort) { - packet.setEtherType(Ethernet.TYPE_ARP); - packet.setVlanID(Ethernet.VLAN_UNTAGGED); - ByteBuffer buf = ByteBuffer.wrap(packet.serialize()); - - TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); - tbuilder.setOutput(outPort.port()); - srManager.packetService.emit(new DefaultOutboundPacket(outPort.deviceId(), - tbuilder.build(), buf)); - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java deleted file mode 100644 index e6451653..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java +++ /dev/null @@ -1,560 +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.segmentrouting; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.IpPrefix; -import org.onosproject.net.Device; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Link; -import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; -import org.onosproject.segmentrouting.config.DeviceConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import static com.google.common.base.Preconditions.checkNotNull; - -public class DefaultRoutingHandler { - - private static Logger log = LoggerFactory - .getLogger(DefaultRoutingHandler.class); - - private SegmentRoutingManager srManager; - private RoutingRulePopulator rulePopulator; - private HashMap<DeviceId, ECMPShortestPathGraph> currentEcmpSpgMap; - private HashMap<DeviceId, ECMPShortestPathGraph> updatedEcmpSpgMap; - private DeviceConfiguration config; - private final Lock statusLock = new ReentrantLock(); - private volatile Status populationStatus; - - /** - * Represents the default routing population status. - */ - public enum Status { - // population process is not started yet. - IDLE, - - // population process started. - STARTED, - - // population process was aborted due to errors, mostly for groups not - // found. - ABORTED, - - // population process was finished successfully. - SUCCEEDED - } - - /** - * Creates a DefaultRoutingHandler object. - * - * @param srManager SegmentRoutingManager object - */ - public DefaultRoutingHandler(SegmentRoutingManager srManager) { - this.srManager = srManager; - this.rulePopulator = checkNotNull(srManager.routingRulePopulator); - this.config = checkNotNull(srManager.deviceConfiguration); - this.populationStatus = Status.IDLE; - this.currentEcmpSpgMap = Maps.newHashMap(); - } - - /** - * Populates all routing rules to all connected routers, including default - * routing rules, adjacency rules, and policy rules if any. - * - * @return true if it succeeds in populating all rules, otherwise false - */ - public boolean populateAllRoutingRules() { - - statusLock.lock(); - try { - populationStatus = Status.STARTED; - rulePopulator.resetCounter(); - log.info("Starting to populate segment-routing rules"); - log.debug("populateAllRoutingRules: populationStatus is STARTED"); - - for (Device sw : srManager.deviceService.getDevices()) { - if (!srManager.mastershipService.isLocalMaster(sw.id())) { - log.debug("populateAllRoutingRules: skipping device {}...we are not master", - sw.id()); - continue; - } - - ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(sw.id(), srManager); - if (!populateEcmpRoutingRules(sw.id(), ecmpSpg)) { - log.debug("populateAllRoutingRules: populationStatus is ABORTED"); - populationStatus = Status.ABORTED; - log.debug("Abort routing rule population"); - return false; - } - currentEcmpSpgMap.put(sw.id(), ecmpSpg); - - // TODO: Set adjacency routing rule for all switches - } - - log.debug("populateAllRoutingRules: populationStatus is SUCCEEDED"); - populationStatus = Status.SUCCEEDED; - log.info("Completed routing rule population. Total # of rules pushed : {}", - rulePopulator.getCounter()); - return true; - } finally { - statusLock.unlock(); - } - } - - /** - * Populates the routing rules according to the route changes due to the link - * failure or link add. It computes the routes changed due to the link changes and - * repopulates the rules only for the routes. - * - * @param linkFail link failed, null for link added - * @return true if it succeeds to populate all rules, false otherwise - */ - public boolean populateRoutingRulesForLinkStatusChange(Link linkFail) { - - statusLock.lock(); - try { - - if (populationStatus == Status.STARTED) { - log.warn("Previous rule population is not finished."); - return true; - } - - // Take the snapshots of the links - updatedEcmpSpgMap = new HashMap<>(); - for (Device sw : srManager.deviceService.getDevices()) { - if (!srManager.mastershipService.isLocalMaster(sw.id())) { - continue; - } - ECMPShortestPathGraph ecmpSpgUpdated = - new ECMPShortestPathGraph(sw.id(), srManager); - updatedEcmpSpgMap.put(sw.id(), ecmpSpgUpdated); - } - - log.info("Starts rule population from link change"); - - Set<ArrayList<DeviceId>> routeChanges; - log.trace("populateRoutingRulesForLinkStatusChange: " - + "populationStatus is STARTED"); - populationStatus = Status.STARTED; - if (linkFail == null) { - // Compare all routes of existing ECMP SPG with the new ones - routeChanges = computeRouteChange(); - } else { - // Compare existing ECMP SPG only with the link removed - routeChanges = computeDamagedRoutes(linkFail); - } - - if (routeChanges.isEmpty()) { - log.info("No route changes for the link status change"); - log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is SUCCEEDED"); - populationStatus = Status.SUCCEEDED; - return true; - } - - if (repopulateRoutingRulesForRoutes(routeChanges)) { - log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is SUCCEEDED"); - populationStatus = Status.SUCCEEDED; - log.info("Complete to repopulate the rules. # of rules populated : {}", - rulePopulator.getCounter()); - return true; - } else { - log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is ABORTED"); - populationStatus = Status.ABORTED; - log.warn("Failed to repopulate the rules."); - return false; - } - } finally { - statusLock.unlock(); - } - } - - private boolean repopulateRoutingRulesForRoutes(Set<ArrayList<DeviceId>> routes) { - rulePopulator.resetCounter(); - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> routesBydevice = - new HashMap<>(); - for (ArrayList<DeviceId> link: routes) { - // When only the source device is defined, reinstall routes to all other devices - if (link.size() == 1) { - log.trace("repopulateRoutingRulesForRoutes: running ECMP graph for device {}", link.get(0)); - ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(link.get(0), srManager); - if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) { - log.debug("Populating flow rules from {} to all is successful", - link.get(0)); - currentEcmpSpgMap.put(link.get(0), ecmpSpg); - } else { - log.warn("Failed to populate the flow rules from {} to all", link.get(0)); - return false; - } - } else { - ArrayList<ArrayList<DeviceId>> deviceRoutes = - routesBydevice.get(link.get(1)); - if (deviceRoutes == null) { - deviceRoutes = new ArrayList<>(); - routesBydevice.put(link.get(1), deviceRoutes); - } - deviceRoutes.add(link); - } - } - - for (DeviceId impactedDevice : routesBydevice.keySet()) { - ArrayList<ArrayList<DeviceId>> deviceRoutes = - routesBydevice.get(impactedDevice); - for (ArrayList<DeviceId> link: deviceRoutes) { - log.debug("repopulate RoutingRules For Routes {} -> {}", - link.get(0), link.get(1)); - DeviceId src = link.get(0); - DeviceId dst = link.get(1); - ECMPShortestPathGraph ecmpSpg = updatedEcmpSpgMap.get(dst); - HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = - ecmpSpg.getAllLearnedSwitchesAndVia(); - for (Integer itrIdx : switchVia.keySet()) { - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap = - switchVia.get(itrIdx); - for (DeviceId targetSw : swViaMap.keySet()) { - if (!targetSw.equals(src)) { - continue; - } - Set<DeviceId> nextHops = new HashSet<>(); - for (ArrayList<DeviceId> via : swViaMap.get(targetSw)) { - if (via.isEmpty()) { - nextHops.add(dst); - } else { - nextHops.add(via.get(0)); - } - } - if (!populateEcmpRoutingRulePartial(targetSw, dst, nextHops)) { - return false; - } - log.debug("Populating flow rules from {} to {} is successful", - targetSw, dst); - } - } - //currentEcmpSpgMap.put(dst, ecmpSpg); - } - //Only if all the flows for all impacted routes to a - //specific target are pushed successfully, update the - //ECMP graph for that target. (Or else the next event - //would not see any changes in the ECMP graphs) - currentEcmpSpgMap.put(impactedDevice, - updatedEcmpSpgMap.get(impactedDevice)); - } - return true; - } - - private Set<ArrayList<DeviceId>> computeDamagedRoutes(Link linkFail) { - - Set<ArrayList<DeviceId>> routes = new HashSet<>(); - - for (Device sw : srManager.deviceService.getDevices()) { - log.debug("Computing the impacted routes for device {} due to link fail", - sw.id()); - if (!srManager.mastershipService.isLocalMaster(sw.id())) { - continue; - } - ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); - if (ecmpSpg == null) { - log.error("No existing ECMP graph for switch {}", sw.id()); - continue; - } - HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = - ecmpSpg.getAllLearnedSwitchesAndVia(); - for (Integer itrIdx : switchVia.keySet()) { - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap = - switchVia.get(itrIdx); - for (DeviceId targetSw : swViaMap.keySet()) { - DeviceId destSw = sw.id(); - Set<ArrayList<DeviceId>> subLinks = - computeLinks(targetSw, destSw, swViaMap); - for (ArrayList<DeviceId> alink: subLinks) { - if ((alink.get(0).equals(linkFail.src().deviceId()) && - alink.get(1).equals(linkFail.dst().deviceId())) - || - (alink.get(0).equals(linkFail.dst().deviceId()) && - alink.get(1).equals(linkFail.src().deviceId()))) { - log.debug("Impacted route:{}->{}", targetSw, destSw); - ArrayList<DeviceId> aRoute = new ArrayList<>(); - aRoute.add(targetSw); - aRoute.add(destSw); - routes.add(aRoute); - break; - } - } - } - } - - } - - return routes; - } - - private Set<ArrayList<DeviceId>> computeRouteChange() { - - Set<ArrayList<DeviceId>> routes = new HashSet<>(); - - for (Device sw : srManager.deviceService.getDevices()) { - log.debug("Computing the impacted routes for device {}", - sw.id()); - if (!srManager.mastershipService.isLocalMaster(sw.id())) { - log.debug("No mastership for {} and skip route optimization", - sw.id()); - continue; - } - - log.trace("link of {} - ", sw.id()); - for (Link link: srManager.linkService.getDeviceLinks(sw.id())) { - log.trace("{} -> {} ", link.src().deviceId(), link.dst().deviceId()); - } - - log.debug("Checking route change for switch {}", sw.id()); - ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); - if (ecmpSpg == null) { - log.debug("No existing ECMP graph for device {}", sw.id()); - ArrayList<DeviceId> route = new ArrayList<>(); - route.add(sw.id()); - routes.add(route); - continue; - } - ECMPShortestPathGraph newEcmpSpg = updatedEcmpSpgMap.get(sw.id()); - //currentEcmpSpgMap.put(sw.id(), newEcmpSpg); - HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = - ecmpSpg.getAllLearnedSwitchesAndVia(); - HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchViaUpdated = - newEcmpSpg.getAllLearnedSwitchesAndVia(); - - for (Integer itrIdx : switchViaUpdated.keySet()) { - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMapUpdated = - switchViaUpdated.get(itrIdx); - for (DeviceId srcSw : swViaMapUpdated.keySet()) { - ArrayList<ArrayList<DeviceId>> viaUpdated = swViaMapUpdated.get(srcSw); - ArrayList<ArrayList<DeviceId>> via = getVia(switchVia, srcSw); - if ((via == null) || !viaUpdated.equals(via)) { - log.debug("Impacted route:{}->{}", srcSw, sw.id()); - ArrayList<DeviceId> route = new ArrayList<>(); - route.add(srcSw); - route.add(sw.id()); - routes.add(route); - } - } - } - } - - for (ArrayList<DeviceId> link: routes) { - log.trace("Route changes - "); - if (link.size() == 1) { - log.trace(" : {} - all", link.get(0)); - } else { - log.trace(" : {} - {}", link.get(0), link.get(1)); - } - } - - return routes; - } - - private ArrayList<ArrayList<DeviceId>> getVia(HashMap<Integer, HashMap<DeviceId, - ArrayList<ArrayList<DeviceId>>>> switchVia, DeviceId srcSw) { - for (Integer itrIdx : switchVia.keySet()) { - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap = - switchVia.get(itrIdx); - if (swViaMap.get(srcSw) == null) { - continue; - } else { - return swViaMap.get(srcSw); - } - } - - return null; - } - - private Set<ArrayList<DeviceId>> computeLinks(DeviceId src, - DeviceId dst, - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> viaMap) { - Set<ArrayList<DeviceId>> subLinks = Sets.newHashSet(); - for (ArrayList<DeviceId> via : viaMap.get(src)) { - DeviceId linkSrc = src; - DeviceId linkDst = dst; - for (DeviceId viaDevice: via) { - ArrayList<DeviceId> link = new ArrayList<>(); - linkDst = viaDevice; - link.add(linkSrc); - link.add(linkDst); - subLinks.add(link); - linkSrc = viaDevice; - } - ArrayList<DeviceId> link = new ArrayList<>(); - link.add(linkSrc); - link.add(dst); - subLinks.add(link); - } - - return subLinks; - } - - private boolean populateEcmpRoutingRules(DeviceId destSw, - ECMPShortestPathGraph ecmpSPG) { - - HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = ecmpSPG - .getAllLearnedSwitchesAndVia(); - for (Integer itrIdx : switchVia.keySet()) { - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap = switchVia - .get(itrIdx); - for (DeviceId targetSw : swViaMap.keySet()) { - Set<DeviceId> nextHops = new HashSet<>(); - log.debug("** Iter: {} root: {} target: {}", itrIdx, destSw, targetSw); - for (ArrayList<DeviceId> via : swViaMap.get(targetSw)) { - if (via.isEmpty()) { - nextHops.add(destSw); - } else { - nextHops.add(via.get(0)); - } - } - if (!populateEcmpRoutingRulePartial(targetSw, destSw, nextHops)) { - return false; - } - } - } - - return true; - } - - private boolean populateEcmpRoutingRulePartial(DeviceId targetSw, - DeviceId destSw, - Set<DeviceId> nextHops) { - boolean result; - - if (nextHops.isEmpty()) { - nextHops.add(destSw); - } - // If both target switch and dest switch are edge routers, then set IP - // rule for both subnet and router IP. - boolean targetIsEdge; - boolean destIsEdge; - Ip4Address destRouterIp; - - try { - targetIsEdge = config.isEdgeDevice(targetSw); - destIsEdge = config.isEdgeDevice(destSw); - destRouterIp = config.getRouterIp(destSw); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting populateEcmpRoutingRulePartial."); - return false; - } - - if (targetIsEdge && destIsEdge) { - Set<Ip4Prefix> subnets = config.getSubnets(destSw); - log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}", - targetSw, destSw, subnets); - result = rulePopulator.populateIpRuleForSubnet(targetSw, - subnets, - destSw, - nextHops); - if (!result) { - return false; - } - - Ip4Address routerIp = destRouterIp; - IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); - log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for router IP {}", - targetSw, destSw, routerIpPrefix); - result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops); - if (!result) { - return false; - } - - } else if (targetIsEdge) { - // If the target switch is an edge router, then set IP rules for the router IP. - Ip4Address routerIp = destRouterIp; - IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); - log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for router IP {}", - targetSw, destSw, routerIpPrefix); - result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops); - if (!result) { - return false; - } - } - // Populates MPLS rules to all routers - log.debug("* populateEcmpRoutingRulePartial in device{} towards {} for all MPLS rules", - targetSw, destSw); - result = rulePopulator.populateMplsRule(targetSw, destSw, nextHops); - if (!result) { - return false; - } - return true; - } - - /** - * Populates filtering rules for permitting Router DstMac and VLAN. - * - * @param deviceId Switch ID to set the rules - */ - public void populatePortAddressingRules(DeviceId deviceId) { - rulePopulator.populateRouterMacVlanFilters(deviceId); - rulePopulator.populateRouterIpPunts(deviceId); - rulePopulator.populateArpPunts(deviceId); - } - - /** - * Start the flow rule population process if it was never started. The - * process finishes successfully when all flow rules are set and stops with - * ABORTED status when any groups required for flows is not set yet. - */ - public void startPopulationProcess() { - statusLock.lock(); - try { - if (populationStatus == Status.IDLE - || populationStatus == Status.SUCCEEDED - || populationStatus == Status.ABORTED) { - populationStatus = Status.STARTED; - populateAllRoutingRules(); - } else { - log.warn("Not initiating startPopulationProcess as populationStatus is {}", - populationStatus); - } - } finally { - statusLock.unlock(); - } - } - - /** - * Resume the flow rule population process if it was aborted for any reason. - * Mostly the process is aborted when the groups required are not set yet. - * XXX is this called? - * - */ - public void resumePopulationProcess() { - statusLock.lock(); - try { - if (populationStatus == Status.ABORTED) { - populationStatus = Status.STARTED; - // TODO: we need to restart from the point aborted instead of - // restarting. - populateAllRoutingRules(); - } - } finally { - statusLock.unlock(); - } - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultTunnel.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultTunnel.java deleted file mode 100644 index 70161432..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultTunnel.java +++ /dev/null @@ -1,109 +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.segmentrouting; - -import java.util.List; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Tunnel class. - */ -public class DefaultTunnel implements Tunnel { - - private final String id; - private final List<Integer> labelIds; - - private int groupId; - private boolean allowedToRemoveGroup; - - /** - * Creates a Tunnel reference. - * - * @param tid Tunnel ID - * @param labelIds Label stack of the tunnel - */ - public DefaultTunnel(String tid, List<Integer> labelIds) { - this.id = checkNotNull(tid); - this.labelIds = labelIds; - //TODO: need to register the class in Kryo for this - //this.labelIds = Collections.unmodifiableList(labelIds); - this.groupId = -1; - } - - /** - * Creates a new DefaultTunnel reference using the tunnel reference. - * - * @param tunnel DefaultTunnel reference - */ - public DefaultTunnel(DefaultTunnel tunnel) { - this.id = tunnel.id; - this.labelIds = tunnel.labelIds; - this.groupId = tunnel.groupId; - } - - @Override - public String id() { - return this.id; - } - - @Override - public List<Integer> labelIds() { - return this.labelIds; - } - - @Override - public int groupId() { - return this.groupId; - } - - @Override - public void setGroupId(int id) { - this.groupId = id; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o instanceof DefaultTunnel) { - DefaultTunnel tunnel = (DefaultTunnel) o; - // We compare only the tunnel paths. - if (tunnel.labelIds.equals(this.labelIds)) { - return true; - } - } - - return false; - } - - @Override - public int hashCode() { - return labelIds.hashCode(); - } - - @Override - public boolean isAllowedToRemoveGroup() { - return this.allowedToRemoveGroup; - } - - @Override - public void allowToRemoveGroup(boolean b) { - this.allowedToRemoveGroup = b; - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ECMPShortestPathGraph.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ECMPShortestPathGraph.java deleted file mode 100644 index e9a59bae..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ECMPShortestPathGraph.java +++ /dev/null @@ -1,370 +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.segmentrouting; - -import org.onosproject.net.DefaultLink; -import org.onosproject.net.DefaultPath; -import org.onosproject.net.Device; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Link; -import org.onosproject.net.Path; -import org.onosproject.net.provider.ProviderId; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; - -/** - * This class creates bandwidth constrained breadth first tree and returns paths - * from root Device to leaf Devices which satisfies the bandwidth condition. If - * bandwidth parameter is not specified, the normal breadth first tree will be - * calculated. The paths are snapshot paths at the point of the class - * instantiation. - */ -public class ECMPShortestPathGraph { - LinkedList<DeviceId> deviceQueue = new LinkedList<>(); - LinkedList<Integer> distanceQueue = new LinkedList<>(); - HashMap<DeviceId, Integer> deviceSearched = new HashMap<>(); - HashMap<DeviceId, ArrayList<Link>> upstreamLinks = new HashMap<>(); - HashMap<DeviceId, ArrayList<Path>> paths = new HashMap<>(); - HashMap<Integer, ArrayList<DeviceId>> distanceDeviceMap = new HashMap<>(); - DeviceId rootDevice; - private SegmentRoutingManager srManager; - private static final Logger log = LoggerFactory - .getLogger(ECMPShortestPathGraph.class); - - /** - * Constructor. - * - * @param rootDevice root of the BFS tree - * @param linkListToAvoid link list to avoid - * @param deviceIdListToAvoid device list to avoid - */ - public ECMPShortestPathGraph(DeviceId rootDevice, List<String> deviceIdListToAvoid, - List<Link> linkListToAvoid) { - this.rootDevice = rootDevice; - calcECMPShortestPathGraph(deviceIdListToAvoid, linkListToAvoid); - } - - /** - * Constructor. - * - * @param rootDevice root of the BFS tree - * @param srManager SegmentRoutingManager object - */ - public ECMPShortestPathGraph(DeviceId rootDevice, SegmentRoutingManager srManager) { - this.rootDevice = rootDevice; - this.srManager = srManager; - calcECMPShortestPathGraph(); - } - - /** - * Calculates the BFS tree using any provided constraints and Intents. - */ - private void calcECMPShortestPathGraph() { - deviceQueue.add(rootDevice); - int currDistance = 0; - distanceQueue.add(currDistance); - deviceSearched.put(rootDevice, currDistance); - while (!deviceQueue.isEmpty()) { - DeviceId sw = deviceQueue.poll(); - DeviceId prevSw = null; - currDistance = distanceQueue.poll(); - - for (Link link : srManager.linkService.getDeviceEgressLinks(sw)) { - DeviceId reachedDevice = link.dst().deviceId(); - if ((prevSw != null) - && (prevSw.equals(reachedDevice))) { - /* Ignore LAG links between the same set of Devicees */ - continue; - } else { - prevSw = reachedDevice; - } - - Integer distance = deviceSearched.get(reachedDevice); - if ((distance != null) && (distance < (currDistance + 1))) { - continue; - } - if (distance == null) { - /* First time visiting this Device node */ - deviceQueue.add(reachedDevice); - distanceQueue.add(currDistance + 1); - deviceSearched.put(reachedDevice, currDistance + 1); - - ArrayList<DeviceId> distanceSwArray = distanceDeviceMap - .get(currDistance + 1); - if (distanceSwArray == null) { - distanceSwArray = new ArrayList<>(); - distanceSwArray.add(reachedDevice); - distanceDeviceMap.put(currDistance + 1, distanceSwArray); - } else { - distanceSwArray.add(reachedDevice); - } - } - - ArrayList<Link> upstreamLinkArray = - upstreamLinks.get(reachedDevice); - if (upstreamLinkArray == null) { - upstreamLinkArray = new ArrayList<>(); - upstreamLinkArray.add(copyDefaultLink(link)); - //upstreamLinkArray.add(link); - upstreamLinks.put(reachedDevice, upstreamLinkArray); - } else { - /* ECMP links */ - upstreamLinkArray.add(copyDefaultLink(link)); - } - } - } - } - - /** - * Calculates the BFS tree using any provided constraints and Intents. - */ - private void calcECMPShortestPathGraph(List<String> deviceIdListToAvoid, List<Link> linksToAvoid) { - deviceQueue.add(rootDevice); - int currDistance = 0; - distanceQueue.add(currDistance); - deviceSearched.put(rootDevice, currDistance); - boolean foundLinkToAvoid = false; - while (!deviceQueue.isEmpty()) { - DeviceId sw = deviceQueue.poll(); - DeviceId prevSw = null; - currDistance = distanceQueue.poll(); - for (Link link : srManager.linkService.getDeviceEgressLinks(sw)) { - for (Link linkToAvoid: linksToAvoid) { - // TODO: equls should work - //if (link.equals(linkToAvoid)) { - if (linkContains(link, linksToAvoid)) { - foundLinkToAvoid = true; - break; - } - } - if (foundLinkToAvoid) { - foundLinkToAvoid = false; - continue; - } - DeviceId reachedDevice = link.dst().deviceId(); - if (deviceIdListToAvoid.contains(reachedDevice.toString())) { - continue; - } - if ((prevSw != null) - && (prevSw.equals(reachedDevice))) { - /* Ignore LAG links between the same set of Devicees */ - continue; - } else { - prevSw = reachedDevice; - } - - Integer distance = deviceSearched.get(reachedDevice); - if ((distance != null) && (distance < (currDistance + 1))) { - continue; - } - if (distance == null) { - /* First time visiting this Device node */ - deviceQueue.add(reachedDevice); - distanceQueue.add(currDistance + 1); - deviceSearched.put(reachedDevice, currDistance + 1); - - ArrayList<DeviceId> distanceSwArray = distanceDeviceMap - .get(currDistance + 1); - if (distanceSwArray == null) { - distanceSwArray = new ArrayList<>(); - distanceSwArray.add(reachedDevice); - distanceDeviceMap.put(currDistance + 1, distanceSwArray); - } else { - distanceSwArray.add(reachedDevice); - } - } - - ArrayList<Link> upstreamLinkArray = - upstreamLinks.get(reachedDevice); - if (upstreamLinkArray == null) { - upstreamLinkArray = new ArrayList<>(); - upstreamLinkArray.add(copyDefaultLink(link)); - upstreamLinks.put(reachedDevice, upstreamLinkArray); - } else { - /* ECMP links */ - upstreamLinkArray.add(copyDefaultLink(link)); - } - } - } - } - - - private boolean linkContains(Link link, List<Link> links) { - - DeviceId srcDevice1 = link.src().deviceId(); - DeviceId dstDevice1 = link.dst().deviceId(); - long srcPort1 = link.src().port().toLong(); - long dstPort1 = link.dst().port().toLong(); - - for (Link link2: links) { - DeviceId srcDevice2 = link2.src().deviceId(); - DeviceId dstDevice2 = link2.dst().deviceId(); - long srcPort2 = link2.src().port().toLong(); - long dstPort2 = link2.dst().port().toLong(); - - if (srcDevice1.toString().equals(srcDevice2.toString()) - && dstDevice1.toString().equals(dstDevice2.toString()) - && srcPort1 == srcPort2 && dstPort1 == dstPort2) { - return true; - } - } - - return false; - } - - private void getDFSPaths(DeviceId dstDeviceDeviceId, Path path, ArrayList<Path> paths) { - DeviceId rootDeviceDeviceId = rootDevice; - for (Link upstreamLink : upstreamLinks.get(dstDeviceDeviceId)) { - /* Deep clone the path object */ - Path sofarPath; - ArrayList<Link> sofarLinks = new ArrayList<>(); - if (path != null && !path.links().isEmpty()) { - sofarLinks.addAll(path.links()); - } - sofarLinks.add(upstreamLink); - sofarPath = new DefaultPath(ProviderId.NONE, sofarLinks, 0); - if (upstreamLink.src().deviceId().equals(rootDeviceDeviceId)) { - paths.add(sofarPath); - return; - } else { - getDFSPaths(upstreamLink.src().deviceId(), sofarPath, paths); - } - } - } - - /** - * Return root Device for the graph. - * - * @return root Device - */ - public DeviceId getRootDevice() { - return rootDevice; - } - - /** - * Return the computed ECMP paths from the root Device to a given Device in - * the network. - * - * @param targetDevice the target Device - * @return the list of ECMP Paths from the root Device to the target Device - */ - public ArrayList<Path> getECMPPaths(DeviceId targetDevice) { - ArrayList<Path> pathArray = paths.get(targetDevice); - if (pathArray == null && deviceSearched.containsKey( - targetDevice)) { - pathArray = new ArrayList<>(); - DeviceId sw = targetDevice; - getDFSPaths(sw, null, pathArray); - paths.put(targetDevice, pathArray); - } - return pathArray; - } - - /** - * Return the complete info of the computed ECMP paths for each Device - * learned in multiple iterations from the root Device. - * - * @return the hash table of Devices learned in multiple Dijkstra - * iterations and corresponding ECMP paths to it from the root - * Device - */ - public HashMap<Integer, HashMap<DeviceId, - ArrayList<Path>>> getCompleteLearnedDeviceesAndPaths() { - - HashMap<Integer, HashMap<DeviceId, ArrayList<Path>>> pathGraph = new HashMap<>(); - - for (Integer itrIndx : distanceDeviceMap.keySet()) { - HashMap<DeviceId, ArrayList<Path>> swMap = new HashMap<>(); - for (DeviceId sw : distanceDeviceMap.get(itrIndx)) { - swMap.put(sw, getECMPPaths(sw)); - } - pathGraph.put(itrIndx, swMap); - } - - return pathGraph; - } - - /** - * Return the complete info of the computed ECMP paths for each Device - * learned in multiple iterations from the root Device. - * - * @return the hash table of Devices learned in multiple Dijkstra - * iterations and corresponding ECMP paths in terms of Devices to - * be traversed to it from the root Device - */ - public HashMap<Integer, HashMap<DeviceId, - ArrayList<ArrayList<DeviceId>>>> getAllLearnedSwitchesAndVia() { - - HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> deviceViaMap = new HashMap<>(); - - for (Integer itrIndx : distanceDeviceMap.keySet()) { - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swMap = new HashMap<>(); - - for (DeviceId sw : distanceDeviceMap.get(itrIndx)) { - ArrayList<ArrayList<DeviceId>> swViaArray = new ArrayList<>(); - for (Path path : getECMPPaths(sw)) { - ArrayList<DeviceId> swVia = new ArrayList<>(); - for (Link link : path.links()) { - if (link.src().deviceId().equals(rootDevice)) { - /* No need to add the root Device again in - * the Via list - */ - continue; - } - swVia.add(link.src().deviceId()); - } - swViaArray.add(swVia); - } - swMap.put(sw, swViaArray); - } - deviceViaMap.put(itrIndx, swMap); - } - return deviceViaMap; - } - - - private Link copyDefaultLink(Link link) { - DefaultLink src = (DefaultLink) link; - DefaultLink defaultLink = new DefaultLink(src.providerId(), src.src(), - src.dst(), src.type(), src.annotations()); - - return defaultLink; - } - - @Override - public String toString() { - StringBuilder sBuilder = new StringBuilder(); - for (Device device: srManager.deviceService.getDevices()) { - if (device.id() != rootDevice) { - sBuilder.append("Paths from" + rootDevice + " to " + device.id() + "\r\n"); - ArrayList<Path> paths = getECMPPaths(device.id()); - if (paths != null) { - for (Path path : paths) { - for (Link link : path.links()) { - sBuilder.append(" : " + link.src() + " -> " + link.dst()); - } - } - } - } - } - return sBuilder.toString(); - } -} - diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java deleted file mode 100644 index d1dc8ddc..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java +++ /dev/null @@ -1,187 +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.segmentrouting; - -import org.onlab.packet.Ethernet; -import org.onlab.packet.ICMP; -import org.onlab.packet.IPv4; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.MPLS; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.DeviceId; -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.segmentrouting.config.DeviceConfigNotFoundException; -import org.onosproject.segmentrouting.config.DeviceConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.Set; - -import static com.google.common.base.Preconditions.checkNotNull; - -public class IcmpHandler { - - private static Logger log = LoggerFactory.getLogger(IcmpHandler.class); - private SegmentRoutingManager srManager; - private DeviceConfiguration config; - - /** - * Creates an IcmpHandler object. - * - * @param srManager SegmentRoutingManager object - */ - public IcmpHandler(SegmentRoutingManager srManager) { - this.srManager = srManager; - this.config = checkNotNull(srManager.deviceConfiguration); - } - - /** - * Process incoming ICMP packet. - * If it is an ICMP request to router or known host, then sends an ICMP response. - * If it is an ICMP packet to known host and forward the packet to the host. - * If it is an ICMP packet to unknown host in a subnet, then sends an ARP request - * to the subnet. - * - * @param pkt inbound packet - */ - public void processPacketIn(InboundPacket pkt) { - - Ethernet ethernet = pkt.parsed(); - IPv4 ipv4 = (IPv4) ethernet.getPayload(); - - ConnectPoint connectPoint = pkt.receivedFrom(); - DeviceId deviceId = connectPoint.deviceId(); - Ip4Address destinationAddress = - Ip4Address.valueOf(ipv4.getDestinationAddress()); - Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId); - Ip4Address routerIp; - try { - routerIp = config.getRouterIp(deviceId); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting processPacketIn."); - return; - } - IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); - Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address(); - - // ICMP to the router IP or gateway IP - if (((ICMP) ipv4.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST && - (destinationAddress.equals(routerIpAddress) || - gatewayIpAddresses.contains(destinationAddress))) { - sendICMPResponse(ethernet, connectPoint); - - // ICMP for any known host - } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) { - // TODO: known host packet should not be coming to controller - resend flows? - srManager.ipHandler.forwardPackets(deviceId, destinationAddress); - - // ICMP for an unknown host in the subnet of the router - } else if (config.inSameSubnet(deviceId, destinationAddress)) { - srManager.arpHandler.sendArpRequest(deviceId, destinationAddress, connectPoint); - - // ICMP for an unknown host - } else { - log.debug("ICMP request for unknown host {} ", destinationAddress); - // Do nothing - } - } - - /** - * Sends an ICMP reply message. - * - * Note: we assume that packets sending from the edge switches to the hosts - * have untagged VLAN. - * @param icmpRequest the original ICMP request - * @param outport the output port where the ICMP reply should be sent to - */ - private void sendICMPResponse(Ethernet icmpRequest, ConnectPoint outport) { - // Note: We assume that packets arrive at the edge switches have - // untagged VLAN. - Ethernet icmpReplyEth = new Ethernet(); - - IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload(); - IPv4 icmpReplyIpv4 = new IPv4(); - - int destAddress = icmpRequestIpv4.getDestinationAddress(); - icmpReplyIpv4.setDestinationAddress(icmpRequestIpv4.getSourceAddress()); - icmpReplyIpv4.setSourceAddress(destAddress); - icmpReplyIpv4.setTtl((byte) 64); - icmpReplyIpv4.setChecksum((short) 0); - - ICMP icmpReply = new ICMP(); - icmpReply.setPayload(((ICMP) icmpRequestIpv4.getPayload()).getPayload()); - icmpReply.setIcmpType(ICMP.TYPE_ECHO_REPLY); - icmpReply.setIcmpCode(ICMP.SUBTYPE_ECHO_REPLY); - icmpReply.setChecksum((short) 0); - icmpReplyIpv4.setPayload(icmpReply); - - icmpReplyEth.setPayload(icmpReplyIpv4); - icmpReplyEth.setEtherType(Ethernet.TYPE_IPV4); - icmpReplyEth.setDestinationMACAddress(icmpRequest.getSourceMACAddress()); - icmpReplyEth.setSourceMACAddress(icmpRequest.getDestinationMACAddress()); - - Ip4Address destIpAddress = Ip4Address.valueOf(icmpReplyIpv4.getDestinationAddress()); - Ip4Address destRouterAddress = config.getRouterIpAddressForASubnetHost(destIpAddress); - int sid = config.getSegmentId(destRouterAddress); - if (sid < 0) { - log.warn("Cannot find the Segment ID for {}", destAddress); - return; - } - - sendPacketOut(outport, icmpReplyEth, sid); - - } - - private void sendPacketOut(ConnectPoint outport, Ethernet payload, int sid) { - - IPv4 ipPacket = (IPv4) payload.getPayload(); - Ip4Address destIpAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress()); - - if (sid == -1 || config.getSegmentId(payload.getDestinationMAC()) == sid || - config.inSameSubnet(outport.deviceId(), destIpAddress)) { - TrafficTreatment treatment = DefaultTrafficTreatment.builder(). - setOutput(outport.port()).build(); - OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(), - treatment, ByteBuffer.wrap(payload.serialize())); - srManager.packetService.emit(packet); - } else { - log.warn("Send a MPLS packet as a ICMP response"); - TrafficTreatment treatment = DefaultTrafficTreatment.builder() - .setOutput(outport.port()) - .build(); - - payload.setEtherType(Ethernet.MPLS_UNICAST); - MPLS mplsPkt = new MPLS(); - mplsPkt.setLabel(sid); - mplsPkt.setTtl(((IPv4) payload.getPayload()).getTtl()); - mplsPkt.setPayload(payload.getPayload()); - payload.setPayload(mplsPkt); - - OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(), - treatment, ByteBuffer.wrap(payload.serialize())); - - srManager.packetService.emit(packet); - } - } - - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java deleted file mode 100644 index d6a9dcfc..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java +++ /dev/null @@ -1,160 +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.segmentrouting; - -import org.onlab.packet.Ethernet; -import org.onlab.packet.IPv4; -import org.onlab.packet.Ip4Address; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Host; -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.segmentrouting.config.DeviceConfigNotFoundException; -import org.onosproject.segmentrouting.config.DeviceConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; - -import static com.google.common.base.Preconditions.checkNotNull; - -public class IpHandler { - - private static Logger log = LoggerFactory.getLogger(IpHandler.class); - private SegmentRoutingManager srManager; - private DeviceConfiguration config; - private ConcurrentHashMap<Ip4Address, ConcurrentLinkedQueue<IPv4>> ipPacketQueue; - - /** - * Creates an IpHandler object. - * - * @param srManager SegmentRoutingManager object - */ - public IpHandler(SegmentRoutingManager srManager) { - this.srManager = srManager; - this.config = checkNotNull(srManager.deviceConfiguration); - ipPacketQueue = new ConcurrentHashMap<>(); - } - - /** - * Processes incoming IP packets. - * - * If it is an IP packet for known host, then forward it to the host. - * If it is an IP packet for unknown host in subnet, then send an ARP request - * to the subnet. - * - * @param pkt incoming packet - */ - public void processPacketIn(InboundPacket pkt) { - Ethernet ethernet = pkt.parsed(); - IPv4 ipv4 = (IPv4) ethernet.getPayload(); - - ConnectPoint connectPoint = pkt.receivedFrom(); - DeviceId deviceId = connectPoint.deviceId(); - Ip4Address destinationAddress = - Ip4Address.valueOf(ipv4.getDestinationAddress()); - - // IP packet for know hosts - if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) { - forwardPackets(deviceId, destinationAddress); - - // IP packet for unknown host in the subnet of the router - } else if (config.inSameSubnet(deviceId, destinationAddress)) { - srManager.arpHandler.sendArpRequest(deviceId, destinationAddress, connectPoint); - - // IP packets for unknown host - } else { - log.debug("ICMP request for unknown host {} which is not in the subnet", - destinationAddress); - // Do nothing - } - } - - /** - * Adds the IP packet to a buffer. - * The packets are forwarded to corresponding destination when the destination - * MAC address is known via ARP response. - * - * @param ipPacket IP packet to add to the buffer - */ - public void addToPacketBuffer(IPv4 ipPacket) { - - // Better not buffer TCP packets due to out-of-order packet transfer - if (ipPacket.getProtocol() == IPv4.PROTOCOL_TCP) { - return; - } - - Ip4Address destIpAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress()); - - if (ipPacketQueue.get(destIpAddress) == null) { - ConcurrentLinkedQueue<IPv4> queue = new ConcurrentLinkedQueue<>(); - queue.add(ipPacket); - ipPacketQueue.put(destIpAddress, queue); - } else { - ipPacketQueue.get(destIpAddress).add(ipPacket); - } - } - - /** - * Forwards IP packets in the buffer to the destination IP address. - * It is called when the controller finds the destination MAC address - * via ARP responses. - * - * @param deviceId switch device ID - * @param destIpAddress destination IP address - */ - public void forwardPackets(DeviceId deviceId, Ip4Address destIpAddress) { - if (ipPacketQueue.get(destIpAddress) == null) { - return; - } - - for (IPv4 ipPacket : ipPacketQueue.get(destIpAddress)) { - Ip4Address destAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress()); - if (config.inSameSubnet(deviceId, destAddress)) { - ipPacket.setTtl((byte) (ipPacket.getTtl() - 1)); - ipPacket.setChecksum((short) 0); - for (Host dest: srManager.hostService.getHostsByIp(destIpAddress)) { - Ethernet eth = new Ethernet(); - eth.setDestinationMACAddress(dest.mac()); - try { - eth.setSourceMACAddress(config.getDeviceMac(deviceId)); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() - + " Skipping forwardPackets for this destination."); - continue; - } - eth.setEtherType(Ethernet.TYPE_IPV4); - eth.setPayload(ipPacket); - - TrafficTreatment treatment = DefaultTrafficTreatment.builder(). - setOutput(dest.location().port()).build(); - OutboundPacket packet = new DefaultOutboundPacket(deviceId, - treatment, ByteBuffer.wrap(eth.serialize())); - srManager.packetService.emit(packet); - ipPacketQueue.get(destIpAddress).remove(ipPacket); - } - ipPacketQueue.get(destIpAddress).remove(ipPacket); - } - } - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/Policy.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/Policy.java deleted file mode 100644 index 2e417959..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/Policy.java +++ /dev/null @@ -1,96 +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.segmentrouting; - -/** - * Interface for Segment Routing Policy. - */ -public interface Policy { - /** - * Enums for policy type. - */ - enum Type { - // Tunnel flow policy type - TUNNEL_FLOW, - - // Load balancing policy type - LOADBALANCE, - - // policy to avoid specific routers or links - AVOID, - - // Access Control policy type - DENY - } - - /** - * Returns the policy ID. - * - * @return policy ID - */ - String id(); - - /** - * Returns the priority of the policy. - * - * @return priority - */ - int priority(); - - /** - * Returns the policy type. - * - * @return policy type - */ - Type type(); - - /** - * Returns the source IP address of the policy. - * - * @return source IP address - */ - String srcIp(); - - /** - * Returns the destination IP address of the policy. - * - * @return destination IP address - */ - String dstIp(); - - /** - * Returns the IP protocol of the policy. - * - * @return IP protocol - */ - String ipProto(); - - /** - * Returns the source port of the policy. - * - * @return source port - */ - short srcPort(); - - /** - * Returns the destination of the policy. - * - * @return destination port - */ - short dstPort(); - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java deleted file mode 100644 index 0a4c26d9..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java +++ /dev/null @@ -1,216 +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.segmentrouting; - -import org.onlab.packet.Ethernet; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.TpPort; -import org.onosproject.cli.net.IpProtocol; -import org.onosproject.core.ApplicationId; -import org.onosproject.net.DeviceId; -import org.onosproject.net.flow.DefaultTrafficSelector; -import org.onosproject.net.flow.TrafficSelector; -import org.onosproject.net.flowobjective.DefaultForwardingObjective; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.flowobjective.ForwardingObjective; -import org.onosproject.segmentrouting.config.DeviceConfiguration; -import org.onosproject.store.service.EventuallyConsistentMap; -import org.slf4j.Logger; - -import java.util.List; -import java.util.stream.Collectors; - -import static org.slf4j.LoggerFactory.getLogger; - -/** - * Segment Routing Policy Handler. - */ -public class PolicyHandler { - - protected final Logger log = getLogger(getClass()); - - private ApplicationId appId; - private DeviceConfiguration deviceConfiguration; - private FlowObjectiveService flowObjectiveService; - private TunnelHandler tunnelHandler; - private final EventuallyConsistentMap<String, Policy> policyStore; - - public enum Result { - SUCCESS, - POLICY_EXISTS, - ID_EXISTS, - TUNNEL_NOT_FOUND, - POLICY_NOT_FOUND, - UNSUPPORTED_TYPE - } - - /** - * Creates a reference. - * - * @param appId segment routing application ID - * @param deviceConfiguration DeviceConfiguration reference - * @param flowObjectiveService FlowObjectiveService reference - * @param tunnelHandler tunnel handler reference - * @param policyStore policy store - */ - public PolicyHandler(ApplicationId appId, - DeviceConfiguration deviceConfiguration, - FlowObjectiveService flowObjectiveService, - TunnelHandler tunnelHandler, - EventuallyConsistentMap<String, Policy> policyStore) { - this.appId = appId; - this.deviceConfiguration = deviceConfiguration; - this.flowObjectiveService = flowObjectiveService; - this.tunnelHandler = tunnelHandler; - this.policyStore = policyStore; - } - - /** - * Returns the policies. - * - * @return policy list - */ - public List<Policy> getPolicies() { - return policyStore.values() - .stream() - .filter(policy -> policy instanceof TunnelPolicy) - .map(policy -> new TunnelPolicy((TunnelPolicy) policy)) - .collect(Collectors.toList()); - } - - /** - * Creates a policy using the policy information given. - * @param policy policy reference to create - * @return ID_EXISTS if the same policy ID exists, - * POLICY_EXISTS if the same policy exists, TUNNEL_NOT_FOUND if the tunnel - * does not exists, UNSUPPORTED_TYPE if the policy type is not supported, - * SUCCESS if the policy is created successfully - */ - public Result createPolicy(Policy policy) { - - if (policyStore.containsKey(policy.id())) { - log.warn("The policy id {} exists already", policy.id()); - return Result.ID_EXISTS; - } - - if (policyStore.containsValue(policy)) { - log.warn("The same policy exists already"); - return Result.POLICY_EXISTS; - } - - if (policy.type() == Policy.Type.TUNNEL_FLOW) { - - TunnelPolicy tunnelPolicy = (TunnelPolicy) policy; - Tunnel tunnel = tunnelHandler.getTunnel(tunnelPolicy.tunnelId()); - if (tunnel == null) { - return Result.TUNNEL_NOT_FOUND; - } - - ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective - .builder() - .fromApp(appId) - .makePermanent() - .nextStep(tunnel.groupId()) - .withPriority(tunnelPolicy.priority()) - .withSelector(buildSelector(policy)) - .withFlag(ForwardingObjective.Flag.VERSATILE); - - DeviceId source = deviceConfiguration.getDeviceId(tunnel.labelIds().get(0)); - flowObjectiveService.forward(source, fwdBuilder.add()); - - } else { - log.warn("Policy type {} is not supported yet.", policy.type()); - return Result.UNSUPPORTED_TYPE; - } - - policyStore.put(policy.id(), policy); - - return Result.SUCCESS; - } - - /** - * Removes the policy given. - * - * @param policyInfo policy information to remove - * @return POLICY_NOT_FOUND if the policy to remove does not exists, - * SUCCESS if it is removed successfully - */ - public Result removePolicy(Policy policyInfo) { - - if (policyStore.get(policyInfo.id()) != null) { - Policy policy = policyStore.get(policyInfo.id()); - if (policy.type() == Policy.Type.TUNNEL_FLOW) { - TunnelPolicy tunnelPolicy = (TunnelPolicy) policy; - Tunnel tunnel = tunnelHandler.getTunnel(tunnelPolicy.tunnelId()); - - ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective - .builder() - .fromApp(appId) - .makePermanent() - .withSelector(buildSelector(policy)) - .withPriority(tunnelPolicy.priority()) - .nextStep(tunnel.groupId()) - .withFlag(ForwardingObjective.Flag.VERSATILE); - - DeviceId source = deviceConfiguration.getDeviceId(tunnel.labelIds().get(0)); - flowObjectiveService.forward(source, fwdBuilder.remove()); - - policyStore.remove(policyInfo.id()); - } - } else { - log.warn("Policy {} was not found", policyInfo.id()); - return Result.POLICY_NOT_FOUND; - } - - return Result.SUCCESS; - } - - - private TrafficSelector buildSelector(Policy policy) { - - TrafficSelector.Builder tsb = DefaultTrafficSelector.builder(); - tsb.matchEthType(Ethernet.TYPE_IPV4); - if (policy.dstIp() != null && !policy.dstIp().isEmpty()) { - tsb.matchIPDst(IpPrefix.valueOf(policy.dstIp())); - } - if (policy.srcIp() != null && !policy.srcIp().isEmpty()) { - tsb.matchIPSrc(IpPrefix.valueOf(policy.srcIp())); - } - if (policy.ipProto() != null && !policy.ipProto().isEmpty()) { - Short ipProto = IpProtocol.valueOf(policy.ipProto()).value(); - tsb.matchIPProtocol(ipProto.byteValue()); - if (IpProtocol.valueOf(policy.ipProto()).equals(IpProtocol.TCP)) { - if (policy.srcPort() != 0) { - tsb.matchTcpSrc(TpPort.tpPort(policy.srcPort())); - } - if (policy.dstPort() != 0) { - tsb.matchTcpDst(TpPort.tpPort(policy.dstPort())); - } - } else if (IpProtocol.valueOf(policy.ipProto()).equals(IpProtocol.UDP)) { - if (policy.srcPort() != 0) { - tsb.matchUdpSrc(TpPort.tpPort(policy.srcPort())); - } - if (policy.dstPort() != 0) { - tsb.matchUdpDst(TpPort.tpPort(policy.dstPort())); - } - } - } - - return tsb.build(); - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java deleted file mode 100644 index d4aa770c..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java +++ /dev/null @@ -1,633 +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.segmentrouting; - -import org.onlab.packet.EthType; -import org.onlab.packet.Ethernet; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.MacAddress; -import org.onlab.packet.MplsLabel; -import org.onlab.packet.VlanId; -import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; -import org.onosproject.segmentrouting.config.DeviceConfiguration; -import org.onosproject.segmentrouting.grouphandler.NeighborSet; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Port; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.DefaultTrafficSelector; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.TrafficSelector; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flow.criteria.Criteria; -import org.onosproject.net.flowobjective.DefaultFilteringObjective; -import org.onosproject.net.flowobjective.DefaultForwardingObjective; -import org.onosproject.net.flowobjective.FilteringObjective; -import org.onosproject.net.flowobjective.ForwardingObjective; -import org.onosproject.net.flowobjective.Objective; -import org.onosproject.net.flowobjective.ObjectiveError; -import org.onosproject.net.flowobjective.ForwardingObjective.Builder; -import org.onosproject.net.flowobjective.ForwardingObjective.Flag; -import org.onosproject.net.flowobjective.ObjectiveContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.atomic.AtomicLong; - -import static com.google.common.base.Preconditions.checkNotNull; - -public class RoutingRulePopulator { - private static final Logger log = LoggerFactory - .getLogger(RoutingRulePopulator.class); - - private AtomicLong rulePopulationCounter; - private SegmentRoutingManager srManager; - private DeviceConfiguration config; - - private static final int HIGHEST_PRIORITY = 0xffff; - private static final long OFPP_MAX = 0xffffff00L; - - - /** - * Creates a RoutingRulePopulator object. - * - * @param srManager segment routing manager reference - */ - public RoutingRulePopulator(SegmentRoutingManager srManager) { - this.srManager = srManager; - this.config = checkNotNull(srManager.deviceConfiguration); - this.rulePopulationCounter = new AtomicLong(0); - } - - /** - * Resets the population counter. - */ - public void resetCounter() { - rulePopulationCounter.set(0); - } - - /** - * Returns the number of rules populated. - * - * @return number of rules - */ - public long getCounter() { - return rulePopulationCounter.get(); - } - - /** - * Populates IP flow rules for specific hosts directly connected to the - * switch. - * - * @param deviceId switch ID to set the rules - * @param hostIp host IP address - * @param hostMac host MAC address - * @param outPort port where the host is connected - */ - public void populateIpRuleForHost(DeviceId deviceId, Ip4Address hostIp, - MacAddress hostMac, PortNumber outPort) { - log.debug("Populate IP table entry for host {} at {}:{}", - hostIp, deviceId, outPort); - ForwardingObjective.Builder fwdBuilder; - try { - fwdBuilder = getForwardingObjectiveBuilder( - deviceId, hostIp, hostMac, outPort); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting populateIpRuleForHost."); - return; - } - srManager.flowObjectiveService. - forward(deviceId, fwdBuilder.add(new SRObjectiveContext(deviceId, - SRObjectiveContext.ObjectiveType.FORWARDING))); - rulePopulationCounter.incrementAndGet(); - } - - public void revokeIpRuleForHost(DeviceId deviceId, Ip4Address hostIp, - MacAddress hostMac, PortNumber outPort) { - log.debug("Revoke IP table entry for host {} at {}:{}", - hostIp, deviceId, outPort); - ForwardingObjective.Builder fwdBuilder; - try { - fwdBuilder = getForwardingObjectiveBuilder( - deviceId, hostIp, hostMac, outPort); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting revokeIpRuleForHost."); - return; - } - srManager.flowObjectiveService. - forward(deviceId, fwdBuilder.remove(new SRObjectiveContext(deviceId, - SRObjectiveContext.ObjectiveType.FORWARDING))); - } - - private ForwardingObjective.Builder getForwardingObjectiveBuilder( - DeviceId deviceId, Ip4Address hostIp, - MacAddress hostMac, PortNumber outPort) - throws DeviceConfigNotFoundException { - MacAddress deviceMac; - deviceMac = config.getDeviceMac(deviceId); - - TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); - TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); - - sbuilder.matchEthType(Ethernet.TYPE_IPV4); - sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH)); - TrafficSelector selector = sbuilder.build(); - - tbuilder.deferred() - .setEthDst(hostMac) - .setEthSrc(deviceMac) - .setOutput(outPort); - TrafficTreatment treatment = tbuilder.build(); - - // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed. - // for switch pipelines that need it, provide outgoing vlan as metadata - VlanId outvlan = null; - Ip4Prefix subnet = srManager.deviceConfiguration.getPortSubnet(deviceId, outPort); - if (subnet == null) { - outvlan = VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET); - } else { - outvlan = srManager.getSubnetAssignedVlanId(deviceId, subnet); - } - TrafficSelector meta = DefaultTrafficSelector.builder() - .matchVlanId(outvlan).build(); - int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outPort, - treatment, meta); - - return DefaultForwardingObjective.builder() - .withSelector(selector) - .nextStep(portNextObjId) - .fromApp(srManager.appId).makePermanent() - .withPriority(100).withFlag(ForwardingObjective.Flag.SPECIFIC); - } - - /** - * Populates IP flow rules for the subnets of the destination router. - * - * @param deviceId switch ID to set the rules - * @param subnets subnet information - * @param destSw destination switch ID - * @param nextHops next hop switch ID list - * @return true if all rules are set successfully, false otherwise - */ - public boolean populateIpRuleForSubnet(DeviceId deviceId, - Set<Ip4Prefix> subnets, - DeviceId destSw, - Set<DeviceId> nextHops) { - - for (IpPrefix subnet : subnets) { - if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) { - return false; - } - } - - return true; - } - - /** - * Populates IP flow rules for the router IP address. - * - * @param deviceId target device ID to set the rules - * @param ipPrefix the IP address of the destination router - * @param destSw device ID of the destination router - * @param nextHops next hop switch ID list - * @return true if all rules are set successfully, false otherwise - */ - public boolean populateIpRuleForRouter(DeviceId deviceId, - IpPrefix ipPrefix, DeviceId destSw, - Set<DeviceId> nextHops) { - int segmentId; - try { - segmentId = config.getSegmentId(destSw); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting populateIpRuleForRouter."); - return false; - } - - TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); - sbuilder.matchIPDst(ipPrefix); - sbuilder.matchEthType(Ethernet.TYPE_IPV4); - TrafficSelector selector = sbuilder.build(); - - TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); - NeighborSet ns; - TrafficTreatment treatment; - - // If the next hop is the same as the final destination, then MPLS label - // is not set. - if (nextHops.size() == 1 && nextHops.toArray()[0].equals(destSw)) { - tbuilder.immediate().decNwTtl(); - ns = new NeighborSet(nextHops); - treatment = tbuilder.build(); - } else { - ns = new NeighborSet(nextHops, segmentId); - treatment = null; - } - - // setup metadata to pass to nextObjective - indicate the vlan on egress - // if needed by the switch pipeline. Since neighbor sets are always to - // other neighboring routers, there is no subnet assigned on those ports. - TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder(selector); - metabuilder.matchVlanId( - VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET)); - - int nextId = srManager.getNextObjectiveId(deviceId, ns, metabuilder.build()); - if (nextId <= 0) { - log.warn("No next objective in {} for ns: {}", deviceId, ns); - return false; - } - - ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective - .builder() - .fromApp(srManager.appId) - .makePermanent() - .nextStep(nextId) - .withSelector(selector) - .withPriority(100) - .withFlag(ForwardingObjective.Flag.SPECIFIC); - if (treatment != null) { - fwdBuilder.withTreatment(treatment); - } - log.debug("Installing IPv4 forwarding objective " - + "for router IP/subnet {} in switch {}", - ipPrefix, - deviceId); - srManager.flowObjectiveService. - forward(deviceId, - fwdBuilder. - add(new SRObjectiveContext(deviceId, - SRObjectiveContext.ObjectiveType.FORWARDING))); - rulePopulationCounter.incrementAndGet(); - - return true; - } - - /** - * Populates MPLS flow rules to all routers. - * - * @param deviceId target device ID of the switch to set the rules - * @param destSwId destination switch device ID - * @param nextHops next hops switch ID list - * @return true if all rules are set successfully, false otherwise - */ - public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId, - Set<DeviceId> nextHops) { - int segmentId; - try { - segmentId = config.getSegmentId(destSwId); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting populateMplsRule."); - return false; - } - - TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); - List<ForwardingObjective.Builder> fwdObjBuilders = new ArrayList<>(); - - // TODO Handle the case of Bos == false - sbuilder.matchEthType(Ethernet.MPLS_UNICAST); - sbuilder.matchMplsLabel(MplsLabel.mplsLabel(segmentId)); - TrafficSelector selector = sbuilder.build(); - - // setup metadata to pass to nextObjective - indicate the vlan on egress - // if needed by the switch pipeline. Since mpls next-hops are always to - // other neighboring routers, there is no subnet assigned on those ports. - TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder(selector); - metabuilder.matchVlanId( - VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET)); - - // If the next hop is the destination router for the segment, do pop - if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) { - log.debug("populateMplsRule: Installing MPLS forwarding objective for " - + "label {} in switch {} with pop", segmentId, deviceId); - - // bos pop case (php) - ForwardingObjective.Builder fwdObjBosBuilder = - getMplsForwardingObjective(deviceId, - nextHops, - true, - true, - metabuilder.build()); - if (fwdObjBosBuilder == null) { - return false; - } - fwdObjBuilders.add(fwdObjBosBuilder); - - // XXX not-bos pop case, SR app multi-label not implemented yet - /*ForwardingObjective.Builder fwdObjNoBosBuilder = - getMplsForwardingObjective(deviceId, - nextHops, - true, - false);*/ - - } else { - // next hop is not destination, SR CONTINUE case (swap with self) - log.debug("Installing MPLS forwarding objective for " - + "label {} in switch {} without pop", segmentId, deviceId); - - // continue case with bos - this does get triggered in edge routers - // and in core routers - driver can handle depending on availability - // of MPLS ECMP or not - ForwardingObjective.Builder fwdObjBosBuilder = - getMplsForwardingObjective(deviceId, - nextHops, - false, - true, - metabuilder.build()); - if (fwdObjBosBuilder == null) { - return false; - } - fwdObjBuilders.add(fwdObjBosBuilder); - - // XXX continue case with not-bos - SR app multi label not implemented yet - // also requires MPLS ECMP - /*ForwardingObjective.Builder fwdObjNoBosBuilder = - getMplsForwardingObjective(deviceId, - nextHops, - false, - false); */ - - } - - for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) { - ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId) - .makePermanent()).withSelector(selector) - .withPriority(100)) - .withFlag(ForwardingObjective.Flag.SPECIFIC); - srManager.flowObjectiveService. - forward(deviceId, - fwdObjBuilder. - add(new SRObjectiveContext(deviceId, - SRObjectiveContext.ObjectiveType.FORWARDING))); - rulePopulationCounter.incrementAndGet(); - } - - return true; - } - - private ForwardingObjective.Builder getMplsForwardingObjective( - DeviceId deviceId, - Set<DeviceId> nextHops, - boolean phpRequired, - boolean isBos, - TrafficSelector meta) { - - ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective - .builder().withFlag(ForwardingObjective.Flag.SPECIFIC); - - TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); - - if (phpRequired) { - // php case - pop should always be flow-action - log.debug("getMplsForwardingObjective: php required"); - tbuilder.deferred().copyTtlIn(); - if (isBos) { - tbuilder.deferred().popMpls(EthType.EtherType.IPV4.ethType()) - .decNwTtl(); - } else { - tbuilder.deferred().popMpls(EthType.EtherType.MPLS_UNICAST.ethType()) - .decMplsTtl(); - } - } else { - // swap with self case - SR CONTINUE - log.debug("getMplsForwardingObjective: php not required"); - tbuilder.deferred().decMplsTtl(); - } - - // All forwarding is via ECMP group, the metadata informs the driver - // that the next-Objective will be used by MPLS flows. In other words, - // MPLS ECMP is requested. It is up to the driver to decide if these - // packets will be hashed or not. - fwdBuilder.withTreatment(tbuilder.build()); - NeighborSet ns = new NeighborSet(nextHops); - log.debug("Trying to get a nextObjid for mpls rule on device:{} to ns:{}", - deviceId, ns); - - int nextId = srManager.getNextObjectiveId(deviceId, ns, meta); - if (nextId <= 0) { - log.warn("No next objective in {} for ns: {}", deviceId, ns); - return null; - } - - fwdBuilder.nextStep(nextId); - return fwdBuilder; - } - - /** - * Creates a filtering objective to permit all untagged packets with a - * dstMac corresponding to the router's MAC address. For those pipelines - * that need to internally assign vlans to untagged packets, this method - * provides per-subnet vlan-ids as metadata. - * <p> - * Note that the vlan assignment is only done by the master-instance for a switch. - * However we send the filtering objective from slave-instances as well, so - * that drivers can obtain other information (like Router MAC and IP). - * - * @param deviceId the switch dpid for the router - */ - public void populateRouterMacVlanFilters(DeviceId deviceId) { - log.debug("Installing per-port filtering objective for untagged " - + "packets in device {}", deviceId); - - MacAddress deviceMac; - try { - deviceMac = config.getDeviceMac(deviceId); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting populateRouterMacVlanFilters."); - return; - } - - for (Port port : srManager.deviceService.getPorts(deviceId)) { - if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) { - Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number()); - VlanId assignedVlan = (portSubnet == null) - ? VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET) - : srManager.getSubnetAssignedVlanId(deviceId, portSubnet); - - FilteringObjective.Builder fob = DefaultFilteringObjective.builder(); - fob.withKey(Criteria.matchInPort(port.number())) - .addCondition(Criteria.matchEthDst(deviceMac)) - .addCondition(Criteria.matchVlanId(VlanId.NONE)); - // vlan assignment is valid only if this instance is master - if (srManager.mastershipService.isLocalMaster(deviceId)) { - TrafficTreatment tt = DefaultTrafficTreatment.builder() - .pushVlan().setVlanId(assignedVlan).build(); - fob.withMeta(tt); - } - fob.permit().fromApp(srManager.appId); - srManager.flowObjectiveService. - filter(deviceId, fob.add(new SRObjectiveContext(deviceId, - SRObjectiveContext.ObjectiveType.FILTER))); - } - } - } - - /** - * Creates a forwarding objective to punt all IP packets, destined to the - * router's port IP addresses, to the controller. Note that the input - * port should not be matched on, as these packets can come from any input. - * Furthermore, these are applied only by the master instance. - * - * @param deviceId the switch dpid for the router - */ - public void populateRouterIpPunts(DeviceId deviceId) { - Ip4Address routerIp; - try { - routerIp = config.getRouterIp(deviceId); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting populateRouterIpPunts."); - return; - } - - if (!srManager.mastershipService.isLocalMaster(deviceId)) { - log.debug("Not installing port-IP punts - not the master for dev:{} ", - deviceId); - return; - } - ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder(); - Set<Ip4Address> allIps = new HashSet<Ip4Address>(config.getPortIPs(deviceId)); - allIps.add(routerIp); - for (Ip4Address ipaddr : allIps) { - TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); - TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); - sbuilder.matchEthType(Ethernet.TYPE_IPV4); - sbuilder.matchIPDst(IpPrefix.valueOf(ipaddr, - IpPrefix.MAX_INET_MASK_LENGTH)); - tbuilder.setOutput(PortNumber.CONTROLLER); - puntIp.withSelector(sbuilder.build()); - puntIp.withTreatment(tbuilder.build()); - puntIp.withFlag(Flag.VERSATILE) - .withPriority(HIGHEST_PRIORITY) - .makePermanent() - .fromApp(srManager.appId); - log.debug("Installing forwarding objective to punt port IP addresses"); - srManager.flowObjectiveService. - forward(deviceId, - puntIp.add(new SRObjectiveContext(deviceId, - SRObjectiveContext.ObjectiveType.FORWARDING))); - } - } - - /** - * Creates a forwarding objective to punt all IP packets, destined to the - * router's port IP addresses, to the controller. Note that the input - * port should not be matched on, as these packets can come from any input. - * Furthermore, these are applied only by the master instance. - * - * @param deviceId the switch dpid for the router - */ - public void populateArpPunts(DeviceId deviceId) { - if (!srManager.mastershipService.isLocalMaster(deviceId)) { - log.debug("Not installing port-IP punts - not the master for dev:{} ", - deviceId); - return; - } - - ForwardingObjective.Builder puntArp = DefaultForwardingObjective.builder(); - TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); - TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); - sbuilder.matchEthType(Ethernet.TYPE_ARP); - tbuilder.setOutput(PortNumber.CONTROLLER); - puntArp.withSelector(sbuilder.build()); - puntArp.withTreatment(tbuilder.build()); - puntArp.withFlag(Flag.VERSATILE) - .withPriority(HIGHEST_PRIORITY) - .makePermanent() - .fromApp(srManager.appId); - log.debug("Installing forwarding objective to punt ARPs"); - srManager.flowObjectiveService. - forward(deviceId, - puntArp.add(new SRObjectiveContext(deviceId, - SRObjectiveContext.ObjectiveType.FORWARDING))); - } - - /** - * Populates a forwarding objective to send packets that miss other high - * priority Bridging Table entries to a group that contains all ports of - * its subnet. - * - * Note: We assume that packets sending from the edge switches to the hosts - * have untagged VLAN. - * The VLAN tag will be popped later in the flooding group. - * - * @param deviceId switch ID to set the rules - */ - public void populateSubnetBroadcastRule(DeviceId deviceId) { - config.getSubnets(deviceId).forEach(subnet -> { - int nextId = srManager.getSubnetNextObjectiveId(deviceId, subnet); - VlanId vlanId = srManager.getSubnetAssignedVlanId(deviceId, subnet); - - if (nextId < 0 || vlanId == null) { - log.error("Cannot install subnet broadcast rule in dev:{} due" - + "to vlanId:{} or nextId:{}", vlanId, nextId); - return; - } - - /* Driver should treat objective with MacAddress.NONE as the - * subnet broadcast rule - */ - TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); - sbuilder.matchVlanId(vlanId); - sbuilder.matchEthDst(MacAddress.NONE); - - ForwardingObjective.Builder fob = DefaultForwardingObjective.builder(); - fob.withFlag(Flag.SPECIFIC) - .withSelector(sbuilder.build()) - .nextStep(nextId) - .withPriority(5) - .fromApp(srManager.appId) - .makePermanent(); - - srManager.flowObjectiveService.forward( - deviceId, - fob.add(new SRObjectiveContext( - deviceId, - SRObjectiveContext.ObjectiveType.FORWARDING) - ) - ); - }); - } - - - private static class SRObjectiveContext implements ObjectiveContext { - enum ObjectiveType { - FILTER, - FORWARDING - } - final DeviceId deviceId; - final ObjectiveType type; - - SRObjectiveContext(DeviceId deviceId, ObjectiveType type) { - this.deviceId = deviceId; - this.type = type; - } - @Override - public void onSuccess(Objective objective) { - log.debug("{} objective operation successful in device {}", - type.name(), deviceId); - } - - @Override - public void onError(Objective objective, ObjectiveError error) { - log.warn("{} objective {} operation failed with error: {} in device {}", - type.name(), objective, error, deviceId); - } - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java deleted file mode 100644 index 62722f02..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java +++ /dev/null @@ -1,1042 +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.segmentrouting; - -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onlab.packet.Ethernet; -import org.onlab.packet.MacAddress; -import org.onlab.packet.VlanId; -import org.onlab.packet.IPv4; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.IpAddress; -import org.onlab.packet.IpPrefix; -import org.onlab.util.KryoNamespace; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.event.Event; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.PortNumber; -import org.onosproject.net.config.ConfigFactory; -import org.onosproject.net.config.NetworkConfigEvent; -import org.onosproject.net.config.NetworkConfigRegistry; -import org.onosproject.net.config.NetworkConfigListener; -import org.onosproject.net.config.basics.SubjectFactories; -import org.onosproject.net.flow.DefaultTrafficSelector; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.TrafficSelector; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flowobjective.DefaultForwardingObjective; -import org.onosproject.net.flowobjective.ForwardingObjective; -import org.onosproject.net.flowobjective.Objective; -import org.onosproject.net.flowobjective.ObjectiveContext; -import org.onosproject.net.flowobjective.ObjectiveError; -import org.onosproject.net.host.HostEvent; -import org.onosproject.net.host.HostListener; -import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; -import org.onosproject.segmentrouting.config.DeviceConfiguration; -import org.onosproject.segmentrouting.config.SegmentRoutingConfig; -import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; -import org.onosproject.segmentrouting.grouphandler.NeighborSet; -import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey; -import org.onosproject.segmentrouting.grouphandler.PortNextObjectiveStoreKey; -import org.onosproject.mastership.MastershipService; -import org.onosproject.net.Device; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Link; -import org.onosproject.net.Port; -import org.onosproject.net.device.DeviceEvent; -import org.onosproject.net.device.DeviceListener; -import org.onosproject.net.device.DeviceService; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.host.HostService; -import org.onosproject.net.intent.IntentService; -import org.onosproject.net.link.LinkEvent; -import org.onosproject.net.link.LinkListener; -import org.onosproject.net.link.LinkService; -import org.onosproject.net.packet.InboundPacket; -import org.onosproject.net.packet.PacketContext; -import org.onosproject.net.packet.PacketProcessor; -import org.onosproject.net.packet.PacketService; -import org.onosproject.net.topology.TopologyService; -import org.onosproject.segmentrouting.grouphandler.SubnetNextObjectiveStoreKey; -import org.onosproject.store.service.EventuallyConsistentMap; -import org.onosproject.store.service.EventuallyConsistentMapBuilder; -import org.onosproject.store.service.StorageService; -import org.onosproject.store.service.WallClockTimestamp; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.URI; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -@Service -@Component(immediate = true) -public class SegmentRoutingManager implements SegmentRoutingService { - - private static Logger log = LoggerFactory - .getLogger(SegmentRoutingManager.class); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected CoreService coreService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected TopologyService topologyService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected PacketService packetService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected IntentService intentService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected HostService hostService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DeviceService deviceService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected FlowObjectiveService flowObjectiveService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected LinkService linkService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected MastershipService mastershipService; - - protected ArpHandler arpHandler = null; - protected IcmpHandler icmpHandler = null; - protected IpHandler ipHandler = null; - protected RoutingRulePopulator routingRulePopulator = null; - protected ApplicationId appId; - protected DeviceConfiguration deviceConfiguration = null; - - private DefaultRoutingHandler defaultRoutingHandler = null; - private TunnelHandler tunnelHandler = null; - private PolicyHandler policyHandler = null; - private InternalPacketProcessor processor = null; - private InternalLinkListener linkListener = null; - private InternalDeviceListener deviceListener = null; - private InternalEventHandler eventHandler = new InternalEventHandler(); - - private ScheduledExecutorService executorService = Executors - .newScheduledThreadPool(1); - - @SuppressWarnings("unused") - private static ScheduledFuture<?> eventHandlerFuture = null; - @SuppressWarnings("rawtypes") - private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>(); - private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = - new ConcurrentHashMap<DeviceId, DefaultGroupHandler>(); - // Per device next objective ID store with (device id + neighbor set) as key - private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer> - nsNextObjStore = null; - // Per device next objective ID store with (device id + subnet) as key - private EventuallyConsistentMap<SubnetNextObjectiveStoreKey, Integer> - subnetNextObjStore = null; - // Per device next objective ID store with (device id + port) as key - private EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer> - portNextObjStore = null; - // Per device, per-subnet assigned-vlans store, with (device id + subnet - // IPv4 prefix) as key - private EventuallyConsistentMap<SubnetAssignedVidStoreKey, VlanId> - subnetVidStore = null; - private EventuallyConsistentMap<String, Tunnel> tunnelStore = null; - private EventuallyConsistentMap<String, Policy> policyStore = null; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected StorageService storageService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected NetworkConfigRegistry cfgService; - - private final InternalConfigListener cfgListener = - new InternalConfigListener(this); - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private final ConfigFactory cfgFactory = - new ConfigFactory(SubjectFactories.DEVICE_SUBJECT_FACTORY, - SegmentRoutingConfig.class, - "segmentrouting") { - @Override - public SegmentRoutingConfig createConfig() { - return new SegmentRoutingConfig(); - } - }; - - private final InternalHostListener hostListener = new InternalHostListener(); - - private Object threadSchedulerLock = new Object(); - private static int numOfEventsQueued = 0; - private static int numOfEventsExecuted = 0; - private static int numOfHandlerExecution = 0; - private static int numOfHandlerScheduled = 0; - - private KryoNamespace.Builder kryoBuilder = null; - - private static final short ASSIGNED_VLAN_START = 4093; - public static final short ASSIGNED_VLAN_NO_SUBNET = 4094; - - @Activate - protected void activate() { - appId = coreService - .registerApplication("org.onosproject.segmentrouting"); - - kryoBuilder = new KryoNamespace.Builder() - .register(NeighborSetNextObjectiveStoreKey.class, - SubnetNextObjectiveStoreKey.class, - SubnetAssignedVidStoreKey.class, - NeighborSet.class, - DeviceId.class, - URI.class, - WallClockTimestamp.class, - org.onosproject.cluster.NodeId.class, - HashSet.class, - Tunnel.class, - DefaultTunnel.class, - Policy.class, - TunnelPolicy.class, - Policy.Type.class, - VlanId.class, - Ip4Address.class, - Ip4Prefix.class, - IpAddress.Version.class, - ConnectPoint.class - ); - - log.debug("Creating EC map nsnextobjectivestore"); - EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer> - nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder(); - nsNextObjStore = nsNextObjMapBuilder - .withName("nsnextobjectivestore") - .withSerializer(kryoBuilder) - .withTimestampProvider((k, v) -> new WallClockTimestamp()) - .build(); - log.trace("Current size {}", nsNextObjStore.size()); - - log.debug("Creating EC map subnetnextobjectivestore"); - EventuallyConsistentMapBuilder<SubnetNextObjectiveStoreKey, Integer> - subnetNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder(); - subnetNextObjStore = subnetNextObjMapBuilder - .withName("subnetnextobjectivestore") - .withSerializer(kryoBuilder) - .withTimestampProvider((k, v) -> new WallClockTimestamp()) - .build(); - - log.debug("Creating EC map subnetnextobjectivestore"); - EventuallyConsistentMapBuilder<PortNextObjectiveStoreKey, Integer> - portNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder(); - portNextObjStore = portNextObjMapBuilder - .withName("portnextobjectivestore") - .withSerializer(kryoBuilder) - .withTimestampProvider((k, v) -> new WallClockTimestamp()) - .build(); - - EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder = - storageService.eventuallyConsistentMapBuilder(); - tunnelStore = tunnelMapBuilder - .withName("tunnelstore") - .withSerializer(kryoBuilder) - .withTimestampProvider((k, v) -> new WallClockTimestamp()) - .build(); - - EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder = - storageService.eventuallyConsistentMapBuilder(); - policyStore = policyMapBuilder - .withName("policystore") - .withSerializer(kryoBuilder) - .withTimestampProvider((k, v) -> new WallClockTimestamp()) - .build(); - - EventuallyConsistentMapBuilder<SubnetAssignedVidStoreKey, VlanId> - subnetVidStoreMapBuilder = storageService.eventuallyConsistentMapBuilder(); - subnetVidStore = subnetVidStoreMapBuilder - .withName("subnetvidstore") - .withSerializer(kryoBuilder) - .withTimestampProvider((k, v) -> new WallClockTimestamp()) - .build(); - - cfgService.addListener(cfgListener); - cfgService.registerConfigFactory(cfgFactory); - - hostService.addListener(hostListener); - - processor = new InternalPacketProcessor(); - linkListener = new InternalLinkListener(); - deviceListener = new InternalDeviceListener(); - - packetService.addProcessor(processor, PacketProcessor.director(2)); - linkService.addListener(linkListener); - deviceService.addListener(deviceListener); - - cfgListener.configureNetwork(); - - log.info("Started"); - } - - @Deactivate - protected void deactivate() { - cfgService.removeListener(cfgListener); - cfgService.unregisterConfigFactory(cfgFactory); - - packetService.removeProcessor(processor); - linkService.removeListener(linkListener); - deviceService.removeListener(deviceListener); - processor = null; - linkListener = null; - deviceService = null; - - groupHandlerMap.clear(); - - log.info("Stopped"); - } - - - @Override - public List<Tunnel> getTunnels() { - return tunnelHandler.getTunnels(); - } - - @Override - public TunnelHandler.Result createTunnel(Tunnel tunnel) { - return tunnelHandler.createTunnel(tunnel); - } - - @Override - public TunnelHandler.Result removeTunnel(Tunnel tunnel) { - for (Policy policy: policyHandler.getPolicies()) { - if (policy.type() == Policy.Type.TUNNEL_FLOW) { - TunnelPolicy tunnelPolicy = (TunnelPolicy) policy; - if (tunnelPolicy.tunnelId().equals(tunnel.id())) { - log.warn("Cannot remove the tunnel used by a policy"); - return TunnelHandler.Result.TUNNEL_IN_USE; - } - } - } - return tunnelHandler.removeTunnel(tunnel); - } - - @Override - public PolicyHandler.Result removePolicy(Policy policy) { - return policyHandler.removePolicy(policy); - } - - @Override - public PolicyHandler.Result createPolicy(Policy policy) { - return policyHandler.createPolicy(policy); - } - - @Override - public List<Policy> getPolicies() { - return policyHandler.getPolicies(); - } - - /** - * Returns the tunnel object with the tunnel ID. - * - * @param tunnelId Tunnel ID - * @return Tunnel reference - */ - public Tunnel getTunnel(String tunnelId) { - return tunnelHandler.getTunnel(tunnelId); - } - - /** - * Returns the vlan-id assigned to the subnet configured for a device. - * If no vlan-id has been assigned, a new one is assigned out of a pool of ids, - * if and only if this controller instance is the master for the device. - * <p> - * USAGE: The assigned vlans are meant to be applied to untagged packets on those - * switches/pipelines that need this functionality. These vids are meant - * to be used internally within a switch, and thus need to be unique only - * on a switch level. Note that packets never go out on the wire with these - * vlans. Currently, vlan ids are assigned from value 4093 down. - * Vlan id 4094 expected to be used for all ports that are not assigned subnets. - * Vlan id 4095 is reserved and unused. Only a single vlan id is assigned - * per subnet. - * XXX This method should avoid any vlans configured on the ports, but - * currently the app works only on untagged packets and as a result - * ignores any vlan configuration. - * - * @param deviceId switch dpid - * @param subnet IPv4 prefix for which assigned vlan is desired - * @return VlanId assigned for the subnet on the device, or - * null if no vlan assignment was found and this instance is not - * the master for the device. - */ - public VlanId getSubnetAssignedVlanId(DeviceId deviceId, Ip4Prefix subnet) { - VlanId assignedVid = subnetVidStore.get(new SubnetAssignedVidStoreKey( - deviceId, subnet)); - if (assignedVid != null) { - log.debug("Query for subnet:{} on device:{} returned assigned-vlan " - + "{}", subnet, deviceId, assignedVid); - return assignedVid; - } - //check mastership for the right to assign a vlan - if (!mastershipService.isLocalMaster(deviceId)) { - log.warn("This controller instance is not the master for device {}. " - + "Cannot assign vlan-id for subnet {}", deviceId, subnet); - return null; - } - // vlan assignment is expensive but done only once - Set<Ip4Prefix> configuredSubnets = deviceConfiguration.getSubnets(deviceId); - Set<Short> assignedVlans = new HashSet<>(); - Set<Ip4Prefix> unassignedSubnets = new HashSet<>(); - for (Ip4Prefix sub : configuredSubnets) { - VlanId v = subnetVidStore.get(new SubnetAssignedVidStoreKey(deviceId, - sub)); - if (v != null) { - assignedVlans.add(v.toShort()); - } else { - unassignedSubnets.add(sub); - } - } - short nextAssignedVlan = ASSIGNED_VLAN_START; - if (!assignedVlans.isEmpty()) { - nextAssignedVlan = (short) (Collections.min(assignedVlans) - 1); - } - for (Ip4Prefix unsub : unassignedSubnets) { - subnetVidStore.put(new SubnetAssignedVidStoreKey(deviceId, unsub), - VlanId.vlanId(nextAssignedVlan--)); - log.info("Assigned vlan: {} to subnet: {} on device: {}", - nextAssignedVlan + 1, unsub, deviceId); - } - - return subnetVidStore.get(new SubnetAssignedVidStoreKey(deviceId, subnet)); - } - - /** - * Returns the next objective ID for the given NeighborSet. - * If the nextObjective does not exist, a new one is created and - * its id is returned. - * - * @param deviceId Device ID - * @param ns NegighborSet - * @param meta metadata passed into the creation of a Next Objective - * @return next objective ID or -1 if an error was encountered during the - * creation of the nextObjective - */ - public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns, - TrafficSelector meta) { - if (groupHandlerMap.get(deviceId) != null) { - log.trace("getNextObjectiveId query in device {}", deviceId); - return groupHandlerMap - .get(deviceId).getNextObjectiveId(ns, meta); - } else { - log.warn("getNextObjectiveId query - groupHandler for device {} " - + "not found", deviceId); - return -1; - } - } - - /** - * Returns the next objective ID for the given subnet prefix. It is expected - * that the next-objective has been pre-created from configuration. - * - * @param deviceId Device ID - * @param prefix Subnet - * @return next objective ID or -1 if it was not found - */ - public int getSubnetNextObjectiveId(DeviceId deviceId, IpPrefix prefix) { - if (groupHandlerMap.get(deviceId) != null) { - log.trace("getSubnetNextObjectiveId query in device {}", deviceId); - return groupHandlerMap - .get(deviceId).getSubnetNextObjectiveId(prefix); - } else { - log.warn("getSubnetNextObjectiveId query - groupHandler for " - + "device {} not found", deviceId); - return -1; - } - } - - /** - * Returns the next objective ID for the given portNumber, given the treatment. - * There could be multiple different treatments to the same outport, which - * would result in different objectives. If the next object - * does not exist, a new one is created and its id is returned. - * - * @param deviceId Device ID - * @param portNum port number on device for which NextObjective is queried - * @param treatment the actions to apply on the packets (should include outport) - * @param meta metadata passed into the creation of a Next Objective if necessary - * @return next objective ID or -1 if it was not found - */ - public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum, - TrafficTreatment treatment, - TrafficSelector meta) { - DefaultGroupHandler ghdlr = groupHandlerMap.get(deviceId); - if (ghdlr != null) { - return ghdlr.getPortNextObjectiveId(portNum, treatment, meta); - } else { - log.warn("getPortNextObjectiveId query - groupHandler for device {}" - + " not found", deviceId); - return -1; - } - } - - private class InternalPacketProcessor implements PacketProcessor { - @Override - public void process(PacketContext context) { - - if (context.isHandled()) { - return; - } - - InboundPacket pkt = context.inPacket(); - Ethernet ethernet = pkt.parsed(); - log.trace("Rcvd pktin: {}", ethernet); - if (ethernet.getEtherType() == Ethernet.TYPE_ARP) { - arpHandler.processPacketIn(pkt); - } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) { - IPv4 ipPacket = (IPv4) ethernet.getPayload(); - ipHandler.addToPacketBuffer(ipPacket); - if (ipPacket.getProtocol() == IPv4.PROTOCOL_ICMP) { - icmpHandler.processPacketIn(pkt); - } else { - ipHandler.processPacketIn(pkt); - } - } - } - } - - private class InternalLinkListener implements LinkListener { - @Override - public void event(LinkEvent event) { - if (event.type() == LinkEvent.Type.LINK_ADDED - || event.type() == LinkEvent.Type.LINK_REMOVED) { - log.debug("Event {} received from Link Service", event.type()); - scheduleEventHandlerIfNotScheduled(event); - } - } - } - - private class InternalDeviceListener implements DeviceListener { - @Override - public void event(DeviceEvent event) { - switch (event.type()) { - case DEVICE_ADDED: - case PORT_REMOVED: - case DEVICE_UPDATED: - case DEVICE_AVAILABILITY_CHANGED: - log.debug("Event {} received from Device Service", event.type()); - scheduleEventHandlerIfNotScheduled(event); - break; - default: - } - } - } - - @SuppressWarnings("rawtypes") - private void scheduleEventHandlerIfNotScheduled(Event event) { - synchronized (threadSchedulerLock) { - eventQueue.add(event); - numOfEventsQueued++; - - if ((numOfHandlerScheduled - numOfHandlerExecution) == 0) { - //No pending scheduled event handling threads. So start a new one. - eventHandlerFuture = executorService - .schedule(eventHandler, 100, TimeUnit.MILLISECONDS); - numOfHandlerScheduled++; - } - log.trace("numOfEventsQueued {}, numOfEventHanlderScheduled {}", - numOfEventsQueued, - numOfHandlerScheduled); - } - } - - private class InternalEventHandler implements Runnable { - @Override - public void run() { - try { - while (true) { - @SuppressWarnings("rawtypes") - Event event = null; - synchronized (threadSchedulerLock) { - if (!eventQueue.isEmpty()) { - event = eventQueue.poll(); - numOfEventsExecuted++; - } else { - numOfHandlerExecution++; - log.debug("numOfHandlerExecution {} numOfEventsExecuted {}", - numOfHandlerExecution, numOfEventsExecuted); - break; - } - } - if (event.type() == LinkEvent.Type.LINK_ADDED) { - processLinkAdded((Link) event.subject()); - } else if (event.type() == LinkEvent.Type.LINK_REMOVED) { - processLinkRemoved((Link) event.subject()); - } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED || - event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED || - event.type() == DeviceEvent.Type.DEVICE_UPDATED) { - if (deviceService.isAvailable(((Device) event.subject()).id())) { - log.info("Processing device event {} for available device {}", - event.type(), ((Device) event.subject()).id()); - processDeviceAdded((Device) event.subject()); - } - } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) { - processPortRemoved((Device) event.subject(), - ((DeviceEvent) event).port()); - } else { - log.warn("Unhandled event type: {}", event.type()); - } - } - } catch (Exception e) { - log.error("SegmentRouting event handler " - + "thread thrown an exception: {}", e); - } - } - } - - private void processLinkAdded(Link link) { - log.debug("A new link {} was added", link.toString()); - if (!deviceConfiguration.isConfigured(link.src().deviceId())) { - log.warn("Source device of this link is not configured."); - return; - } - //Irrespective whether the local is a MASTER or not for this device, - //create group handler instance and push default TTP flow rules. - //Because in a multi-instance setup, instances can initiate - //groups for any devices. Also the default TTP rules are needed - //to be pushed before inserting any IP table entries for any device - DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src() - .deviceId()); - if (groupHandler != null) { - groupHandler.linkUp(link, mastershipService.isLocalMaster( - link.src().deviceId())); - } else { - Device device = deviceService.getDevice(link.src().deviceId()); - if (device != null) { - log.warn("processLinkAdded: Link Added " - + "Notification without Device Added " - + "event, still handling it"); - processDeviceAdded(device); - groupHandler = groupHandlerMap.get(link.src() - .deviceId()); - groupHandler.linkUp(link, mastershipService.isLocalMaster(device.id())); - } - } - - log.trace("Starting optimized route population process"); - defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null); - //log.trace("processLinkAdded: re-starting route population process"); - //defaultRoutingHandler.startPopulationProcess(); - } - - private void processLinkRemoved(Link link) { - log.debug("A link {} was removed", link.toString()); - DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId()); - if (groupHandler != null) { - groupHandler.portDown(link.src().port()); - } - log.trace("Starting optimized route population process"); - defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); - //log.trace("processLinkRemoved: re-starting route population process"); - //defaultRoutingHandler.startPopulationProcess(); - } - - private void processDeviceAdded(Device device) { - log.debug("A new device with ID {} was added", device.id()); - if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) { - log.warn("Device configuration uploading. Device {} will be " - + "processed after config completes.", device.id()); - return; - } - // Irrespective of whether the local is a MASTER or not for this device, - // we need to create a SR-group-handler instance. This is because in a - // multi-instance setup, any instance can initiate forwarding/next-objectives - // for any switch (even if this instance is a SLAVE or not even connected - // to the switch). To handle this, a default-group-handler instance is necessary - // per switch. - if (groupHandlerMap.get(device.id()) == null) { - DefaultGroupHandler groupHandler; - try { - groupHandler = DefaultGroupHandler. - createGroupHandler(device.id(), - appId, - deviceConfiguration, - linkService, - flowObjectiveService, - nsNextObjStore, - subnetNextObjStore, - portNextObjStore); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting processDeviceAdded."); - return; - } - groupHandlerMap.put(device.id(), groupHandler); - // Also, in some cases, drivers may need extra - // information to process rules (eg. Router IP/MAC); and so, we send - // port addressing rules to the driver as well irrespective of whether - // this instance is the master or not. - defaultRoutingHandler.populatePortAddressingRules(device.id()); - hostListener.readInitialHosts(); - } - if (mastershipService.isLocalMaster(device.id())) { - DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); - groupHandler.createGroupsFromSubnetConfig(); - routingRulePopulator.populateSubnetBroadcastRule(device.id()); - } - } - - private void processPortRemoved(Device device, Port port) { - log.debug("Port {} was removed", port.toString()); - DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); - if (groupHandler != null) { - groupHandler.portDown(port.number()); - } - } - - private class InternalConfigListener implements NetworkConfigListener { - SegmentRoutingManager segmentRoutingManager; - - public InternalConfigListener(SegmentRoutingManager srMgr) { - this.segmentRoutingManager = srMgr; - } - - public void configureNetwork() { - deviceConfiguration = new DeviceConfiguration(segmentRoutingManager.cfgService); - - arpHandler = new ArpHandler(segmentRoutingManager); - icmpHandler = new IcmpHandler(segmentRoutingManager); - ipHandler = new IpHandler(segmentRoutingManager); - routingRulePopulator = new RoutingRulePopulator(segmentRoutingManager); - defaultRoutingHandler = new DefaultRoutingHandler(segmentRoutingManager); - - tunnelHandler = new TunnelHandler(linkService, deviceConfiguration, - groupHandlerMap, tunnelStore); - policyHandler = new PolicyHandler(appId, deviceConfiguration, - flowObjectiveService, - tunnelHandler, policyStore); - - for (Device device : deviceService.getDevices()) { - // Irrespective of whether the local is a MASTER or not for this device, - // we need to create a SR-group-handler instance. This is because in a - // multi-instance setup, any instance can initiate forwarding/next-objectives - // for any switch (even if this instance is a SLAVE or not even connected - // to the switch). To handle this, a default-group-handler instance is necessary - // per switch. - if (groupHandlerMap.get(device.id()) == null) { - DefaultGroupHandler groupHandler; - try { - groupHandler = DefaultGroupHandler. - createGroupHandler(device.id(), - appId, - deviceConfiguration, - linkService, - flowObjectiveService, - nsNextObjStore, - subnetNextObjStore, - portNextObjStore); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting configureNetwork."); - return; - } - groupHandlerMap.put(device.id(), groupHandler); - - // Also, in some cases, drivers may need extra - // information to process rules (eg. Router IP/MAC); and so, we send - // port addressing rules to the driver as well, irrespective of whether - // this instance is the master or not. - defaultRoutingHandler.populatePortAddressingRules(device.id()); - hostListener.readInitialHosts(); - } - if (mastershipService.isLocalMaster(device.id())) { - DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); - groupHandler.createGroupsFromSubnetConfig(); - routingRulePopulator.populateSubnetBroadcastRule(device.id()); - } - } - - defaultRoutingHandler.startPopulationProcess(); - } - - @Override - public void event(NetworkConfigEvent event) { - if (event.configClass().equals(SegmentRoutingConfig.class)) { - if (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED) { - log.info("Network configuration added."); - configureNetwork(); - } - if (event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) { - log.info("Network configuration updated."); - // TODO support dynamic configuration - } - } - } - } - - // TODO Move bridging table population to a separate class - private class InternalHostListener implements HostListener { - private void readInitialHosts() { - hostService.getHosts().forEach(host -> { - MacAddress mac = host.mac(); - VlanId vlanId = host.vlan(); - DeviceId deviceId = host.location().deviceId(); - PortNumber port = host.location().port(); - Set<IpAddress> ips = host.ipAddresses(); - log.debug("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port); - - // Populate bridging table entry - ForwardingObjective.Builder fob = - getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); - flowObjectiveService.forward(deviceId, fob.add( - new BridgingTableObjectiveContext(mac, vlanId) - )); - - // Populate IP table entry - ips.forEach(ip -> { - if (ip.isIp4()) { - routingRulePopulator.populateIpRuleForHost( - deviceId, ip.getIp4Address(), mac, port); - } - }); - }); - } - - private ForwardingObjective.Builder getForwardingObjectiveBuilder( - DeviceId deviceId, MacAddress mac, VlanId vlanId, - PortNumber outport) { - // match rule - TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); - sbuilder.matchEthDst(mac); - sbuilder.matchVlanId(vlanId); - - TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); - tbuilder.immediate().popVlan(); - tbuilder.immediate().setOutput(outport); - - // for switch pipelines that need it, provide outgoing vlan as metadata - VlanId outvlan = null; - Ip4Prefix subnet = deviceConfiguration.getPortSubnet(deviceId, outport); - if (subnet == null) { - outvlan = VlanId.vlanId(ASSIGNED_VLAN_NO_SUBNET); - } else { - outvlan = getSubnetAssignedVlanId(deviceId, subnet); - } - TrafficSelector meta = DefaultTrafficSelector.builder() - .matchVlanId(outvlan).build(); - - // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed. - int portNextObjId = getPortNextObjectiveId(deviceId, outport, - tbuilder.build(), - meta); - - return DefaultForwardingObjective.builder() - .withFlag(ForwardingObjective.Flag.SPECIFIC) - .withSelector(sbuilder.build()) - .nextStep(portNextObjId) - .withPriority(100) - .fromApp(appId) - .makePermanent(); - } - - private void processHostAddedEvent(HostEvent event) { - MacAddress mac = event.subject().mac(); - VlanId vlanId = event.subject().vlan(); - DeviceId deviceId = event.subject().location().deviceId(); - PortNumber port = event.subject().location().port(); - Set<IpAddress> ips = event.subject().ipAddresses(); - log.info("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port); - - // Populate bridging table entry - log.debug("Populate L2 table entry for host {} at {}:{}", - mac, deviceId, port); - ForwardingObjective.Builder fob = - getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); - flowObjectiveService.forward(deviceId, fob.add( - new BridgingTableObjectiveContext(mac, vlanId) - )); - - // Populate IP table entry - ips.forEach(ip -> { - if (ip.isIp4()) { - routingRulePopulator.populateIpRuleForHost( - deviceId, ip.getIp4Address(), mac, port); - } - }); - } - - private void processHostRemoveEvent(HostEvent event) { - MacAddress mac = event.subject().mac(); - VlanId vlanId = event.subject().vlan(); - DeviceId deviceId = event.subject().location().deviceId(); - PortNumber port = event.subject().location().port(); - Set<IpAddress> ips = event.subject().ipAddresses(); - log.debug("Host {}/{} is removed from {}:{}", mac, vlanId, deviceId, port); - - // Revoke bridging table entry - ForwardingObjective.Builder fob = - getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); - flowObjectiveService.forward(deviceId, fob.remove( - new BridgingTableObjectiveContext(mac, vlanId) - )); - - // Revoke IP table entry - ips.forEach(ip -> { - if (ip.isIp4()) { - routingRulePopulator.revokeIpRuleForHost( - deviceId, ip.getIp4Address(), mac, port); - } - }); - } - - private void processHostMovedEvent(HostEvent event) { - MacAddress mac = event.subject().mac(); - VlanId vlanId = event.subject().vlan(); - DeviceId prevDeviceId = event.prevSubject().location().deviceId(); - PortNumber prevPort = event.prevSubject().location().port(); - Set<IpAddress> prevIps = event.prevSubject().ipAddresses(); - DeviceId newDeviceId = event.subject().location().deviceId(); - PortNumber newPort = event.subject().location().port(); - Set<IpAddress> newIps = event.subject().ipAddresses(); - log.debug("Host {}/{} is moved from {}:{} to {}:{}", - mac, vlanId, prevDeviceId, prevPort, newDeviceId, newPort); - - // Revoke previous bridging table entry - ForwardingObjective.Builder prevFob = - getForwardingObjectiveBuilder(prevDeviceId, mac, vlanId, prevPort); - flowObjectiveService.forward(prevDeviceId, prevFob.remove( - new BridgingTableObjectiveContext(mac, vlanId) - )); - - // Revoke previous IP table entry - prevIps.forEach(ip -> { - if (ip.isIp4()) { - routingRulePopulator.revokeIpRuleForHost( - prevDeviceId, ip.getIp4Address(), mac, prevPort); - } - }); - - // Populate new bridging table entry - ForwardingObjective.Builder newFob = - getForwardingObjectiveBuilder(newDeviceId, mac, vlanId, newPort); - flowObjectiveService.forward(newDeviceId, newFob.add( - new BridgingTableObjectiveContext(mac, vlanId) - )); - - // Populate new IP table entry - newIps.forEach(ip -> { - if (ip.isIp4()) { - routingRulePopulator.populateIpRuleForHost( - newDeviceId, ip.getIp4Address(), mac, newPort); - } - }); - } - - private void processHostUpdatedEvent(HostEvent event) { - MacAddress mac = event.subject().mac(); - VlanId vlanId = event.subject().vlan(); - DeviceId prevDeviceId = event.prevSubject().location().deviceId(); - PortNumber prevPort = event.prevSubject().location().port(); - Set<IpAddress> prevIps = event.prevSubject().ipAddresses(); - DeviceId newDeviceId = event.subject().location().deviceId(); - PortNumber newPort = event.subject().location().port(); - Set<IpAddress> newIps = event.subject().ipAddresses(); - log.debug("Host {}/{} is updated", mac, vlanId); - - // Revoke previous IP table entry - prevIps.forEach(ip -> { - if (ip.isIp4()) { - routingRulePopulator.revokeIpRuleForHost( - prevDeviceId, ip.getIp4Address(), mac, prevPort); - } - }); - - // Populate new IP table entry - newIps.forEach(ip -> { - if (ip.isIp4()) { - routingRulePopulator.populateIpRuleForHost( - newDeviceId, ip.getIp4Address(), mac, newPort); - } - }); - } - - @Override - public void event(HostEvent event) { - // Do not proceed without mastership - DeviceId deviceId = event.subject().location().deviceId(); - if (!mastershipService.isLocalMaster(deviceId)) { - return; - } - - switch (event.type()) { - case HOST_ADDED: - processHostAddedEvent(event); - break; - case HOST_MOVED: - processHostMovedEvent(event); - break; - case HOST_REMOVED: - processHostRemoveEvent(event); - break; - case HOST_UPDATED: - processHostUpdatedEvent(event); - break; - default: - log.warn("Unsupported host event type: {}", event.type()); - break; - } - } - } - - private static class BridgingTableObjectiveContext implements ObjectiveContext { - final MacAddress mac; - final VlanId vlanId; - - BridgingTableObjectiveContext(MacAddress mac, VlanId vlanId) { - this.mac = mac; - this.vlanId = vlanId; - } - - @Override - public void onSuccess(Objective objective) { - if (objective.op() == Objective.Operation.ADD) { - log.debug("Successfully populate bridging table entry for {}/{}", - mac, vlanId); - } else { - log.debug("Successfully revoke bridging table entry for {}/{}", - mac, vlanId); - } - } - - @Override - public void onError(Objective objective, ObjectiveError error) { - if (objective.op() == Objective.Operation.ADD) { - log.debug("Fail to populate bridging table entry for {}/{}. {}", - mac, vlanId, error); - } else { - log.debug("Fail to revoke bridging table entry for {}/{}. {}", - mac, vlanId, error); - } - } - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java deleted file mode 100644 index 44bd453c..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java +++ /dev/null @@ -1,79 +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.segmentrouting; - -import java.util.List; - -/** - * Segment Routing Service for REST API. - */ -public interface SegmentRoutingService { - - /** - * Returns all tunnels. - * - * @return list of tunnels - */ - List<Tunnel> getTunnels(); - - /** - * Creates a tunnel. - * - * @param tunnel tunnel reference to create - * @return WRONG_PATH if the tunnel path is wrong, ID_EXISTS if the tunnel ID - * exists already, TUNNEL_EXISTS if the same tunnel exists, INTERNAL_ERROR - * if the tunnel creation failed internally, SUCCESS if the tunnel is created - * successfully - */ - TunnelHandler.Result createTunnel(Tunnel tunnel); - - /** - * Returns all policies. - * - * @return list of policy - */ - List<Policy> getPolicies(); - - /** - * Creates a policy. - * - * @param policy policy reference to create - * @return ID_EXISTS if the same policy ID exists, - * POLICY_EXISTS if the same policy exists, TUNNEL_NOT_FOUND if the tunnel - * does not exists, UNSUPPORTED_TYPE if the policy type is not supported, - * SUCCESS if the policy is created successfully. - */ - PolicyHandler.Result createPolicy(Policy policy); - - /** - * Removes a tunnel. - * - * @param tunnel tunnel reference to remove - * @return TUNNEL_NOT_FOUND if the tunnel to remove does not exists, - * INTERNAL_ERROR if the tunnel creation failed internally, SUCCESS - * if the tunnel is created successfully. - */ - TunnelHandler.Result removeTunnel(Tunnel tunnel); - - /** - * Removes a policy. - * - * @param policy policy reference to remove - * @return POLICY_NOT_FOUND if the policy to remove does not exists, - * SUCCESS if it is removed successfully - */ - PolicyHandler.Result removePolicy(Policy policy); -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SubnetAssignedVidStoreKey.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SubnetAssignedVidStoreKey.java deleted file mode 100644 index 84b44c97..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SubnetAssignedVidStoreKey.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.onosproject.segmentrouting; - -import java.util.Objects; - -import org.onlab.packet.Ip4Prefix; -import org.onosproject.net.DeviceId; - -/** - * Class definition for key used to map per device subnets to assigned Vlan ids. - * - */ -public class SubnetAssignedVidStoreKey { - private final DeviceId deviceId; - private final Ip4Prefix subnet; - - public SubnetAssignedVidStoreKey(DeviceId deviceId, Ip4Prefix subnet) { - this.deviceId = deviceId; - this.subnet = subnet; - } - - /** - * Returns the device identification used to create this key. - * - * @return the device identifier - */ - public DeviceId deviceId() { - return deviceId; - } - - /** - * Returns the subnet information used to create this key. - * - * @return the subnet - */ - public Ip4Prefix subnet() { - return subnet; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof SubnetAssignedVidStoreKey)) { - return false; - } - SubnetAssignedVidStoreKey that = - (SubnetAssignedVidStoreKey) o; - return (Objects.equals(this.deviceId, that.deviceId) && - Objects.equals(this.subnet, that.subnet)); - } - - @Override - public int hashCode() { - int result = 17; - result = 31 * result + Objects.hashCode(deviceId) - + Objects.hashCode(subnet); - return result; - } - - @Override - public String toString() { - return "Device: " + deviceId + " Subnet: " + subnet; - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/Tunnel.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/Tunnel.java deleted file mode 100644 index 783d253e..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/Tunnel.java +++ /dev/null @@ -1,67 +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.segmentrouting; - -import java.util.List; - -/** - * Tunnel interface. - */ -public interface Tunnel { - - /** - * Returns the tunnel ID. - * - * @return tunnel ID - */ - String id(); - - /** - * Returns Segment IDs for the tunnel including source and destination. - * - * @return List of Node ID - */ - List<Integer> labelIds(); - - /** - * Returns the group ID for the tunnel. - * - * @return group ID - */ - int groupId(); - - /** - * Sets group ID for the tunnel. - * - * @param groupId group identifier - */ - void setGroupId(int groupId); - - /** - * Sets the flag to allow to remove the group or not. - * - * @param ok the flag; true - allow to remove - */ - void allowToRemoveGroup(boolean ok); - - /** - * Checks if it is allowed to remove the group for the tunnel. - * - * @return true if allowed, false otherwise - */ - boolean isAllowedToRemoveGroup(); -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java deleted file mode 100644 index 5a82e712..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java +++ /dev/null @@ -1,200 +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.segmentrouting; - -import org.onosproject.net.DeviceId; -import org.onosproject.net.Link; -import org.onosproject.net.link.LinkService; -import org.onosproject.segmentrouting.config.DeviceConfiguration; -import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; -import org.onosproject.segmentrouting.grouphandler.NeighborSet; -import org.onosproject.store.service.EventuallyConsistentMap; -import org.slf4j.Logger; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.slf4j.LoggerFactory.getLogger; - -/** - * Tunnel Handler. - */ -public class TunnelHandler { - protected final Logger log = getLogger(getClass()); - - private final DeviceConfiguration config; - private final EventuallyConsistentMap<String, Tunnel> tunnelStore; - private Map<DeviceId, DefaultGroupHandler> groupHandlerMap; - private LinkService linkService; - - public enum Result { - SUCCESS, - WRONG_PATH, - TUNNEL_EXISTS, - ID_EXISTS, - TUNNEL_NOT_FOUND, - TUNNEL_IN_USE, - INTERNAL_ERROR - } - - public TunnelHandler(LinkService linkService, - DeviceConfiguration deviceConfiguration, - Map<DeviceId, DefaultGroupHandler> groupHandlerMap, - EventuallyConsistentMap<String, Tunnel> tunnelStore) { - this.linkService = linkService; - this.config = deviceConfiguration; - this.groupHandlerMap = groupHandlerMap; - this.tunnelStore = tunnelStore; - } - - /** - * Creates a tunnel. - * - * @param tunnel tunnel reference to create a tunnel - * @return WRONG_PATH if the tunnel path is wrong, ID_EXISTS if the tunnel ID - * exists already, TUNNEL_EXISTS if the same tunnel exists, INTERNAL_ERROR - * if the tunnel creation failed internally, SUCCESS if the tunnel is created - * successfully - */ - public Result createTunnel(Tunnel tunnel) { - - if (tunnel.labelIds().isEmpty() || tunnel.labelIds().size() < 3) { - log.error("More than one router needs to specified to created a tunnel"); - return Result.WRONG_PATH; - } - - if (tunnelStore.containsKey(tunnel.id())) { - log.warn("The same tunnel ID exists already"); - return Result.ID_EXISTS; - } - - if (tunnelStore.containsValue(tunnel)) { - log.warn("The same tunnel exists already"); - return Result.TUNNEL_EXISTS; - } - - int groupId = createGroupsForTunnel(tunnel); - if (groupId < 0) { - log.error("Failed to create groups for the tunnel"); - return Result.INTERNAL_ERROR; - } - - tunnel.setGroupId(groupId); - tunnelStore.put(tunnel.id(), tunnel); - - return Result.SUCCESS; - } - - /** - * Removes the tunnel with the tunnel ID given. - * - * @param tunnelInfo tunnel information to delete tunnels - * @return TUNNEL_NOT_FOUND if the tunnel to remove does not exists, - * INTERNAL_ERROR if the tunnel creation failed internally, SUCCESS - * if the tunnel is created successfully. - */ - public Result removeTunnel(Tunnel tunnelInfo) { - - Tunnel tunnel = tunnelStore.get(tunnelInfo.id()); - if (tunnel != null) { - DeviceId deviceId = config.getDeviceId(tunnel.labelIds().get(0)); - if (tunnel.isAllowedToRemoveGroup()) { - if (groupHandlerMap.get(deviceId).removeGroup(tunnel.groupId())) { - tunnelStore.remove(tunnel.id()); - } else { - log.error("Failed to remove the tunnel {}", tunnelInfo.id()); - return Result.INTERNAL_ERROR; - } - } else { - log.debug("The group is not removed because it is being used."); - tunnelStore.remove(tunnel.id()); - } - } else { - log.error("No tunnel found for tunnel ID {}", tunnelInfo.id()); - return Result.TUNNEL_NOT_FOUND; - } - - return Result.SUCCESS; - } - - /** - * Returns the tunnel with the tunnel ID given. - * - * @param tid Tunnel ID - * @return Tunnel reference - */ - public Tunnel getTunnel(String tid) { - return tunnelStore.get(tid); - } - - /** - * Returns all tunnels. - * - * @return list of Tunnels - */ - public List<Tunnel> getTunnels() { - List<Tunnel> tunnels = new ArrayList<>(); - tunnelStore.values().forEach(tunnel -> tunnels.add( - new DefaultTunnel((DefaultTunnel) tunnel))); - - return tunnels; - } - - private int createGroupsForTunnel(Tunnel tunnel) { - - Set<Integer> portNumbers; - final int groupError = -1; - - DeviceId deviceId = config.getDeviceId(tunnel.labelIds().get(0)); - if (deviceId == null) { - log.warn("No device found for SID {}", tunnel.labelIds().get(0)); - return groupError; - } else if (groupHandlerMap.get(deviceId) == null) { - log.warn("group handler not found for {}", deviceId); - return groupError; - } - Set<DeviceId> deviceIds = new HashSet<>(); - int sid = tunnel.labelIds().get(1); - if (config.isAdjacencySid(deviceId, sid)) { - portNumbers = config.getPortsForAdjacencySid(deviceId, sid); - for (Link link: linkService.getDeviceEgressLinks(deviceId)) { - for (Integer port: portNumbers) { - if (link.src().port().toLong() == port) { - deviceIds.add(link.dst().deviceId()); - } - } - } - } else { - deviceIds.add(config.getDeviceId(sid)); - } - - NeighborSet ns = new NeighborSet(deviceIds, tunnel.labelIds().get(2)); - - // If the tunnel reuses any existing groups, then tunnel handler - // should not remove the group. - if (groupHandlerMap.get(deviceId).hasNextObjectiveId(ns)) { - tunnel.allowToRemoveGroup(false); - } else { - tunnel.allowToRemoveGroup(true); - } - - return groupHandlerMap.get(deviceId).getNextObjectiveId(ns, null); - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelPolicy.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelPolicy.java deleted file mode 100644 index 06dbdb21..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelPolicy.java +++ /dev/null @@ -1,291 +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.segmentrouting; - -import java.util.Objects; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Tunnel Policy. - */ -public final class TunnelPolicy implements Policy { - - private final Type type; - private final String id; - private final int priority; - private final String tunnelId; - private String dstIp; - private String srcIp; - private String ipProto; - private short srcPort; - private short dstPort; - - private TunnelPolicy(String policyId, Type type, int priority, String tunnelId, String srcIp, - String dstIp, String ipProto, short srcPort, short dstPort) { - this.id = checkNotNull(policyId); - this.type = type; - this.tunnelId = tunnelId; - this.priority = priority; - this.dstIp = dstIp; - this.srcIp = srcIp; - this.ipProto = ipProto; - this.srcPort = srcPort; - this.dstPort = dstPort; - - } - - /** - * Creates a TunnelPolicy reference. - * - * @param p TunnelPolicy reference - */ - public TunnelPolicy(TunnelPolicy p) { - this.id = p.id; - this.type = p.type; - this.tunnelId = p.tunnelId; - this.priority = p.priority; - this.srcIp = p.srcIp; - this.dstIp = p.dstIp; - this.ipProto = p.ipProto; - this.srcPort = p.srcPort; - this.dstPort = p.dstPort; - } - - /** - * Returns the TunnelPolicy builder reference. - * - * @return TunnelPolicy builder - */ - public static TunnelPolicy.Builder builder() { - return new Builder(); - } - - @Override - public String id() { - return this.id; - } - - @Override - public int priority() { - return priority; - } - - @Override - public Type type() { - return type; - } - - @Override - public String srcIp() { - return srcIp; - } - - @Override - public String dstIp() { - return dstIp; - } - - @Override - public String ipProto() { - return ipProto; - } - - @Override - public short srcPort() { - return srcPort; - } - - @Override - public short dstPort() { - return dstPort; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o instanceof TunnelPolicy) { - TunnelPolicy that = (TunnelPolicy) o; - // We do not compare the policy ID - if (this.type.equals(that.type) && - this.tunnelId.equals(that.tunnelId) && - this.priority == that.priority && - this.srcIp.equals(that.srcIp) && - this.dstIp.equals(that.dstIp) && - this.srcPort == that.srcPort && - this.dstPort == that.dstPort && - this.ipProto.equals(that.ipProto)) { - return true; - } - } - - return false; - } - - @Override - public int hashCode() { - return Objects.hash(type, tunnelId, srcIp, dstIp, ipProto, - srcPort, dstPort, priority); - } - - /** - * Returns the tunnel ID of the policy. - * - * @return Tunnel ID - */ - public String tunnelId() { - return this.tunnelId; - } - - - /** - * Tunnel Policy Builder. - */ - public static final class Builder { - - private String id; - private Type type; - private int priority; - private String tunnelId; - private String dstIp; - private String srcIp; - private String ipProto; - private short srcPort; - private short dstPort; - - /** - * Sets the policy Id. - * - * @param id policy Id - * @return Builder object - */ - public Builder setPolicyId(String id) { - this.id = id; - - return this; - } - - /** - * Sets the policy type. - * - * @param type policy type - * @return Builder object - */ - public Builder setType(Type type) { - this.type = type; - - return this; - } - - /** - * Sets the source IP address. - * - * @param srcIp source IP address - * @return Builder object - */ - public Builder setSrcIp(String srcIp) { - this.srcIp = srcIp; - - return this; - } - - /** - * Sets the destination IP address. - * - * @param dstIp destination IP address - * @return Builder object - */ - public Builder setDstIp(String dstIp) { - this.dstIp = dstIp; - - return this; - } - - /** - * Sets the IP protocol. - * - * @param proto IP protocol - * @return Builder object - */ - public Builder setIpProto(String proto) { - this.ipProto = proto; - - return this; - } - - /** - * Sets the source port. - * - * @param srcPort source port - * @return Builder object - */ - public Builder setSrcPort(short srcPort) { - this.srcPort = srcPort; - - return this; - } - - /** - * Sets the destination port. - * - * @param dstPort destination port - * @return Builder object - */ - public Builder setDstPort(short dstPort) { - this.dstPort = dstPort; - - return this; - } - - /** - * Sets the priority of the policy. - * - * @param p priority - * @return Builder object - */ - public Builder setPriority(int p) { - this.priority = p; - - return this; - } - - /** - * Sets the tunnel Id. - * - * @param tunnelId tunnel Id - * @return Builder object - */ - public Builder setTunnelId(String tunnelId) { - this.tunnelId = tunnelId; - - return this; - } - - /** - * Builds the policy. - * - * @return Tunnel Policy reference - */ - public Policy build() { - return new TunnelPolicy(id, type, priority, tunnelId, srcIp, dstIp, - ipProto, srcPort, dstPort); - } - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PolicyAddCommand.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PolicyAddCommand.java deleted file mode 100644 index b00633cd..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PolicyAddCommand.java +++ /dev/null @@ -1,132 +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.segmentrouting.cli; - -import org.apache.karaf.shell.commands.Argument; -import org.apache.karaf.shell.commands.Command; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.segmentrouting.Policy; -import org.onosproject.segmentrouting.PolicyHandler; -import org.onosproject.segmentrouting.SegmentRoutingService; -import org.onosproject.segmentrouting.TunnelPolicy; - -/** - * Command to add a new policy. - */ -@Command(scope = "onos", name = "srpolicy-add", - description = "Create a new policy") -public class PolicyAddCommand extends AbstractShellCommand { - - // TODO: Need to support skipping some parameters - - @Argument(index = 0, name = "ID", - description = "policy ID", - required = true, multiValued = false) - String policyId; - - @Argument(index = 1, name = "priority", - description = "priority", - required = true, multiValued = false) - int priority; - - @Argument(index = 2, name = "src_IP", - description = "src IP", - required = false, multiValued = false) - String srcIp; - - @Argument(index = 3, name = "src_port", - description = "src port", - required = false, multiValued = false) - short srcPort; - - @Argument(index = 4, name = "dst_IP", - description = "dst IP", - required = false, multiValued = false) - String dstIp; - - @Argument(index = 5, name = "dst_port", - description = "dst port", - required = false, multiValued = false) - short dstPort; - - @Argument(index = 6, name = "proto", - description = "IP protocol", - required = false, multiValued = false) - String proto; - - @Argument(index = 7, name = "policy_type", - description = "policy type", - required = true, multiValued = false) - String policyType; - - @Argument(index = 8, name = "tunnel_ID", - description = "tunnel ID", - required = false, multiValued = false) - String tunnelId; - - @Override - protected void execute() { - - SegmentRoutingService srService = - AbstractShellCommand.get(SegmentRoutingService.class); - - TunnelPolicy.Builder tpb = TunnelPolicy.builder().setPolicyId(policyId); - tpb.setPriority(priority); - tpb.setType(Policy.Type.valueOf(policyType)); - - if (srcIp != null) { - tpb.setSrcIp(srcIp); - } - if (dstIp != null) { - tpb.setDstIp(dstIp); - } - if (srcPort != 0) { - tpb.setSrcPort(srcPort); - } - if (dstPort != 0) { - tpb.setDstPort(dstPort); - } - if (!proto.equals("ip")) { - tpb.setIpProto(proto); - } - if (Policy.Type.valueOf(policyType) == Policy.Type.TUNNEL_FLOW) { - if (tunnelId == null) { - error("tunnel ID must be specified for TUNNEL_FLOW policy"); - return; - } - tpb.setTunnelId(tunnelId); - } - PolicyHandler.Result result = srService.createPolicy(tpb.build()); - - switch (result) { - case POLICY_EXISTS: - error("the same policy exists"); - break; - case ID_EXISTS: - error("the same policy ID exists"); - break; - case TUNNEL_NOT_FOUND: - error("the tunnel is not found"); - break; - case UNSUPPORTED_TYPE: - error("the policy type specified is not supported"); - break; - default: - break; - } - - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PolicyListCommand.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PolicyListCommand.java deleted file mode 100644 index 929c98c5..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PolicyListCommand.java +++ /dev/null @@ -1,51 +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.segmentrouting.cli; - -import org.apache.karaf.shell.commands.Command; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.segmentrouting.Policy; -import org.onosproject.segmentrouting.SegmentRoutingService; -import org.onosproject.segmentrouting.TunnelPolicy; - -/** - * Command to show the list of policies. - */ -@Command(scope = "onos", name = "srpolicy-list", - description = "Lists all policies") -public class PolicyListCommand extends AbstractShellCommand { - - private static final String FORMAT_MAPPING_TUNNEL = - " id=%s, type=%s, prio=%d, src=%s, port=%d, dst=%s, port=%d, proto=%s, tunnel=%s"; - - @Override - protected void execute() { - - SegmentRoutingService srService = - AbstractShellCommand.get(SegmentRoutingService.class); - - srService.getPolicies().forEach(policy -> printPolicy(policy)); - } - - private void printPolicy(Policy policy) { - if (policy.type() == Policy.Type.TUNNEL_FLOW) { - print(FORMAT_MAPPING_TUNNEL, policy.id(), policy.type(), policy.priority(), - policy.srcIp(), policy.srcPort(), policy.dstIp(), policy.dstPort(), - (policy.ipProto() == null) ? "" : policy.ipProto(), - ((TunnelPolicy) policy).tunnelId()); - } - } -}
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PolicyRemoveCommand.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PolicyRemoveCommand.java deleted file mode 100644 index 34fe40d8..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PolicyRemoveCommand.java +++ /dev/null @@ -1,50 +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.segmentrouting.cli; - - -import org.apache.karaf.shell.commands.Argument; -import org.apache.karaf.shell.commands.Command; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.segmentrouting.PolicyHandler; -import org.onosproject.segmentrouting.SegmentRoutingService; -import org.onosproject.segmentrouting.TunnelPolicy; - -/** - * Command to remove a policy. - */ -@Command(scope = "onos", name = "srpolicy-remove", - description = "Remove a policy") -public class PolicyRemoveCommand extends AbstractShellCommand { - - @Argument(index = 0, name = "policy ID", - description = "policy ID", - required = true, multiValued = false) - String policyId; - - @Override - protected void execute() { - - SegmentRoutingService srService = - AbstractShellCommand.get(SegmentRoutingService.class); - - TunnelPolicy.Builder tpb = TunnelPolicy.builder().setPolicyId(policyId); - PolicyHandler.Result result = srService.removePolicy(tpb.build()); - if (result == PolicyHandler.Result.POLICY_NOT_FOUND) { - print("ERROR: the policy is not found"); - } - } -}
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/TunnelAddCommand.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/TunnelAddCommand.java deleted file mode 100644 index bb0ae549..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/TunnelAddCommand.java +++ /dev/null @@ -1,80 +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.segmentrouting.cli; - -import org.apache.karaf.shell.commands.Argument; -import org.apache.karaf.shell.commands.Command; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.segmentrouting.DefaultTunnel; -import org.onosproject.segmentrouting.SegmentRoutingService; -import org.onosproject.segmentrouting.Tunnel; -import org.onosproject.segmentrouting.TunnelHandler; - -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; - -/** - * Command to add a new tunnel. - */ -@Command(scope = "onos", name = "srtunnel-add", - description = "Create a new tunnel") -public class TunnelAddCommand extends AbstractShellCommand { - - @Argument(index = 0, name = "tunnel ID", - description = "tunnel ID", - required = true, multiValued = false) - String tunnelId; - - @Argument(index = 1, name = "label path", - description = "label path", - required = true, multiValued = false) - String labels; - - - @Override - protected void execute() { - - SegmentRoutingService srService = - AbstractShellCommand.get(SegmentRoutingService.class); - - List<Integer> labelIds = new ArrayList<>(); - StringTokenizer strToken = new StringTokenizer(labels, ","); - while (strToken.hasMoreTokens()) { - labelIds.add(Integer.valueOf(strToken.nextToken())); - } - Tunnel tunnel = new DefaultTunnel(tunnelId, labelIds); - - TunnelHandler.Result result = srService.createTunnel(tunnel); - switch (result) { - case ID_EXISTS: - print("ERROR: the same tunnel ID exists"); - break; - case TUNNEL_EXISTS: - print("ERROR: the same tunnel exists"); - break; - case INTERNAL_ERROR: - print("ERROR: internal tunnel creation error"); - break; - case WRONG_PATH: - print("ERROR: the tunnel path is wrong"); - break; - default: - break; - } - } -}
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/TunnelListCommand.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/TunnelListCommand.java deleted file mode 100644 index fe510783..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/TunnelListCommand.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.segmentrouting.cli; - -import org.apache.karaf.shell.commands.Command; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.segmentrouting.SegmentRoutingService; -import org.onosproject.segmentrouting.Tunnel; - -/** - * Command to show the list of tunnels. - */ -@Command(scope = "onos", name = "srtunnel-list", - description = "Lists all tunnels") -public class TunnelListCommand extends AbstractShellCommand { - - private static final String FORMAT_MAPPING = - " id=%s, path=%s"; - - @Override - protected void execute() { - - SegmentRoutingService srService = - AbstractShellCommand.get(SegmentRoutingService.class); - - srService.getTunnels().forEach(tunnel -> printTunnel(tunnel)); - } - - private void printTunnel(Tunnel tunnel) { - print(FORMAT_MAPPING, tunnel.id(), tunnel.labelIds()); - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/TunnelRemoveCommand.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/TunnelRemoveCommand.java deleted file mode 100644 index cca22c30..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/TunnelRemoveCommand.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.segmentrouting.cli; - - -import com.google.common.collect.Lists; -import org.apache.karaf.shell.commands.Argument; -import org.apache.karaf.shell.commands.Command; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.segmentrouting.DefaultTunnel; -import org.onosproject.segmentrouting.SegmentRoutingService; -import org.onosproject.segmentrouting.Tunnel; -import org.onosproject.segmentrouting.TunnelHandler; - -/** - * Command to remove a tunnel. - */ -@Command(scope = "onos", name = "srtunnel-remove", - description = "Remove a tunnel") -public class TunnelRemoveCommand extends AbstractShellCommand { - - @Argument(index = 0, name = "tunnel ID", - description = "tunnel ID", - required = true, multiValued = false) - String tunnelId; - - @Override - protected void execute() { - SegmentRoutingService srService = - AbstractShellCommand.get(SegmentRoutingService.class); - - Tunnel tunnel = new DefaultTunnel(tunnelId, Lists.newArrayList()); - TunnelHandler.Result result = srService.removeTunnel(tunnel); - switch (result) { - case TUNNEL_IN_USE: - print("ERROR: the tunnel is still in use"); - break; - case TUNNEL_NOT_FOUND: - print("ERROR: the tunnel is not found"); - break; - default: - break; - } - } -}
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/package-info.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/package-info.java deleted file mode 100644 index 1a9d3c78..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/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. - */ - -/** - * Segment routing application CLI handlers. - */ -package org.onosproject.segmentrouting.cli;
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java deleted file mode 100644 index ae156e60..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2014-2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.segmentrouting.config; - -/** - * Signals that an error occurred during reading device configuration. - */ -public class DeviceConfigNotFoundException extends Exception { - - /** - * Creates a new ConfigNotFoundException with the given message. - * - * @param message exception message - */ - public DeviceConfigNotFoundException(String message) { - super(message); - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java deleted file mode 100644 index dbac596d..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright 2014-2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.segmentrouting.config; - -import com.google.common.collect.ImmutableSet; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.MacAddress; -import org.onosproject.incubator.net.config.basics.ConfigException; -import org.onosproject.incubator.net.config.basics.InterfaceConfig; -import org.onosproject.incubator.net.intf.Interface; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.config.NetworkConfigRegistry; -import org.onosproject.net.host.InterfaceIpAddress; -import org.onosproject.net.DeviceId; -import org.onosproject.net.PortNumber; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Segment Routing configuration component that reads the - * segment routing related configuration from Network Configuration Manager - * component and organizes in more accessible formats. - */ -public class DeviceConfiguration implements DeviceProperties { - - private static final Logger log = LoggerFactory - .getLogger(DeviceConfiguration.class); - private final List<Integer> allSegmentIds = new ArrayList<>(); - private final ConcurrentHashMap<DeviceId, SegmentRouterInfo> deviceConfigMap - = new ConcurrentHashMap<>(); - - private class SegmentRouterInfo { - int nodeSid; - DeviceId deviceId; - Ip4Address ip; - MacAddress mac; - boolean isEdge; - HashMap<PortNumber, Ip4Address> gatewayIps; - HashMap<PortNumber, Ip4Prefix> subnets; - Map<Integer, Set<Integer>> adjacencySids; - - public SegmentRouterInfo() { - this.gatewayIps = new HashMap<>(); - this.subnets = new HashMap<>(); - } - } - - /** - * Constructor. Reads all the configuration for all devices of type - * Segment Router and organizes into various maps for easier access. - * - * @param cfgService config service - */ - public DeviceConfiguration(NetworkConfigRegistry cfgService) { - // Read config from device subject, excluding gatewayIps and subnets. - Set<DeviceId> deviceSubjects = - cfgService.getSubjects(DeviceId.class, SegmentRoutingConfig.class); - deviceSubjects.forEach(subject -> { - SegmentRoutingConfig config = - cfgService.getConfig(subject, SegmentRoutingConfig.class); - SegmentRouterInfo info = new SegmentRouterInfo(); - info.deviceId = subject; - info.nodeSid = config.nodeSid(); - info.ip = config.routerIp(); - info.mac = config.routerMac(); - info.isEdge = config.isEdgeRouter(); - info.adjacencySids = config.adjacencySids(); - - this.deviceConfigMap.put(info.deviceId, info); - this.allSegmentIds.add(info.nodeSid); - }); - - // Read gatewayIps and subnets from port subject. - Set<ConnectPoint> portSubjects = - cfgService.getSubjects(ConnectPoint.class, InterfaceConfig.class); - portSubjects.forEach(subject -> { - InterfaceConfig config = - cfgService.getConfig(subject, InterfaceConfig.class); - Set<Interface> networkInterfaces; - try { - networkInterfaces = config.getInterfaces(); - } catch (ConfigException e) { - log.error("Error loading port configuration"); - return; - } - networkInterfaces.forEach(networkInterface -> { - DeviceId dpid = networkInterface.connectPoint().deviceId(); - PortNumber port = networkInterface.connectPoint().port(); - SegmentRouterInfo info = this.deviceConfigMap.get(dpid); - - // skip if there is no corresponding device for this ConenctPoint - if (info != null) { - Set<InterfaceIpAddress> interfaceAddresses = networkInterface.ipAddresses(); - interfaceAddresses.forEach(interfaceAddress -> { - info.gatewayIps.put(port, interfaceAddress.ipAddress().getIp4Address()); - info.subnets.put(port, interfaceAddress.subnetAddress().getIp4Prefix()); - }); - } - }); - - }); - } - - @Override - public boolean isConfigured(DeviceId deviceId) { - return deviceConfigMap.get(deviceId) != null; - } - - @Override - public int getSegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("getSegmentId for device{} is {}", deviceId, srinfo.nodeSid); - return srinfo.nodeSid; - } else { - String message = "getSegmentId fails for device: " + deviceId + "."; - throw new DeviceConfigNotFoundException(message); - } - } - - /** - * Returns the Node segment id of a segment router given its Router mac address. - * - * @param routerMac router mac address - * @return node segment id, or -1 if not found in config - */ - public int getSegmentId(MacAddress routerMac) { - for (Map.Entry<DeviceId, SegmentRouterInfo> entry: - deviceConfigMap.entrySet()) { - if (entry.getValue().mac.equals(routerMac)) { - return entry.getValue().nodeSid; - } - } - - return -1; - } - - /** - * Returns the Node segment id of a segment router given its Router ip address. - * - * @param routerAddress router ip address - * @return node segment id, or -1 if not found in config - */ - public int getSegmentId(Ip4Address routerAddress) { - for (Map.Entry<DeviceId, SegmentRouterInfo> entry: - deviceConfigMap.entrySet()) { - if (entry.getValue().ip.equals(routerAddress)) { - return entry.getValue().nodeSid; - } - } - - return -1; - } - - @Override - public MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("getDeviceMac for device{} is {}", deviceId, srinfo.mac); - return srinfo.mac; - } else { - String message = "getDeviceMac fails for device: " + deviceId + "."; - throw new DeviceConfigNotFoundException(message); - } - } - - @Override - public Ip4Address getRouterIp(DeviceId deviceId) throws DeviceConfigNotFoundException { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("getDeviceIp for device{} is {}", deviceId, srinfo.ip); - return srinfo.ip; - } else { - String message = "getRouterIp fails for device: " + deviceId + "."; - throw new DeviceConfigNotFoundException(message); - } - } - - @Override - public boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("isEdgeDevice for device{} is {}", deviceId, srinfo.isEdge); - return srinfo.isEdge; - } else { - String message = "isEdgeDevice fails for device: " + deviceId + "."; - throw new DeviceConfigNotFoundException(message); - } - } - - @Override - public List<Integer> getAllDeviceSegmentIds() { - return allSegmentIds; - } - - @Override - public Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId) { - Map<Ip4Prefix, List<PortNumber>> subnetPortMap = new HashMap<>(); - - // Construct subnet-port mapping from port-subnet mapping - Map<PortNumber, Ip4Prefix> portSubnetMap = - this.deviceConfigMap.get(deviceId).subnets; - portSubnetMap.forEach((port, subnet) -> { - if (subnetPortMap.containsKey(subnet)) { - subnetPortMap.get(subnet).add(port); - } else { - ArrayList<PortNumber> ports = new ArrayList<>(); - ports.add(port); - subnetPortMap.put(subnet, ports); - } - }); - - return subnetPortMap; - } - - /** - * Returns the device identifier or data plane identifier (dpid) - * of a segment router given its segment id. - * - * @param sid segment id - * @return deviceId device identifier - */ - public DeviceId getDeviceId(int sid) { - for (Map.Entry<DeviceId, SegmentRouterInfo> entry: - deviceConfigMap.entrySet()) { - if (entry.getValue().nodeSid == sid) { - return entry.getValue().deviceId; - } - } - - return null; - } - - /** - * Returns the device identifier or data plane identifier (dpid) - * of a segment router given its router ip address. - * - * @param ipAddress router ip address - * @return deviceId device identifier - */ - public DeviceId getDeviceId(Ip4Address ipAddress) { - for (Map.Entry<DeviceId, SegmentRouterInfo> entry: - deviceConfigMap.entrySet()) { - if (entry.getValue().ip.equals(ipAddress)) { - return entry.getValue().deviceId; - } - } - - return null; - } - - /** - * Returns the configured port ip addresses for a segment router. - * These addresses serve as gateway IP addresses for the subnets configured - * on those ports. - * - * @param deviceId device identifier - * @return immutable set of ip addresses configured on the ports or null if not found - */ - public Set<Ip4Address> getPortIPs(DeviceId deviceId) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("getSubnetGatewayIps for device{} is {}", deviceId, - srinfo.gatewayIps.values()); - return ImmutableSet.copyOf(srinfo.gatewayIps.values()); - } - return null; - } - - /** - * Returns the configured IP addresses per port - * for a segment router. - * - * @param deviceId device identifier - * @return map of port to gateway IP addresses or null if not found - */ - public Map<PortNumber, Ip4Address> getPortIPMap(DeviceId deviceId) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - return srinfo.gatewayIps; - } - return null; - } - - /** - * Returns the configured subnet prefixes for a segment router. - * - * @param deviceId device identifier - * @return list of ip prefixes or null if not found - */ - public Set<Ip4Prefix> getSubnets(DeviceId deviceId) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - log.trace("getSubnets for device{} is {}", deviceId, - srinfo.subnets.values()); - return ImmutableSet.copyOf(srinfo.subnets.values()); - } - return null; - } - - /** - * Returns the configured subnet on the given port, or null if no - * subnet has been configured on the port. - * - * @param deviceId device identifier - * @param pnum port identifier - * @return configured subnet on port, or null - */ - public Ip4Prefix getPortSubnet(DeviceId deviceId, PortNumber pnum) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - return srinfo.subnets.get(pnum); - } - return null; - } - - /** - * Returns the router ip address of segment router that has the - * specified ip address in its subnets. - * - * @param destIpAddress target ip address - * @return router ip address - */ - public Ip4Address getRouterIpAddressForASubnetHost(Ip4Address destIpAddress) { - for (Map.Entry<DeviceId, SegmentRouterInfo> entry: - deviceConfigMap.entrySet()) { - for (Ip4Prefix prefix:entry.getValue().subnets.values()) { - if (prefix.contains(destIpAddress)) { - return entry.getValue().ip; - } - } - } - - log.debug("No router was found for {}", destIpAddress); - return null; - } - - /** - * Returns the router mac address of segment router that has the - * specified ip address as one of its subnet gateway ip address. - * - * @param gatewayIpAddress router gateway ip address - * @return router mac address or null if not found - */ - public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) { - for (Map.Entry<DeviceId, SegmentRouterInfo> entry: - deviceConfigMap.entrySet()) { - if (entry.getValue().gatewayIps. - values().contains(gatewayIpAddress)) { - return entry.getValue().mac; - } - } - - log.debug("Cannot find a router for {}", gatewayIpAddress); - return null; - } - - - /** - * Checks if the host is in the subnet defined in the router with the - * device ID given. - * - * @param deviceId device identification of the router - * @param hostIp host IP address to check - * @return true if the host is within the subnet of the router, - * false if no subnet is defined under the router or if the host is not - * within the subnet defined in the router - */ - public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) { - - Set<Ip4Prefix> subnets = getSubnets(deviceId); - if (subnets == null) { - return false; - } - - for (Ip4Prefix subnet: subnets) { - if (subnet.contains(hostIp)) { - return true; - } - } - - return false; - } - - /** - * Returns the ports corresponding to the adjacency Sid given. - * - * @param deviceId device identification of the router - * @param sid adjacency Sid - * @return set of port numbers - */ - public Set<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - return srinfo != null ? - ImmutableSet.copyOf(srinfo.adjacencySids.get(sid)) : - ImmutableSet.copyOf(new HashSet<>()); - } - - /** - * Check if the Sid given is whether adjacency Sid of the router device or not. - * - * @param deviceId device identification of the router - * @param sid Sid to check - * @return true if the Sid given is the adjacency Sid of the device, - * otherwise false - */ - public boolean isAdjacencySid(DeviceId deviceId, int sid) { - SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - return srinfo != null && srinfo.adjacencySids.containsKey(sid); - } -}
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java deleted file mode 100644 index a39c9567..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2014-2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.onosproject.segmentrouting.config; - -import java.util.List; -import java.util.Map; - -import org.onlab.packet.Ip4Address; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.MacAddress; -import org.onosproject.net.DeviceId; -import org.onosproject.net.PortNumber; - -/** - * Mechanism through which group handler module retrieves - * the device specific attributes such as segment ID, - * Mac address...etc from group handler applications. - */ -public interface DeviceProperties { - /** - * Checks if the device is configured. - * - * @param deviceId device identifier - * @return true if the device is configured - */ - boolean isConfigured(DeviceId deviceId); - - /** - * Returns the segment id of a device to be used in group creation. - * - * @param deviceId device identifier - * @throws DeviceConfigNotFoundException if the device configuration is not found - * @return segment id of a device - */ - int getSegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException; - - /** - * Returns the Mac address of a device to be used in group creation. - * - * @param deviceId device identifier - * @throws DeviceConfigNotFoundException if the device configuration is not found - * @return mac address of a device - */ - MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException; - - /** - * Returns the router ip address of a segment router. - * - * @param deviceId device identifier - * @throws DeviceConfigNotFoundException if the device configuration is not found - * @return router ip address - */ - Ip4Address getRouterIp(DeviceId deviceId) throws DeviceConfigNotFoundException; - - /** - * Indicates whether a device is edge device or transit/core device. - * - * @param deviceId device identifier - * @throws DeviceConfigNotFoundException if the device configuration is not found - * @return boolean - */ - boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException; - - /** - * Returns all segment IDs to be considered in building auto - * - * created groups. - * @return list of segment IDs - */ - List<Integer> getAllDeviceSegmentIds(); - - /** - * Returns subnet-to-ports mapping of given device. - * - * For each entry of the map - * Key: a subnet - * Value: a list of ports, which are bound to the subnet - * - * @param deviceId device identifier - * @return a map that contains all subnet-to-ports mapping of given device - */ - Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId); -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java deleted file mode 100644 index f788925c..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2014-2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.segmentrouting.config; - -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.ImmutableMap; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.MacAddress; -import org.onosproject.net.DeviceId; -import org.onosproject.net.config.Config; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -/** - * Configuration object for Segment Routing Application. - */ -public class SegmentRoutingConfig extends Config<DeviceId> { - public static final String NAME = "name"; - public static final String IP = "routerIp"; - public static final String MAC = "routerMac"; - public static final String SID = "nodeSid"; - public static final String EDGE = "isEdgeRouter"; - public static final String ADJSIDS = "adjacencySids"; - public static final String ADJSID = "adjSid"; - public static final String PORTS = "ports"; - - @Override - public boolean isValid() { - return hasOnlyFields(NAME, IP, MAC, SID, EDGE, ADJSIDS, ADJSID, PORTS) && - this.name() != null && - this.routerIp() != null && - this.routerMac() != null && - this.nodeSid() != -1 && - this.isEdgeRouter() != null && - this.adjacencySids() != null; - } - - /** - * Gets the name of the router. - * - * @return Optional name of the router. May be empty if not configured. - */ - public Optional<String> name() { - String name = get(NAME, null); - return name != null ? Optional.of(name) : Optional.empty(); - } - - /** - * Sets the name of the router. - * - * @param name name of the router. - * @return the config of the router. - */ - public SegmentRoutingConfig setName(String name) { - return (SegmentRoutingConfig) setOrClear(NAME, name); - } - - /** - * Gets the IP address of the router. - * - * @return IP address of the router. Or null if not configured. - */ - public Ip4Address routerIp() { - String ip = get(IP, null); - return ip != null ? Ip4Address.valueOf(ip) : null; - } - - /** - * Sets the IP address of the router. - * - * @param ip IP address of the router. - * @return the config of the router. - */ - public SegmentRoutingConfig setRouterIp(String ip) { - return (SegmentRoutingConfig) setOrClear(IP, ip); - } - - /** - * Gets the MAC address of the router. - * - * @return MAC address of the router. Or null if not configured. - */ - public MacAddress routerMac() { - String mac = get(MAC, null); - return mac != null ? MacAddress.valueOf(mac) : null; - } - - /** - * Sets the MAC address of the router. - * - * @param mac MAC address of the router. - * @return the config of the router. - */ - public SegmentRoutingConfig setRouterMac(String mac) { - return (SegmentRoutingConfig) setOrClear(MAC, mac); - } - - /** - * Gets the node SID of the router. - * - * @return node SID of the router. Or -1 if not configured. - */ - public int nodeSid() { - return get(SID, -1); - } - - /** - * Sets the node SID of the router. - * - * @param sid node SID of the router. - * @return the config of the router. - */ - public SegmentRoutingConfig setNodeSid(int sid) { - return (SegmentRoutingConfig) setOrClear(SID, sid); - } - - /** - * Checks if the router is an edge router. - * - * @return true if the router is an edge router. - * false if the router is not an edge router. - * null if the value is not configured. - */ - public Boolean isEdgeRouter() { - String isEdgeRouter = get(EDGE, null); - return isEdgeRouter != null ? - Boolean.valueOf(isEdgeRouter) : - null; - } - - /** - * Specifies if the router is an edge router. - * - * @param isEdgeRouter true if the router is an edge router. - * @return the config of the router. - */ - public SegmentRoutingConfig setIsEdgeRouter(boolean isEdgeRouter) { - return (SegmentRoutingConfig) setOrClear(EDGE, isEdgeRouter); - } - - /** - * Gets the adjacency SIDs of the router. - * - * @return adjacency SIDs of the router. Or null if not configured. - */ - public Map<Integer, Set<Integer>> adjacencySids() { - if (!object.has(ADJSIDS)) { - return null; - } - - Map<Integer, Set<Integer>> adjacencySids = new HashMap<>(); - ArrayNode adjacencySidsNode = (ArrayNode) object.path(ADJSIDS); - for (JsonNode adjacencySidNode : adjacencySidsNode) { - int asid = adjacencySidNode.path(ADJSID).asInt(-1); - if (asid == -1) { - return null; - } - - HashSet<Integer> ports = new HashSet<>(); - ArrayNode portsNode = (ArrayNode) adjacencySidNode.path(PORTS); - for (JsonNode portNode : portsNode) { - int port = portNode.asInt(-1); - if (port == -1) { - return null; - } - ports.add(port); - } - adjacencySids.put(asid, ports); - } - - return ImmutableMap.copyOf(adjacencySids); - } - - /** - * Sets the adjacency SIDs of the router. - * - * @param adjacencySids adjacency SIDs of the router. - * @return the config of the router. - */ - public SegmentRoutingConfig setAdjacencySids(Map<Integer, Set<Integer>> adjacencySids) { - if (adjacencySids == null) { - object.remove(ADJSIDS); - } else { - ArrayNode adjacencySidsNode = mapper.createArrayNode(); - - adjacencySids.forEach((sid, ports) -> { - ObjectNode adjacencySidNode = mapper.createObjectNode(); - - adjacencySidNode.put(ADJSID, sid); - - ArrayNode portsNode = mapper.createArrayNode(); - ports.forEach(port -> { - portsNode.add(port.toString()); - }); - adjacencySidNode.set(PORTS, portsNode); - - adjacencySidsNode.add(adjacencySidNode); - }); - - object.set(ADJSIDS, adjacencySidsNode); - } - - return this; - } -}
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/package-info.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/package-info.java deleted file mode 100644 index 95f7e244..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2014-2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Segment routing network configuration mechanism. - */ -package org.onosproject.segmentrouting.config;
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java deleted file mode 100644 index 32c53654..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java +++ /dev/null @@ -1,187 +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.segmentrouting.grouphandler; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.onosproject.core.ApplicationId; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Link; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.link.LinkService; -import org.onosproject.segmentrouting.config.DeviceProperties; -import org.onosproject.store.service.EventuallyConsistentMap; - -/** - * Default ECMP group handler creation module for an edge device. - * This component creates a set of ECMP groups for every neighbor - * that this device is connected to. - * For example, consider a network of 4 devices: D0 (Segment ID: 100), - * D1 (Segment ID: 101), D2 (Segment ID: 102) and D3 (Segment ID: 103), - * where D0 and D3 are edge devices and D1 and D2 are transit devices. - * Assume device D0 is connected to 2 neighbors (D1 and D2 ). - * The following groups will be created in D0: - * 1) all ports to D1 + with no label push, // direct attach case, seen - * 2) all ports to D1 + with label 102 pushed, // this is not needed - * 3) all ports to D1 + with label 103 pushed, // maybe needed, sometimes seen - * 4) all ports to D2 + with no label push, - * 5) all ports to D2 + with label 101 pushed, - * 6) all ports to D2 + with label 103 pushed, - * 7) all ports to D1 and D2 + with label 103 pushed // ecmp case - * 8) what about ecmp no label case - */ -public class DefaultEdgeGroupHandler extends DefaultGroupHandler { - - protected DefaultEdgeGroupHandler(DeviceId deviceId, - ApplicationId appId, - DeviceProperties config, - LinkService linkService, - FlowObjectiveService flowObjService, - EventuallyConsistentMap< - NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore, - EventuallyConsistentMap<SubnetNextObjectiveStoreKey, - Integer> subnetNextObjStore, - EventuallyConsistentMap<PortNextObjectiveStoreKey, - Integer> portNextObjStore) { - super(deviceId, appId, config, linkService, flowObjService, - nsNextObjStore, subnetNextObjStore, portNextObjStore); - } - - @Override - public void createGroups() { - log.debug("Creating default groups " - + "for edge device {}", deviceId); - Set<DeviceId> neighbors = devicePortMap.keySet(); - if (neighbors == null || neighbors.isEmpty()) { - return; - } - - // Create all possible Neighbor sets from this router - Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(neighbors); - log.trace("createGroupsAtEdgeRouter: The size of neighbor powerset " - + "for sw {} is {}", deviceId, powerSet.size()); - Set<NeighborSet> nsSet = new HashSet<>(); - for (Set<DeviceId> combo : powerSet) { - if (combo.isEmpty()) { - continue; - } - List<Integer> groupSegmentIds = - getSegmentIdsTobePairedWithNeighborSet(combo); - for (Integer sId : groupSegmentIds) { - NeighborSet ns = new NeighborSet(combo, sId); - log.trace("createGroupsAtEdgeRouter: sw {} " - + "combo {} sId {} ns {}", - deviceId, combo, sId, ns); - nsSet.add(ns); - } - } - log.trace("createGroupsAtEdgeRouter: The neighborset " - + "with label for sw {} is {}", - deviceId, nsSet); - - //createGroupsFromNeighborsets(nsSet); - } - - @Override - protected void newNeighbor(Link newNeighborLink) { - log.debug("New Neighbor: Updating groups " - + "for edge device {}", deviceId); - // Recompute neighbor power set - addNeighborAtPort(newNeighborLink.dst().deviceId(), - newNeighborLink.src().port()); - // Compute new neighbor sets due to the addition of new neighbor - Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent( - newNeighborLink.dst().deviceId(), - devicePortMap.keySet()); - //createGroupsFromNeighborsets(nsSet); - } - - @Override - protected void newPortToExistingNeighbor(Link newNeighborLink) { - /*log.debug("New port to existing neighbor: Updating " - + "groups for edge device {}", deviceId); - addNeighborAtPort(newNeighborLink.dst().deviceId(), - newNeighborLink.src().port()); - Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent( - newNeighborLink.dst().deviceId(), - devicePortMap.keySet()); - for (NeighborSet ns : nsSet) { - // Create the new bucket to be updated - TrafficTreatment.Builder tBuilder = - DefaultTrafficTreatment.builder(); - tBuilder.setOutput(newNeighborLink.src().port()) - .setEthDst(deviceConfig.getDeviceMac( - newNeighborLink.dst().deviceId())) - .setEthSrc(nodeMacAddr); - if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { - tBuilder.pushMpls() - .setMpls(MplsLabel. - mplsLabel(ns.getEdgeLabel())); - } - - Integer nextId = deviceNextObjectiveIds.get(ns); - if (nextId != null) { - NextObjective.Builder nextObjBuilder = DefaultNextObjective - .builder().withId(nextId) - .withType(NextObjective.Type.HASHED).fromApp(appId); - - nextObjBuilder.addTreatment(tBuilder.build()); - - NextObjective nextObjective = nextObjBuilder.add(); - flowObjectiveService.next(deviceId, nextObjective); - } - }*/ - } - - @Override - protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent( - DeviceId impactedNeighbor, - Set<DeviceId> updatedNeighbors) { - Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors); - - Set<DeviceId> tmp = new HashSet<>(); - tmp.addAll(updatedNeighbors); - tmp.remove(impactedNeighbor); - Set<Set<DeviceId>> tmpPowerSet = getPowerSetOfNeighbors(tmp); - - // Compute the impacted neighbor sets - powerSet.removeAll(tmpPowerSet); - - Set<NeighborSet> nsSet = new HashSet<>(); - for (Set<DeviceId> combo : powerSet) { - if (combo.isEmpty()) { - continue; - } - List<Integer> groupSegmentIds = - getSegmentIdsTobePairedWithNeighborSet(combo); - for (Integer sId : groupSegmentIds) { - NeighborSet ns = new NeighborSet(combo, sId); - log.trace("computeImpactedNeighborsetForPortEvent: sw {} " - + "combo {} sId {} ns {}", - deviceId, combo, sId, ns); - nsSet.add(ns); - } - } - log.trace("computeImpactedNeighborsetForPortEvent: The neighborset " - + "with label for sw {} is {}", - deviceId, nsSet); - return nsSet; - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java deleted file mode 100644 index bc394b84..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java +++ /dev/null @@ -1,739 +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.segmentrouting.grouphandler; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.slf4j.LoggerFactory.getLogger; - -import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.MacAddress; -import org.onlab.packet.MplsLabel; -import org.onlab.util.KryoNamespace; -import org.onosproject.core.ApplicationId; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Link; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.TrafficSelector; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flowobjective.DefaultNextObjective; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.flowobjective.NextObjective; -import org.onosproject.net.flowobjective.Objective; -import org.onosproject.net.flowobjective.ObjectiveContext; -import org.onosproject.net.flowobjective.ObjectiveError; -import org.onosproject.net.group.DefaultGroupKey; -import org.onosproject.net.group.GroupKey; -import org.onosproject.net.link.LinkService; -import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; -import org.onosproject.segmentrouting.config.DeviceProperties; -import org.onosproject.store.service.EventuallyConsistentMap; -import org.slf4j.Logger; - -/** - * Default ECMP group handler creation module. This component creates a set of - * ECMP groups for every neighbor that this device is connected to based on - * whether the current device is an edge device or a transit device. - */ -public class DefaultGroupHandler { - protected static final Logger log = getLogger(DefaultGroupHandler.class); - - protected final DeviceId deviceId; - protected final ApplicationId appId; - protected final DeviceProperties deviceConfig; - protected final List<Integer> allSegmentIds; - protected int nodeSegmentId = -1; - protected boolean isEdgeRouter = false; - protected MacAddress nodeMacAddr = null; - protected LinkService linkService; - protected FlowObjectiveService flowObjectiveService; - - protected ConcurrentHashMap<DeviceId, Set<PortNumber>> devicePortMap = - new ConcurrentHashMap<>(); - protected ConcurrentHashMap<PortNumber, DeviceId> portDeviceMap = - new ConcurrentHashMap<>(); - protected EventuallyConsistentMap< - NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null; - protected EventuallyConsistentMap< - SubnetNextObjectiveStoreKey, Integer> subnetNextObjStore = null; - protected EventuallyConsistentMap< - PortNextObjectiveStoreKey, Integer> portNextObjStore = null; - - protected KryoNamespace.Builder kryo = new KryoNamespace.Builder() - .register(URI.class).register(HashSet.class) - .register(DeviceId.class).register(PortNumber.class) - .register(NeighborSet.class).register(PolicyGroupIdentifier.class) - .register(PolicyGroupParams.class) - .register(GroupBucketIdentifier.class) - .register(GroupBucketIdentifier.BucketOutputType.class); - - protected DefaultGroupHandler(DeviceId deviceId, ApplicationId appId, - DeviceProperties config, - LinkService linkService, - FlowObjectiveService flowObjService, - EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore, - EventuallyConsistentMap<SubnetNextObjectiveStoreKey, - Integer> subnetNextObjStore, - EventuallyConsistentMap<PortNextObjectiveStoreKey, - Integer> portNextObjStore) { - this.deviceId = checkNotNull(deviceId); - this.appId = checkNotNull(appId); - this.deviceConfig = checkNotNull(config); - this.linkService = checkNotNull(linkService); - this.allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds()); - try { - this.nodeSegmentId = config.getSegmentId(deviceId); - this.isEdgeRouter = config.isEdgeDevice(deviceId); - this.nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId)); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() - + " Skipping value assignment in DefaultGroupHandler"); - } - this.flowObjectiveService = flowObjService; - this.nsNextObjStore = nsNextObjStore; - this.subnetNextObjStore = subnetNextObjStore; - this.portNextObjStore = portNextObjStore; - - populateNeighborMaps(); - } - - /** - * Creates a group handler object based on the type of device. If device is - * of edge type it returns edge group handler, else it returns transit group - * handler. - * - * @param deviceId device identifier - * @param appId application identifier - * @param config interface to retrieve the device properties - * @param linkService link service object - * @param flowObjService flow objective service object - * @param nsNextObjStore NeighborSet next objective store map - * @param subnetNextObjStore subnet next objective store map - * @throws DeviceConfigNotFoundException if the device configuration is not found - * @return default group handler type - */ - public static DefaultGroupHandler createGroupHandler( - DeviceId deviceId, - ApplicationId appId, - DeviceProperties config, - LinkService linkService, - FlowObjectiveService flowObjService, - EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore, - EventuallyConsistentMap<SubnetNextObjectiveStoreKey, - Integer> subnetNextObjStore, - EventuallyConsistentMap<PortNextObjectiveStoreKey, - Integer> portNextObjStore) - throws DeviceConfigNotFoundException { - // handle possible exception in the caller - if (config.isEdgeDevice(deviceId)) { - return new DefaultEdgeGroupHandler(deviceId, appId, config, - linkService, - flowObjService, - nsNextObjStore, - subnetNextObjStore, - portNextObjStore); - } else { - return new DefaultTransitGroupHandler(deviceId, appId, config, - linkService, - flowObjService, - nsNextObjStore, - subnetNextObjStore, - portNextObjStore); - } - } - - /** - * Creates the auto created groups for this device based on the current - * snapshot of the topology. - */ - // Empty implementations to be overridden by derived classes - public void createGroups() { - } - - /** - * Performs group creation or update procedures when a new link is - * discovered on this device. - * - * @param newLink new neighbor link - */ - public void linkUp(Link newLink, boolean isMaster) { - - if (newLink.type() != Link.Type.DIRECT) { - log.warn("linkUp: unknown link type"); - return; - } - - if (!newLink.src().deviceId().equals(deviceId)) { - log.warn("linkUp: deviceId{} doesn't match with link src{}", - deviceId, newLink.src().deviceId()); - return; - } - - log.info("* LinkUP: Device {} linkUp at local port {} to neighbor {}", deviceId, - newLink.src().port(), newLink.dst().deviceId()); - MacAddress dstMac; - try { - dstMac = deviceConfig.getDeviceMac(newLink.dst().deviceId()); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting linkUp."); - return; - } - - addNeighborAtPort(newLink.dst().deviceId(), - newLink.src().port()); - /*if (devicePortMap.get(newLink.dst().deviceId()) == null) { - // New Neighbor - newNeighbor(newLink); - } else { - // Old Neighbor - newPortToExistingNeighbor(newLink); - }*/ - Set<NeighborSet> nsSet = nsNextObjStore.keySet() - .stream() - .filter((nsStoreEntry) -> (nsStoreEntry.deviceId().equals(deviceId))) - .map((nsStoreEntry) -> (nsStoreEntry.neighborSet())) - .filter((ns) -> (ns.getDeviceIds() - .contains(newLink.dst().deviceId()))) - .collect(Collectors.toSet()); - log.trace("linkUp: nsNextObjStore contents for device {}:", - deviceId, - nsSet); - for (NeighborSet ns : nsSet) { - // Create the new bucket to be updated - TrafficTreatment.Builder tBuilder = - DefaultTrafficTreatment.builder(); - tBuilder.setOutput(newLink.src().port()) - .setEthDst(dstMac) - .setEthSrc(nodeMacAddr); - if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { - tBuilder.pushMpls() - .copyTtlOut() - .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); - } - - Integer nextId = nsNextObjStore. - get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); - if (nextId != null && isMaster) { - NextObjective.Builder nextObjBuilder = DefaultNextObjective - .builder().withId(nextId) - .withType(NextObjective.Type.HASHED).fromApp(appId); - - nextObjBuilder.addTreatment(tBuilder.build()); - log.info("**linkUp in device {}: Adding Bucket " - + "with Port {} to next object id {}", - deviceId, - newLink.src().port(), - nextId); - NextObjective nextObjective = nextObjBuilder. - addToExisting(new SRNextObjectiveContext(deviceId)); - flowObjectiveService.next(deviceId, nextObjective); - } else if (isMaster) { - log.warn("linkUp in device {}, but global store has no record " - + "for neighbor-set {}", deviceId, ns); - } - } - } - - /** - * Performs group recovery procedures when a port goes down on this device. - * - * @param port port number that has gone down - */ - public void portDown(PortNumber port) { - if (portDeviceMap.get(port) == null) { - log.warn("portDown: unknown port"); - return; - } - - MacAddress dstMac; - try { - dstMac = deviceConfig.getDeviceMac(portDeviceMap.get(port)); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting portDown."); - return; - } - - log.debug("Device {} portDown {} to neighbor {}", deviceId, port, - portDeviceMap.get(port)); - /*Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap - .get(port), - devicePortMap - .keySet());*/ - Set<NeighborSet> nsSet = nsNextObjStore.keySet() - .stream() - .filter((nsStoreEntry) -> (nsStoreEntry.deviceId().equals(deviceId))) - .map((nsStoreEntry) -> (nsStoreEntry.neighborSet())) - .filter((ns) -> (ns.getDeviceIds() - .contains(portDeviceMap.get(port)))) - .collect(Collectors.toSet()); - log.trace("portDown: nsNextObjStore contents for device {}:", - deviceId, - nsSet); - for (NeighborSet ns : nsSet) { - // Create the bucket to be removed - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment - .builder(); - tBuilder.setOutput(port) - .setEthDst(dstMac) - .setEthSrc(nodeMacAddr); - if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { - tBuilder.pushMpls() - .copyTtlOut() - .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); - } - - Integer nextId = nsNextObjStore. - get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); - if (nextId != null) { - NextObjective.Builder nextObjBuilder = DefaultNextObjective - .builder().withType(NextObjective.Type.SIMPLE).withId(nextId).fromApp(appId); - - nextObjBuilder.addTreatment(tBuilder.build()); - - log.info("**portDown in device {}: Removing Bucket " - + "with Port {} to next object id {}", - deviceId, - port, - nextId); - // should do removefromexisting and only if master - /*NextObjective nextObjective = nextObjBuilder. - remove(new SRNextObjectiveContext(deviceId)); - - flowObjectiveService.next(deviceId, nextObjective);*/ - } - - } - - devicePortMap.get(portDeviceMap.get(port)).remove(port); - portDeviceMap.remove(port); - } - - /** - * Returns the next objective of type hashed associated with the neighborset. - * If there is no next objective for this neighborset, this method - * would create a next objective and return. Optionally metadata can be - * passed in for the creation of the next objective. - * - * @param ns neighborset - * @param meta metadata passed into the creation of a Next Objective - * @return int if found or -1 if there are errors in the creation of the - * neighbor set. - */ - public int getNextObjectiveId(NeighborSet ns, TrafficSelector meta) { - Integer nextId = nsNextObjStore. - get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); - if (nextId == null) { - log.trace("getNextObjectiveId in device{}: Next objective id " - + "not found for {} and creating", deviceId, ns); - log.trace("getNextObjectiveId: nsNextObjStore contents for device {}: {}", - deviceId, - nsNextObjStore.entrySet() - .stream() - .filter((nsStoreEntry) -> - (nsStoreEntry.getKey().deviceId().equals(deviceId))) - .collect(Collectors.toList())); - createGroupsFromNeighborsets(Collections.singleton(ns), meta); - nextId = nsNextObjStore. - get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); - if (nextId == null) { - log.warn("getNextObjectiveId: unable to create next objective"); - return -1; - } else { - log.debug("getNextObjectiveId in device{}: Next objective id {} " - + "created for {}", deviceId, nextId, ns); - } - } else { - log.trace("getNextObjectiveId in device{}: Next objective id {} " - + "found for {}", deviceId, nextId, ns); - } - return nextId; - } - - /** - * Returns the next objective of type broadcast associated with the subnet, - * or -1 if no such objective exists. Note that this method does NOT create - * the next objective as a side-effect. It is expected that is objective is - * created at startup from network configuration. - * - * @param prefix subnet information - * @return int if found or -1 - */ - public int getSubnetNextObjectiveId(IpPrefix prefix) { - Integer nextId = subnetNextObjStore. - get(new SubnetNextObjectiveStoreKey(deviceId, prefix)); - - return (nextId != null) ? nextId : -1; - } - - /** - * Returns the next objective of type simple associated with the port on the - * device, given the treatment. Different treatments to the same port result - * in different next objectives. If no such objective exists, this method - * creates one and returns the id. Optionally metadata can be passed in for - * the creation of the objective. - * - * @param portNum the port number for the simple next objective - * @param treatment the actions to apply on the packets (should include outport) - * @param meta optional metadata passed into the creation of the next objective - * @return int if found or created, -1 if there are errors during the - * creation of the next objective. - */ - public int getPortNextObjectiveId(PortNumber portNum, TrafficTreatment treatment, - TrafficSelector meta) { - Integer nextId = portNextObjStore. - get(new PortNextObjectiveStoreKey(deviceId, portNum, treatment)); - if (nextId == null) { - log.trace("getPortNextObjectiveId in device{}: Next objective id " - + "not found for {} and {} creating", deviceId, portNum); - createGroupFromPort(portNum, treatment, meta); - nextId = portNextObjStore.get( - new PortNextObjectiveStoreKey(deviceId, portNum, treatment)); - if (nextId == null) { - log.warn("getPortNextObjectiveId: unable to create next obj" - + "for dev:{} port{}", deviceId, portNum); - return -1; - } - } - return nextId; - } - - /** - * Checks if the next objective ID (group) for the neighbor set exists or not. - * - * @param ns neighbor set to check - * @return true if it exists, false otherwise - */ - public boolean hasNextObjectiveId(NeighborSet ns) { - Integer nextId = nsNextObjStore. - get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); - if (nextId == null) { - return false; - } - - return true; - } - - // Empty implementation - protected void newNeighbor(Link newLink) { - } - - // Empty implementation - protected void newPortToExistingNeighbor(Link newLink) { - } - - // Empty implementation - protected Set<NeighborSet> - computeImpactedNeighborsetForPortEvent(DeviceId impactedNeighbor, - Set<DeviceId> updatedNeighbors) { - return null; - } - - private void populateNeighborMaps() { - Set<Link> outgoingLinks = linkService.getDeviceEgressLinks(deviceId); - for (Link link : outgoingLinks) { - if (link.type() != Link.Type.DIRECT) { - continue; - } - addNeighborAtPort(link.dst().deviceId(), link.src().port()); - } - } - - protected void addNeighborAtPort(DeviceId neighborId, - PortNumber portToNeighbor) { - // Update DeviceToPort database - log.debug("Device {} addNeighborAtPort: neighbor {} at port {}", - deviceId, neighborId, portToNeighbor); - Set<PortNumber> ports = Collections - .newSetFromMap(new ConcurrentHashMap<PortNumber, Boolean>()); - ports.add(portToNeighbor); - Set<PortNumber> portnums = devicePortMap.putIfAbsent(neighborId, ports); - if (portnums != null) { - portnums.add(portToNeighbor); - } - - // Update portToDevice database - DeviceId prev = portDeviceMap.putIfAbsent(portToNeighbor, neighborId); - if (prev != null) { - log.warn("Device: {} port: {} has neighbor: {}. NOT updating " - + "to neighbor: {}", deviceId, portToNeighbor, prev, neighborId); - } - } - - protected Set<Set<DeviceId>> getPowerSetOfNeighbors(Set<DeviceId> neighbors) { - List<DeviceId> list = new ArrayList<>(neighbors); - Set<Set<DeviceId>> sets = new HashSet<>(); - // get the number of elements in the neighbors - int elements = list.size(); - // the number of members of a power set is 2^n - // including the empty set - int powerElements = (1 << elements); - - // run a binary counter for the number of power elements - // NOTE: Exclude empty set - for (long i = 1; i < powerElements; i++) { - Set<DeviceId> neighborSubSet = new HashSet<>(); - for (int j = 0; j < elements; j++) { - if ((i >> j) % 2 == 1) { - neighborSubSet.add(list.get(j)); - } - } - sets.add(neighborSubSet); - } - return sets; - } - - private boolean isSegmentIdSameAsNodeSegmentId(DeviceId deviceId, int sId) { - int segmentId; - try { - segmentId = deviceConfig.getSegmentId(deviceId); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting isSegmentIdSameAsNodeSegmentId."); - return false; - } - - return segmentId == sId; - } - - protected List<Integer> getSegmentIdsTobePairedWithNeighborSet(Set<DeviceId> neighbors) { - - List<Integer> nsSegmentIds = new ArrayList<>(); - - // Always pair up with no edge label - // If (neighbors.size() == 1) { - nsSegmentIds.add(-1); - // } - - // Filter out SegmentIds matching with the - // nodes in the combo - for (Integer sId : allSegmentIds) { - if (sId.equals(nodeSegmentId)) { - continue; - } - boolean filterOut = false; - // Check if the edge label being set is of - // any node in the Neighbor set - for (DeviceId deviceId : neighbors) { - if (isSegmentIdSameAsNodeSegmentId(deviceId, sId)) { - filterOut = true; - break; - } - } - if (!filterOut) { - nsSegmentIds.add(sId); - } - } - return nsSegmentIds; - } - - /** - * Creates Groups from a set of NeighborSet given. - * - * @param nsSet a set of NeighborSet - * @param meta metadata passed into the creation of a Next Objective - */ - public void createGroupsFromNeighborsets(Set<NeighborSet> nsSet, - TrafficSelector meta) { - for (NeighborSet ns : nsSet) { - int nextId = flowObjectiveService.allocateNextId(); - NextObjective.Builder nextObjBuilder = DefaultNextObjective - .builder().withId(nextId) - .withType(NextObjective.Type.HASHED).fromApp(appId); - for (DeviceId neighborId : ns.getDeviceIds()) { - if (devicePortMap.get(neighborId) == null) { - log.warn("Neighbor {} is not in the port map yet for dev:{}", - neighborId, deviceId); - return; - } else if (devicePortMap.get(neighborId).size() == 0) { - log.warn("There are no ports for " - + "the Device {} in the port map yet", neighborId); - return; - } - - MacAddress neighborMac; - try { - neighborMac = deviceConfig.getDeviceMac(neighborId); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Aborting createGroupsFromNeighborsets."); - return; - } - - for (PortNumber sp : devicePortMap.get(neighborId)) { - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment - .builder(); - tBuilder.setEthDst(neighborMac) - .setEthSrc(nodeMacAddr); - if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { - tBuilder.pushMpls() - .copyTtlOut() - .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); - } - tBuilder.setOutput(sp); - nextObjBuilder.addTreatment(tBuilder.build()); - } - } - if (meta != null) { - nextObjBuilder.withMeta(meta); - } - NextObjective nextObj = nextObjBuilder. - add(new SRNextObjectiveContext(deviceId)); - log.info("**createGroupsFromNeighborsets: Submited " - + "next objective {} in device {}", - nextId, deviceId); - flowObjectiveService.next(deviceId, nextObj); - nsNextObjStore.put(new NeighborSetNextObjectiveStoreKey(deviceId, ns), - nextId); - } - } - - /** - * Creates broadcast groups for all ports in the same configured subnet. - * - */ - public void createGroupsFromSubnetConfig() { - Map<Ip4Prefix, List<PortNumber>> subnetPortMap = - this.deviceConfig.getSubnetPortsMap(this.deviceId); - // Construct a broadcast group for each subnet - subnetPortMap.forEach((subnet, ports) -> { - SubnetNextObjectiveStoreKey key = - new SubnetNextObjectiveStoreKey(deviceId, subnet); - - if (subnetNextObjStore.containsKey(key)) { - log.debug("Broadcast group for device {} and subnet {} exists", - deviceId, subnet); - return; - } - - int nextId = flowObjectiveService.allocateNextId(); - - NextObjective.Builder nextObjBuilder = DefaultNextObjective - .builder().withId(nextId) - .withType(NextObjective.Type.BROADCAST).fromApp(appId); - - ports.forEach(port -> { - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); - tBuilder.popVlan(); - tBuilder.setOutput(port); - nextObjBuilder.addTreatment(tBuilder.build()); - }); - - NextObjective nextObj = nextObjBuilder.add(); - flowObjectiveService.next(deviceId, nextObj); - log.debug("createGroupFromSubnetConfig: Submited " - + "next objective {} in device {}", - nextId, deviceId); - - subnetNextObjStore.put(key, nextId); - }); - } - - - /** - * Create simple next objective for a single port. The treatments can include - * all outgoing actions that need to happen on the packet. - * - * @param portNum the outgoing port on the device - * @param treatment the actions to apply on the packets (should include outport) - * @param meta optional data to pass to the driver - */ - public void createGroupFromPort(PortNumber portNum, TrafficTreatment treatment, - TrafficSelector meta) { - int nextId = flowObjectiveService.allocateNextId(); - PortNextObjectiveStoreKey key = new PortNextObjectiveStoreKey( - deviceId, portNum, treatment); - - NextObjective.Builder nextObjBuilder = DefaultNextObjective - .builder().withId(nextId) - .withType(NextObjective.Type.SIMPLE) - .addTreatment(treatment) - .fromApp(appId) - .withMeta(meta); - - NextObjective nextObj = nextObjBuilder.add(); - flowObjectiveService.next(deviceId, nextObj); - log.debug("createGroupFromPort: Submited next objective {} in device {} " - + "for port {}", nextId, deviceId, portNum); - - portNextObjStore.put(key, nextId); - } - - - public GroupKey getGroupKey(Object obj) { - return new DefaultGroupKey(kryo.build().serialize(obj)); - } - - /** - * Removes groups for the next objective ID given. - * - * @param objectiveId next objective ID to remove - * @return true if succeeds, false otherwise - */ - public boolean removeGroup(int objectiveId) { - - if (nsNextObjStore.containsValue(objectiveId)) { - NextObjective.Builder nextObjBuilder = DefaultNextObjective - .builder().withId(objectiveId) - .withType(NextObjective.Type.HASHED).fromApp(appId); - NextObjective nextObjective = nextObjBuilder. - remove(new SRNextObjectiveContext(deviceId)); - log.info("**removeGroup: Submited " - + "next objective {} in device {}", - objectiveId, deviceId); - flowObjectiveService.next(deviceId, nextObjective); - - for (Map.Entry<NeighborSetNextObjectiveStoreKey, Integer> entry: nsNextObjStore.entrySet()) { - if (entry.getValue().equals(objectiveId)) { - nsNextObjStore.remove(entry.getKey()); - break; - } - } - return true; - } - - return false; - } - - protected static class SRNextObjectiveContext implements ObjectiveContext { - final DeviceId deviceId; - - SRNextObjectiveContext(DeviceId deviceId) { - this.deviceId = deviceId; - } - @Override - public void onSuccess(Objective objective) { - log.info("Next objective {} operation successful in device {}", - objective.id(), deviceId); - } - - @Override - public void onError(Objective objective, ObjectiveError error) { - log.warn("Next objective {} operation failed with error: {} in device {}", - objective.id(), error, deviceId); - } - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java deleted file mode 100644 index 7a43e73d..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java +++ /dev/null @@ -1,200 +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.segmentrouting.grouphandler; - -import java.util.HashSet; -import java.util.Set; - -import org.onosproject.core.ApplicationId; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Link; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.link.LinkService; -import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; -import org.onosproject.segmentrouting.config.DeviceProperties; -import org.onosproject.store.service.EventuallyConsistentMap; - -/** - * Default ECMP group handler creation module for a transit device. - * This component creates a set of ECMP groups for every neighbor - * that this device is connected to. - * For example, consider a network of 4 devices: D0 (Segment ID: 100), - * D1 (Segment ID: 101), D2 (Segment ID: 102) and D3 (Segment ID: 103), - * where D0 and D3 are edge devices and D1 and D2 are transit devices. - * Assume transit device D1 is connected to 2 neighbors (D0 and D3 ). - * The following groups will be created in D1: - * 1) all ports to D0 + with no label push, - * 2) all ports to D3 + with no label push, - */ -public class DefaultTransitGroupHandler extends DefaultGroupHandler { - - protected DefaultTransitGroupHandler(DeviceId deviceId, - ApplicationId appId, - DeviceProperties config, - LinkService linkService, - FlowObjectiveService flowObjService, - EventuallyConsistentMap< - NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore, - EventuallyConsistentMap<SubnetNextObjectiveStoreKey, - Integer> subnetNextObjStore, - EventuallyConsistentMap<PortNextObjectiveStoreKey, - Integer> portNextObjStore) { - super(deviceId, appId, config, linkService, flowObjService, - nsNextObjStore, subnetNextObjStore, portNextObjStore); - } - - @Override - public void createGroups() { - Set<DeviceId> neighbors = devicePortMap.keySet(); - if (neighbors == null || neighbors.isEmpty()) { - return; - } - - // Create all possible Neighbor sets from this router - // NOTE: Avoid any pairings of edge routers only - Set<Set<DeviceId>> sets = getPowerSetOfNeighbors(neighbors); - sets = filterEdgeRouterOnlyPairings(sets); - log.debug("createGroupsAtTransitRouter: The size of neighbor powerset " - + "for sw {} is {}", deviceId, sets.size()); - Set<NeighborSet> nsSet = new HashSet<>(); - for (Set<DeviceId> combo : sets) { - if (combo.isEmpty()) { - continue; - } - NeighborSet ns = new NeighborSet(combo); - log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}", - deviceId, combo, ns); - nsSet.add(ns); - } - log.debug("createGroupsAtTransitRouter: The neighborset with label " - + "for sw {} is {}", deviceId, nsSet); - - //createGroupsFromNeighborsets(nsSet); - } - - @Override - protected void newNeighbor(Link newNeighborLink) { - log.debug("New Neighbor: Updating groups for " - + "transit device {}", deviceId); - // Recompute neighbor power set - addNeighborAtPort(newNeighborLink.dst().deviceId(), - newNeighborLink.src().port()); - // Compute new neighbor sets due to the addition of new neighbor - Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent( - newNeighborLink.dst().deviceId(), - devicePortMap.keySet()); - //createGroupsFromNeighborsets(nsSet); - } - - @Override - protected void newPortToExistingNeighbor(Link newNeighborLink) { - /*log.debug("New port to existing neighbor: Updating " - + "groups for transit device {}", deviceId); - addNeighborAtPort(newNeighborLink.dst().deviceId(), - newNeighborLink.src().port()); - Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent( - newNeighborLink.dst().deviceId(), - devicePortMap.keySet()); - for (NeighborSet ns : nsSet) { - // Create the new bucket to be updated - TrafficTreatment.Builder tBuilder = - DefaultTrafficTreatment.builder(); - tBuilder.setOutput(newNeighborLink.src().port()) - .setEthDst(deviceConfig.getDeviceMac( - newNeighborLink.dst().deviceId())) - .setEthSrc(nodeMacAddr); - if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { - tBuilder.pushMpls() - .setMpls(MplsLabel. - mplsLabel(ns.getEdgeLabel())); - } - - - Integer nextId = deviceNextObjectiveIds.get(ns); - if (nextId != null) { - NextObjective.Builder nextObjBuilder = DefaultNextObjective - .builder().withId(nextId) - .withType(NextObjective.Type.HASHED).fromApp(appId); - - nextObjBuilder.addTreatment(tBuilder.build()); - - NextObjective nextObjective = nextObjBuilder.add(); - flowObjectiveService.next(deviceId, nextObjective); - } - }*/ - } - - @Override - protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent( - DeviceId impactedNeighbor, - Set<DeviceId> updatedNeighbors) { - Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors); - - Set<DeviceId> tmp = new HashSet<>(); - tmp.addAll(updatedNeighbors); - tmp.remove(impactedNeighbor); - Set<Set<DeviceId>> tmpPowerSet = getPowerSetOfNeighbors(tmp); - - // Compute the impacted neighbor sets - powerSet.removeAll(tmpPowerSet); - - powerSet = filterEdgeRouterOnlyPairings(powerSet); - Set<NeighborSet> nsSet = new HashSet<>(); - for (Set<DeviceId> combo : powerSet) { - if (combo.isEmpty()) { - continue; - } - NeighborSet ns = new NeighborSet(combo); - log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}", - deviceId, combo, ns); - nsSet.add(ns); - } - log.debug("computeImpactedNeighborsetForPortEvent: The neighborset with label " - + "for sw {} is {}", deviceId, nsSet); - - return nsSet; - } - - private Set<Set<DeviceId>> filterEdgeRouterOnlyPairings(Set<Set<DeviceId>> sets) { - Set<Set<DeviceId>> fiteredSets = new HashSet<>(); - for (Set<DeviceId> deviceSubSet : sets) { - if (deviceSubSet.size() > 1) { - boolean avoidEdgeRouterPairing = true; - for (DeviceId device : deviceSubSet) { - boolean isEdge; - try { - isEdge = deviceConfig.isEdgeDevice(device); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() + " Skipping filterEdgeRouterOnlyPairings on this device."); - continue; - } - - if (!isEdge) { - avoidEdgeRouterPairing = false; - break; - } - } - if (!avoidEdgeRouterPairing) { - fiteredSets.add(deviceSubSet); - } - } else { - fiteredSets.add(deviceSubSet); - } - } - return fiteredSets; - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/GroupBucketIdentifier.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/GroupBucketIdentifier.java deleted file mode 100644 index 2ecb4493..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/GroupBucketIdentifier.java +++ /dev/null @@ -1,69 +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.segmentrouting.grouphandler; - -import static com.google.common.base.Preconditions.checkNotNull; - -import org.onosproject.net.PortNumber; - -/** - * Representation of policy group bucket identifier. Not exposed to - * the application and only to be used internally. - */ -public class GroupBucketIdentifier { - private int label; - private BucketOutputType type; - private PortNumber outPort; - private PolicyGroupIdentifier outGroup; - - protected enum BucketOutputType { - PORT, - GROUP - } - - protected GroupBucketIdentifier(int label, - PortNumber outPort) { - this.label = label; - this.type = BucketOutputType.PORT; - this.outPort = checkNotNull(outPort); - this.outGroup = null; - } - - protected GroupBucketIdentifier(int label, - PolicyGroupIdentifier outGroup) { - this.label = label; - this.type = BucketOutputType.GROUP; - this.outPort = null; - this.outGroup = checkNotNull(outGroup); - } - - protected int label() { - return this.label; - } - - protected BucketOutputType type() { - return this.type; - } - - protected PortNumber outPort() { - return this.outPort; - } - - protected PolicyGroupIdentifier outGroup() { - return this.outGroup; - } -} - diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/NeighborSet.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/NeighborSet.java deleted file mode 100644 index 44715d24..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/NeighborSet.java +++ /dev/null @@ -1,123 +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.segmentrouting.grouphandler; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -import org.onosproject.net.DeviceId; - -/** - * Representation of a set of neighbor switch dpids along with edge node - * label. Meant to be used as a lookup-key in a hash-map to retrieve an - * ECMP-group that hashes packets to a set of ports connecting to the - * neighbors in this set. - */ -public class NeighborSet { - private final Set<DeviceId> neighbors; - private final int edgeLabel; - public static final int NO_EDGE_LABEL = -1; - - /** - * Constructor with set of neighbors. Edge label is - * default to -1. - * - * @param neighbors set of neighbors to be part of neighbor set - */ - public NeighborSet(Set<DeviceId> neighbors) { - checkNotNull(neighbors); - this.edgeLabel = NO_EDGE_LABEL; - this.neighbors = new HashSet<>(); - this.neighbors.addAll(neighbors); - } - - /** - * Constructor with set of neighbors and edge label. - * - * @param neighbors set of neighbors to be part of neighbor set - * @param edgeLabel label to be pushed as part of group operation - */ - public NeighborSet(Set<DeviceId> neighbors, int edgeLabel) { - checkNotNull(neighbors); - this.edgeLabel = edgeLabel; - this.neighbors = new HashSet<>(); - this.neighbors.addAll(neighbors); - } - - /** - * Default constructor for kryo serialization. - */ - public NeighborSet() { - this.edgeLabel = NO_EDGE_LABEL; - this.neighbors = new HashSet<>(); - } - - /** - * Gets the neighbors part of neighbor set. - * - * @return set of neighbor identifiers - */ - public Set<DeviceId> getDeviceIds() { - return neighbors; - } - - /** - * Gets the label associated with neighbor set. - * - * @return integer - */ - public int getEdgeLabel() { - return edgeLabel; - } - - // The list of neighbor ids and label are used for comparison. - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof NeighborSet)) { - return false; - } - NeighborSet that = (NeighborSet) o; - return (this.neighbors.containsAll(that.neighbors) && - that.neighbors.containsAll(this.neighbors) && - (this.edgeLabel == that.edgeLabel)); - } - - // The list of neighbor ids and label are used for comparison. - @Override - public int hashCode() { - int result = 17; - int combinedHash = 0; - for (DeviceId d : neighbors) { - combinedHash = combinedHash + Objects.hash(d); - } - result = 31 * result + combinedHash + Objects.hash(edgeLabel); - - return result; - } - - @Override - public String toString() { - return " Neighborset Sw: " + neighbors - + " and Label: " + edgeLabel; - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/NeighborSetNextObjectiveStoreKey.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/NeighborSetNextObjectiveStoreKey.java deleted file mode 100644 index 9ace5313..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/NeighborSetNextObjectiveStoreKey.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.segmentrouting.grouphandler; - -import java.util.Objects; - -import org.onosproject.net.DeviceId; - -/** - * Class definition of Key for Neighborset to NextObjective store. - */ -public class NeighborSetNextObjectiveStoreKey { - private final DeviceId deviceId; - private final NeighborSet ns; - - public NeighborSetNextObjectiveStoreKey(DeviceId deviceId, - NeighborSet ns) { - this.deviceId = deviceId; - this.ns = ns; - } - - public DeviceId deviceId() { - return this.deviceId; - } - - public NeighborSet neighborSet() { - return this.ns; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof NeighborSetNextObjectiveStoreKey)) { - return false; - } - NeighborSetNextObjectiveStoreKey that = - (NeighborSetNextObjectiveStoreKey) o; - return (Objects.equals(this.deviceId, that.deviceId) && - Objects.equals(this.ns, that.ns)); - } - - // The list of neighbor ids and label are used for comparison. - @Override - public int hashCode() { - int result = 17; - result = 31 * result + Objects.hashCode(this.deviceId) - + Objects.hashCode(this.ns); - - return result; - } - - @Override - public String toString() { - return "Device: " + deviceId + " Neighborset: " + ns; - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java deleted file mode 100644 index ef143dc7..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java +++ /dev/null @@ -1,378 +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.segmentrouting.grouphandler; - -import static com.google.common.base.Preconditions.checkArgument; -import static org.slf4j.LoggerFactory.getLogger; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; - -import org.onlab.packet.MacAddress; -import org.onlab.packet.MplsLabel; -import org.onosproject.core.ApplicationId; -import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; -import org.onosproject.segmentrouting.config.DeviceProperties; -import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType; -import org.onosproject.store.service.EventuallyConsistentMap; -import org.onosproject.net.DeviceId; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.group.GroupBucket; -import org.onosproject.net.link.LinkService; -import org.slf4j.Logger; - -/** - * A module to create group chains based on the specified device - * ports and label stack to be applied on each port. - */ -public class PolicyGroupHandler extends DefaultGroupHandler { - - private final Logger log = getLogger(getClass()); - private HashMap<PolicyGroupIdentifier, PolicyGroupIdentifier> dependentGroups = new HashMap<>(); - - /** - * Policy group handler constructor. - * - * @param deviceId device identifier - * @param appId application identifier - * @param config interface to retrieve the device properties - * @param linkService link service object - * @param flowObjService flow objective service object - * @param nsNextObjStore NeighborSet next objective store map - * @param subnetNextObjStore subnet next objective store map - */ - public PolicyGroupHandler(DeviceId deviceId, - ApplicationId appId, - DeviceProperties config, - LinkService linkService, - FlowObjectiveService flowObjService, - EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore, - EventuallyConsistentMap<SubnetNextObjectiveStoreKey, - Integer> subnetNextObjStore, - EventuallyConsistentMap<PortNextObjectiveStoreKey, - Integer> portNextObjStore) { - super(deviceId, appId, config, linkService, flowObjService, - nsNextObjStore, subnetNextObjStore, portNextObjStore); - } - - public PolicyGroupIdentifier createPolicyGroupChain(String id, - List<PolicyGroupParams> params) { - List<GroupBucketIdentifier> bucketIds = new ArrayList<>(); - for (PolicyGroupParams param: params) { - List<PortNumber> ports = param.getPorts(); - if (ports == null) { - log.warn("createPolicyGroupChain in sw {} with wrong " - + "input parameters", deviceId); - return null; - } - - int labelStackSize = (param.getLabelStack() != null) ? - param.getLabelStack().size() : 0; - - if (labelStackSize > 1) { - for (PortNumber sp : ports) { - PolicyGroupIdentifier previousGroupkey = null; - DeviceId neighbor = portDeviceMap.get(sp); - for (int idx = 0; idx < param.getLabelStack().size(); idx++) { - int label = param.getLabelStack().get(idx); - if (idx == (labelStackSize - 1)) { - // Innermost Group - GroupBucketIdentifier bucketId = - new GroupBucketIdentifier(label, - previousGroupkey); - bucketIds.add(bucketId); - } else if (idx == 0) { - // Outermost Group - List<GroupBucket> outBuckets = new ArrayList<>(); - GroupBucketIdentifier bucketId = - new GroupBucketIdentifier(label, sp); - PolicyGroupIdentifier key = new - PolicyGroupIdentifier(id, - Collections.singletonList(param), - Collections.singletonList(bucketId)); - MacAddress neighborEthDst; - try { - neighborEthDst = deviceConfig.getDeviceMac(neighbor); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() - + " Skipping createPolicyGroupChain for this label."); - continue; - } - - TrafficTreatment.Builder tBuilder = - DefaultTrafficTreatment.builder(); - tBuilder.setOutput(sp) - .setEthDst(neighborEthDst) - .setEthSrc(nodeMacAddr) - .pushMpls() - .setMpls(MplsLabel.mplsLabel(label)); - /*outBuckets.add(DefaultGroupBucket. - createSelectGroupBucket(tBuilder.build())); - GroupDescription desc = new - DefaultGroupDescription(deviceId, - GroupDescription.Type.INDIRECT, - new GroupBuckets(outBuckets)); - //TODO: BoS*/ - previousGroupkey = key; - //groupService.addGroup(desc); - //TODO: Use nextObjective APIs here - } else { - // Intermediate Groups - GroupBucketIdentifier bucketId = - new GroupBucketIdentifier(label, - previousGroupkey); - PolicyGroupIdentifier key = new - PolicyGroupIdentifier(id, - Collections.singletonList(param), - Collections.singletonList(bucketId)); - // Add to group dependency list - dependentGroups.put(previousGroupkey, key); - previousGroupkey = key; - } - } - } - } else { - int label = -1; - if (labelStackSize == 1) { - label = param.getLabelStack().get(0); - } - for (PortNumber sp : ports) { - GroupBucketIdentifier bucketId = - new GroupBucketIdentifier(label, sp); - bucketIds.add(bucketId); - } - } - } - PolicyGroupIdentifier innermostGroupkey = null; - if (!bucketIds.isEmpty()) { - innermostGroupkey = new - PolicyGroupIdentifier(id, - params, - bucketIds); - // Add to group dependency list - boolean fullyResolved = true; - for (GroupBucketIdentifier bucketId:bucketIds) { - if (bucketId.type() == BucketOutputType.GROUP) { - dependentGroups.put(bucketId.outGroup(), - innermostGroupkey); - fullyResolved = false; - } - } - - if (fullyResolved) { - List<GroupBucket> outBuckets = new ArrayList<>(); - for (GroupBucketIdentifier bucketId : bucketIds) { - DeviceId neighbor = portDeviceMap. - get(bucketId.outPort()); - - MacAddress neighborEthDst; - try { - neighborEthDst = deviceConfig.getDeviceMac(neighbor); - } catch (DeviceConfigNotFoundException e) { - log.warn(e.getMessage() - + " Skipping createPolicyGroupChain for this bucketId."); - continue; - } - - TrafficTreatment.Builder tBuilder = - DefaultTrafficTreatment.builder(); - tBuilder.setOutput(bucketId.outPort()) - .setEthDst(neighborEthDst) - .setEthSrc(nodeMacAddr); - if (bucketId.label() != NeighborSet.NO_EDGE_LABEL) { - tBuilder.pushMpls() - .setMpls(MplsLabel.mplsLabel(bucketId.label())); - } - //TODO: BoS - /*outBuckets.add(DefaultGroupBucket. - createSelectGroupBucket(tBuilder.build()));*/ - } - /*GroupDescription desc = new - DefaultGroupDescription(deviceId, - GroupDescription.Type.SELECT, - new GroupBuckets(outBuckets)); - groupService.addGroup(desc);*/ - //TODO: Use nextObjective APIs here - } - } - return innermostGroupkey; - } - - //TODO: Use nextObjective APIs to handle the group chains - /*@Override - protected void handleGroupEvent(GroupEvent event) { - if (event.type() == GroupEvent.Type.GROUP_ADDED) { - if (dependentGroups.get(event.subject().appCookie()) != null) { - PolicyGroupIdentifier dependentGroupKey = dependentGroups.get(event.subject().appCookie()); - dependentGroups.remove(event.subject().appCookie()); - boolean fullyResolved = true; - for (GroupBucketIdentifier bucketId: - dependentGroupKey.bucketIds()) { - if (bucketId.type() != BucketOutputType.GROUP) { - continue; - } - if (dependentGroups.containsKey(bucketId.outGroup())) { - fullyResolved = false; - break; - } - } - - if (fullyResolved) { - List<GroupBucket> outBuckets = new ArrayList<GroupBucket>(); - for (GroupBucketIdentifier bucketId: - dependentGroupKey.bucketIds()) { - TrafficTreatment.Builder tBuilder = - DefaultTrafficTreatment.builder(); - if (bucketId.label() != NeighborSet.NO_EDGE_LABEL) { - tBuilder.pushMpls() - .setMpls(MplsLabel. - mplsLabel(bucketId.label())); - } - //TODO: BoS - if (bucketId.type() == BucketOutputType.PORT) { - DeviceId neighbor = portDeviceMap. - get(bucketId.outPort()); - tBuilder.setOutput(bucketId.outPort()) - .setEthDst(deviceConfig. - getDeviceMac(neighbor)) - .setEthSrc(nodeMacAddr); - } else { - if (groupService. - getGroup(deviceId, - getGroupKey(bucketId. - outGroup())) == null) { - throw new IllegalStateException(); - } - GroupId indirectGroupId = groupService. - getGroup(deviceId, - getGroupKey(bucketId. - outGroup())).id(); - tBuilder.group(indirectGroupId); - } - outBuckets.add(DefaultGroupBucket. - createSelectGroupBucket(tBuilder.build())); - } - GroupDescription desc = new - DefaultGroupDescription(deviceId, - GroupDescription.Type.SELECT, - new GroupBuckets(outBuckets)); - groupService.addGroup(desc); - } - } - } - }*/ - - public PolicyGroupIdentifier generatePolicyGroupKey(String id, - List<PolicyGroupParams> params) { - List<GroupBucketIdentifier> bucketIds = new ArrayList<>(); - for (PolicyGroupParams param: params) { - List<PortNumber> ports = param.getPorts(); - if (ports == null) { - log.warn("generateGroupKey in sw {} with wrong " - + "input parameters", deviceId); - return null; - } - - int labelStackSize = (param.getLabelStack() != null) - ? param.getLabelStack().size() : 0; - - if (labelStackSize > 1) { - for (PortNumber sp : ports) { - PolicyGroupIdentifier previousGroupkey = null; - for (int idx = 0; idx < param.getLabelStack().size(); idx++) { - int label = param.getLabelStack().get(idx); - if (idx == (labelStackSize - 1)) { - // Innermost Group - GroupBucketIdentifier bucketId = - new GroupBucketIdentifier(label, - previousGroupkey); - bucketIds.add(bucketId); - } else if (idx == 0) { - // Outermost Group - GroupBucketIdentifier bucketId = - new GroupBucketIdentifier(label, sp); - PolicyGroupIdentifier key = new - PolicyGroupIdentifier(id, - Collections.singletonList(param), - Collections.singletonList(bucketId)); - previousGroupkey = key; - } else { - // Intermediate Groups - GroupBucketIdentifier bucketId = - new GroupBucketIdentifier(label, - previousGroupkey); - PolicyGroupIdentifier key = new - PolicyGroupIdentifier(id, - Collections.singletonList(param), - Collections.singletonList(bucketId)); - previousGroupkey = key; - } - } - } - } else { - int label = -1; - if (labelStackSize == 1) { - label = param.getLabelStack().get(0); - } - for (PortNumber sp : ports) { - GroupBucketIdentifier bucketId = - new GroupBucketIdentifier(label, sp); - bucketIds.add(bucketId); - } - } - } - PolicyGroupIdentifier innermostGroupkey = null; - if (!bucketIds.isEmpty()) { - innermostGroupkey = new - PolicyGroupIdentifier(id, - params, - bucketIds); - } - return innermostGroupkey; - } - - public void removeGroupChain(PolicyGroupIdentifier key) { - checkArgument(key != null); - List<PolicyGroupIdentifier> groupsToBeDeleted = new ArrayList<>(); - groupsToBeDeleted.add(key); - - Iterator<PolicyGroupIdentifier> it = - groupsToBeDeleted.iterator(); - - while (it.hasNext()) { - PolicyGroupIdentifier innerMostGroupKey = it.next(); - for (GroupBucketIdentifier bucketId: - innerMostGroupKey.bucketIds()) { - if (bucketId.type() != BucketOutputType.GROUP) { - groupsToBeDeleted.add(bucketId.outGroup()); - } - } - /*groupService.removeGroup(deviceId, - getGroupKey(innerMostGroupKey), - appId);*/ - //TODO: Use nextObjective APIs here - it.remove(); - } - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupIdentifier.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupIdentifier.java deleted file mode 100644 index 44a0a2ce..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupIdentifier.java +++ /dev/null @@ -1,90 +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.segmentrouting.grouphandler; - -import java.util.List; - -/** - * Representation of policy based group identifiers. - * Opaque to group handler applications and only the outermost - * policy group identifier in a chain is visible to the applications. - */ -public class PolicyGroupIdentifier { - private String id; - private List<PolicyGroupParams> inputParams; - private List<GroupBucketIdentifier> bucketIds; - - /** - * Constructor. - * - * @param id unique identifier associated with the policy group - * @param input policy group params associated with this group - * @param bucketIds buckets associated with this group - */ - protected PolicyGroupIdentifier(String id, - List<PolicyGroupParams> input, - List<GroupBucketIdentifier> bucketIds) { - this.id = id; - this.inputParams = input; - this.bucketIds = bucketIds; - } - - /** - * Returns the bucket identifier list associated with the policy - * group identifier. - * - * @return list of bucket identifier - */ - protected List<GroupBucketIdentifier> bucketIds() { - return this.bucketIds; - } - - @Override - public int hashCode() { - int result = 17; - int combinedHash = 0; - for (PolicyGroupParams input:inputParams) { - combinedHash = combinedHash + input.hashCode(); - } - for (GroupBucketIdentifier bucketId:bucketIds) { - combinedHash = combinedHash + bucketId.hashCode(); - } - result = 31 * result + combinedHash; - - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj instanceof PolicyGroupIdentifier) { - PolicyGroupIdentifier that = (PolicyGroupIdentifier) obj; - boolean result = this.id.equals(that.id); - result = result && - this.inputParams.containsAll(that.inputParams) && - that.inputParams.containsAll(this.inputParams); - result = result && - this.bucketIds.containsAll(that.bucketIds) && - that.bucketIds.containsAll(this.bucketIds); - return result; - } - - return false; - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupParams.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupParams.java deleted file mode 100644 index 5a3f26b5..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupParams.java +++ /dev/null @@ -1,92 +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.segmentrouting.grouphandler; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.List; -import java.util.Objects; - -import org.onosproject.net.PortNumber; - -/** - * Representation of parameters used to create policy based groups. - */ -public class PolicyGroupParams { - private final List<PortNumber> ports; - private final List<Integer> labelStack; - - /** - * Constructor. - * - * @param labelStack mpls label stack to be applied on the ports - * @param ports ports to be part of the policy group - */ - public PolicyGroupParams(List<Integer> labelStack, - List<PortNumber> ports) { - this.ports = checkNotNull(ports); - this.labelStack = checkNotNull(labelStack); - } - - /** - * Returns the ports associated with the policy group params. - * - * @return list of port numbers - */ - public List<PortNumber> getPorts() { - return ports; - } - - /** - * Returns the label stack associated with the policy group params. - * - * @return list of integers - */ - public List<Integer> getLabelStack() { - return labelStack; - } - - @Override - public int hashCode() { - int result = 17; - int combinedHash = 0; - for (PortNumber port:ports) { - combinedHash = combinedHash + port.hashCode(); - } - combinedHash = combinedHash + Objects.hash(labelStack); - result = 31 * result + combinedHash; - - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj instanceof PolicyGroupParams) { - PolicyGroupParams that = (PolicyGroupParams) obj; - boolean result = this.labelStack.equals(that.labelStack); - result = result && - this.ports.containsAll(that.ports) && - that.ports.containsAll(this.ports); - return result; - } - - return false; - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PortNextObjectiveStoreKey.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PortNextObjectiveStoreKey.java deleted file mode 100644 index 5555565c..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PortNextObjectiveStoreKey.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.onosproject.segmentrouting.grouphandler; - -import org.onosproject.net.DeviceId; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.TrafficTreatment; - -import java.util.Objects; - -/** - * Class definition of Key for Device/Port to NextObjective store. Since there - * can be multiple next objectives to the same physical port, we differentiate - * between them by including the treatment in the key. - */ -public class PortNextObjectiveStoreKey { - private final DeviceId deviceId; - private final PortNumber portNum; - private final TrafficTreatment treatment; - - public PortNextObjectiveStoreKey(DeviceId deviceId, PortNumber portNum, - TrafficTreatment treatment) { - this.deviceId = deviceId; - this.portNum = portNum; - this.treatment = treatment; - } - - /** - * Gets device id in this PortNextObjectiveStoreKey. - * - * @return device id - */ - public DeviceId deviceId() { - return deviceId; - } - - /** - * Gets port information in this PortNextObjectiveStoreKey. - * - * @return port information - */ - public PortNumber portNumber() { - return portNum; - } - - /** - * Gets treatment information in this PortNextObjectiveStoreKey. - * - * @return treatment information - */ - public TrafficTreatment treatment() { - return treatment; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof PortNextObjectiveStoreKey)) { - return false; - } - PortNextObjectiveStoreKey that = - (PortNextObjectiveStoreKey) o; - return (Objects.equals(this.deviceId, that.deviceId) && - Objects.equals(this.portNum, that.portNum) && - Objects.equals(this.treatment, that.treatment)); - } - - @Override - public int hashCode() { - return Objects.hash(deviceId, portNum, treatment); - } - - @Override - public String toString() { - return "Device: " + deviceId + " Port: " + portNum + " Treatment: " + treatment; - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/SubnetNextObjectiveStoreKey.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/SubnetNextObjectiveStoreKey.java deleted file mode 100644 index d6b16c7a..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/SubnetNextObjectiveStoreKey.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2014-2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.segmentrouting.grouphandler; - -import org.onlab.packet.IpPrefix; -import org.onosproject.net.DeviceId; - -import java.util.Objects; - -/** - * Class definition of Key for Subnet to NextObjective store. - */ -public class SubnetNextObjectiveStoreKey { - private final DeviceId deviceId; - private final IpPrefix prefix; - - public SubnetNextObjectiveStoreKey(DeviceId deviceId, - IpPrefix prefix) { - this.deviceId = deviceId; - this.prefix = prefix; - } - - /** - * Gets device id in this SubnetNextObjectiveStoreKey. - * - * @return device id - */ - public DeviceId deviceId() { - return this.deviceId; - } - - /** - * Gets subnet information in this SubnetNextObjectiveStoreKey. - * - * @return subnet information - */ - public IpPrefix prefix() { - return this.prefix; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof SubnetNextObjectiveStoreKey)) { - return false; - } - SubnetNextObjectiveStoreKey that = - (SubnetNextObjectiveStoreKey) o; - return (Objects.equals(this.deviceId, that.deviceId) && - Objects.equals(this.prefix, that.prefix)); - } - - @Override - public int hashCode() { - return Objects.hash(deviceId, prefix); - } - - @Override - public String toString() { - return "Device: " + deviceId + " Subnet: " + prefix; - } -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/package-info.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/package-info.java deleted file mode 100644 index 1a8d595e..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/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. - */ - -/** - * Segment routing group handling. - */ -package org.onosproject.segmentrouting.grouphandler;
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/package-info.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/package-info.java deleted file mode 100644 index 7b81db8a..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/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. - */ - -/** - * Segment routing application components. - */ -package org.onosproject.segmentrouting;
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/PolicyCodec.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/PolicyCodec.java deleted file mode 100644 index 8e508872..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/PolicyCodec.java +++ /dev/null @@ -1,122 +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.segmentrouting.web; - -import org.onosproject.codec.CodecContext; -import org.onosproject.codec.JsonCodec; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.onosproject.segmentrouting.Policy; -import org.onosproject.segmentrouting.TunnelPolicy; - -public final class PolicyCodec extends JsonCodec<Policy> { - - // JSON field names - private static final String POLICY_ID = "policy_id"; - private static final String PRIORITY = "priority"; - private static final String TYPE = "policy_type"; - private static final String TUNNEL_ID = "tunnel_id"; - private static final String DST_IP = "dst_ip"; - private static final String SRC_IP = "src_ip"; - private static final String PROTO_TYPE = "proto_type"; - private static final String SRC_PORT = "src_tp_port"; - private static final String DST_PORT = "dst_tp_port"; - - @Override - public ObjectNode encode(Policy policy, CodecContext context) { - final ObjectNode result = context.mapper().createObjectNode() - .put(POLICY_ID, policy.id()); - - result.put(PRIORITY, policy.priority()); - result.put(TYPE, policy.type().toString()); - - if (policy.dstIp() != null) { - result.put(DST_IP, policy.dstIp()); - } - if (policy.srcIp() != null) { - result.put(SRC_IP, policy.srcIp()); - } - if (policy.ipProto() != null) { - result.put(PROTO_TYPE, policy.ipProto()); - } - - int srcPort = policy.srcPort() & 0xffff; - if (policy.srcPort() != 0) { - result.put(SRC_PORT, srcPort); - } - int dstPort = policy.dstPort() & 0xffff; - if (policy.dstPort() != 0) { - result.put(DST_PORT, dstPort); - } - if (policy.type() == Policy.Type.TUNNEL_FLOW) { - result.put(TUNNEL_ID, ((TunnelPolicy) policy).tunnelId()); - } - - return result; - } - - @Override - public Policy decode(ObjectNode json, CodecContext context) { - - String pid = json.path(POLICY_ID).asText(); - String type = json.path(TYPE).asText(); - int priority = json.path(PRIORITY).asInt(); - String dstIp = json.path(DST_IP).asText(); - String srcIp = json.path(SRC_IP).asText(); - String tunnelId = json.path(TUNNEL_ID).asText(); - String protoType = json.path(PROTO_TYPE).asText(); - short srcPort = json.path(SRC_PORT).shortValue(); - short dstPort = json.path(DST_PORT).shortValue(); - - if (json.path(POLICY_ID).isMissingNode() || pid == null) { - // TODO: handle errors - return null; - } - - TunnelPolicy.Builder tpb = TunnelPolicy.builder().setPolicyId(pid); - if (!json.path(TYPE).isMissingNode() && type != null && - Policy.Type.valueOf(type).equals(Policy.Type.TUNNEL_FLOW)) { - - if (json.path(TUNNEL_ID).isMissingNode() || tunnelId == null) { - return null; - } - - tpb.setTunnelId(tunnelId); - tpb.setType(Policy.Type.valueOf(type)); - - if (!json.path(PRIORITY).isMissingNode()) { - tpb.setPriority(priority); - } - if (dstIp != null) { - tpb.setDstIp(dstIp); - } - if (srcIp != null) { - tpb.setSrcIp(srcIp); - } - if (protoType != null) { - tpb.setIpProto(protoType); - } - if (dstPort != 0) { - tpb.setDstPort(dstPort); - } - if (srcPort != 0) { - tpb.setSrcPort(srcPort); - } - } - - return tpb.build(); - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/PolicyWebResource.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/PolicyWebResource.java deleted file mode 100644 index cdc53a02..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/PolicyWebResource.java +++ /dev/null @@ -1,108 +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.segmentrouting.web; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import org.onosproject.rest.AbstractWebResource; -import org.onosproject.segmentrouting.Policy; -import org.onosproject.segmentrouting.SegmentRoutingService; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -/** - * Query, create and remove segment routing plicies. - */ -@Path("policy") -public class PolicyWebResource extends AbstractWebResource { - - private static final PolicyCodec POLICY_CODEC = new PolicyCodec(); - - /** - * Get all segment routing policies. - * Returns an array of segment routing policies. - * - * @return status of OK - */ - @GET - @Produces(MediaType.APPLICATION_JSON) - public Response getPolicy() { - SegmentRoutingService srService = get(SegmentRoutingService.class); - List<Policy> policies = srService.getPolicies(); - ObjectNode result = new ObjectMapper().createObjectNode(); - result.set("policy", new PolicyCodec().encode(policies, this)); - - return ok(result.toString()).build(); - } - - /** - * Create a new segment routing policy. - * - * @param input JSON stream for policy to create - * @return status of the request - OK if the policy is created, - * INTERNAL_SERVER_ERROR if the JSON is invalid or the policy cannot be created - * @throws IOException if JSON processing fails - */ - @POST - @Consumes(MediaType.APPLICATION_JSON) - public Response createPolicy(InputStream input) throws IOException { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode policyJson = (ObjectNode) mapper.readTree(input); - SegmentRoutingService srService = get(SegmentRoutingService.class); - Policy policyInfo = POLICY_CODEC.decode(policyJson, this); - - if (policyInfo.type() == Policy.Type.TUNNEL_FLOW) { - srService.createPolicy(policyInfo); - return Response.ok().build(); - } else { - return Response.serverError().build(); - } - } - - /** - * Delete a segment routing policy. - * - * @param input JSON stream for policy to delete - * @return status of the request - OK if the policy is removed, - * INTERNAL_SERVER_ERROR otherwise - * @throws IOException if JSON is invalid - */ - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - public Response removePolicy(InputStream input) throws IOException { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode policyJson = (ObjectNode) mapper.readTree(input); - SegmentRoutingService srService = get(SegmentRoutingService.class); - Policy policyInfo = POLICY_CODEC.decode(policyJson, this); - // TODO: Check the result - srService.removePolicy(policyInfo); - - return Response.ok().build(); - - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/TunnelCodec.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/TunnelCodec.java deleted file mode 100644 index 2f85afd5..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/TunnelCodec.java +++ /dev/null @@ -1,66 +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.segmentrouting.web; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import org.onosproject.codec.CodecContext; -import org.onosproject.codec.JsonCodec; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.onosproject.segmentrouting.DefaultTunnel; -import org.onosproject.segmentrouting.Tunnel; - -import java.util.ArrayList; -import java.util.List; - -public final class TunnelCodec extends JsonCodec<Tunnel> { - - // JSON field names - private static final String TUNNEL_ID = "tunnel_id"; - private static final String GROUP_ID = "group_id"; - private static final String LABEL_PATH = "label_path"; - - @Override - public ObjectNode encode(Tunnel tunnel, CodecContext context) { - final ObjectNode result = context.mapper().createObjectNode() - .put(TUNNEL_ID, tunnel.id()); - - result.put(GROUP_ID, tunnel.groupId()); - - final ArrayNode jsonLabelIds = result.putArray(LABEL_PATH); - - tunnel.labelIds().forEach(label -> jsonLabelIds.add(label.intValue())); - - return result; - } - - @Override - public DefaultTunnel decode(ObjectNode json, CodecContext context) { - - String tid = json.path(TUNNEL_ID).asText(); - List<Integer> labels = new ArrayList<>(); - - if (!json.path(LABEL_PATH).isMissingNode()) { - ArrayNode labelArray = (ArrayNode) json.path(LABEL_PATH); - for (JsonNode o : labelArray) { - labels.add(o.asInt()); - } - } - - return new DefaultTunnel(tid, labels); - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/TunnelWebResource.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/TunnelWebResource.java deleted file mode 100644 index fb30308a..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/TunnelWebResource.java +++ /dev/null @@ -1,102 +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.segmentrouting.web; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import org.onosproject.rest.AbstractWebResource; -import org.onosproject.segmentrouting.SegmentRoutingService; -import org.onosproject.segmentrouting.Tunnel; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -/** - * Query, create and remove segment routing tunnels. - */ -@Path("tunnel") -public class TunnelWebResource extends AbstractWebResource { - - private static final TunnelCodec TUNNEL_CODEC = new TunnelCodec(); - - /** - * Get all segment routing tunnels. - * Returns an array of segment routing tunnels. - * - * @return status of OK - */ - @GET - @Produces(MediaType.APPLICATION_JSON) - public Response getTunnel() { - SegmentRoutingService srService = get(SegmentRoutingService.class); - List<Tunnel> tunnels = srService.getTunnels(); - ObjectNode result = new ObjectMapper().createObjectNode(); - result.set("tunnel", new TunnelCodec().encode(tunnels, this)); - - return ok(result.toString()).build(); - } - - /** - * Create a new segment routing tunnel. - * - * @param input JSON stream for tunnel to create - * @return status of the request - OK if the tunnel is created, - * INTERNAL_SERVER_ERROR if the JSON is invalid or the tunnel cannot be created - * @throws IOException if the JSON is invalid - */ - @POST - @Consumes(MediaType.APPLICATION_JSON) - public Response createTunnel(InputStream input) throws IOException { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode tunnelJson = (ObjectNode) mapper.readTree(input); - SegmentRoutingService srService = get(SegmentRoutingService.class); - Tunnel tunnelInfo = TUNNEL_CODEC.decode(tunnelJson, this); - srService.createTunnel(tunnelInfo); - - return Response.ok().build(); - } - - /** - * Delete a segment routing tunnel. - * - * @param input JSON stream for tunnel to delete - * @return status of the request - OK if the tunnel is removed, - * INTERNAL_SERVER_ERROR otherwise - * @throws IOException if JSON is invalid - */ - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - public Response removeTunnel(InputStream input) throws IOException { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode tunnelJson = (ObjectNode) mapper.readTree(input); - SegmentRoutingService srService = get(SegmentRoutingService.class); - Tunnel tunnelInfo = TUNNEL_CODEC.decode(tunnelJson, this); - srService.removeTunnel(tunnelInfo); - - return Response.ok().build(); - } - -} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/package-info.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/package-info.java deleted file mode 100644 index 85c63de5..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/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. - */ - -/** - * Set of resources implementing the segment routing application REST API. - */ -package org.onosproject.segmentrouting.web;
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/apps/segmentrouting/src/main/resources/OSGI-INF/blueprint/shell-config.xml deleted file mode 100644 index 3e47bf8f..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/resources/OSGI-INF/blueprint/shell-config.xml +++ /dev/null @@ -1,40 +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. - --> -<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> - - <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> - <command> - <action class="org.onosproject.segmentrouting.cli.TunnelListCommand"/> - </command> - <command> - <action class="org.onosproject.segmentrouting.cli.PolicyListCommand"/> - </command> - <command> - <action class="org.onosproject.segmentrouting.cli.PolicyAddCommand"/> - </command> - <command> - <action class="org.onosproject.segmentrouting.cli.PolicyRemoveCommand"/> - </command> - <command> - <action class="org.onosproject.segmentrouting.cli.TunnelAddCommand"/> - </command> - <command> - <action class="org.onosproject.segmentrouting.cli.TunnelRemoveCommand"/> - </command> - </command-bundle> -</blueprint> - - diff --git a/framework/src/onos/apps/segmentrouting/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/segmentrouting/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 94c0d7de..00000000 --- a/framework/src/onos/apps/segmentrouting/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ Copyright 2015 Open Networking Laboratory - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - --> -<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" - xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" - xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" - id="ONOS" version="2.5"> - <display-name>Segment Routing REST API v1.0</display-name> - - <servlet> - <servlet-name>JAX-RS Service</servlet-name> - <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> - <init-param> - <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name> - <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value> - </init-param> - <init-param> - <param-name>com.sun.jersey.config.property.classnames</param-name> - <param-value> - org.onosproject.segmentrouting.web.TunnelWebResource, - org.onosproject.segmentrouting.web.PolicyWebResource - </param-value> - </init-param> - <load-on-startup>1</load-on-startup> - </servlet> - - <servlet-mapping> - <servlet-name>JAX-RS Service</servlet-name> - <url-pattern>/*</url-pattern> - </servlet-mapping> -</web-app> diff --git a/framework/src/onos/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingConfigTest.java b/framework/src/onos/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingConfigTest.java deleted file mode 100644 index 3e5daa5b..00000000 --- a/framework/src/onos/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingConfigTest.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2014-2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.segmentrouting.config; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Before; -import org.junit.Test; -import org.onlab.packet.IpAddress; -import org.onlab.packet.MacAddress; -import org.onosproject.net.DeviceId; -import org.onosproject.net.config.Config; -import org.onosproject.net.config.ConfigApplyDelegate; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static org.junit.Assert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertTrue; - -/** - * Tests for class {@link SegmentRoutingConfig}. - */ -public class SegmentRoutingConfigTest { - private SegmentRoutingConfig config; - private Map<Integer, Set<Integer>> adjacencySids1; - private Map<Integer, Set<Integer>> adjacencySids2; - - @Before - public void setUp() throws Exception { - String jsonString = "{" + - "\"name\" : \"Leaf-R1\"," + - "\"nodeSid\" : 101," + - "\"routerIp\" : \"10.0.1.254\"," + - "\"routerMac\" : \"00:00:00:00:01:80\"," + - "\"isEdgeRouter\" : true," + - "\"adjacencySids\" : [" + - " { \"adjSid\" : 100, \"ports\" : [2, 3] }," + - " { \"adjSid\" : 200, \"ports\" : [4, 5] }" + - "]}"; - - adjacencySids1 = new HashMap<>(); - Set<Integer> ports1 = new HashSet<>(); - ports1.add(2); - ports1.add(3); - adjacencySids1.put(100, ports1); - Set<Integer> ports2 = new HashSet<>(); - ports2.add(4); - ports2.add(5); - adjacencySids1.put(200, ports2); - - adjacencySids2 = new HashMap<>(); - Set<Integer> ports3 = new HashSet<>(); - ports3.add(6); - adjacencySids2.put(300, ports3); - - DeviceId subject = DeviceId.deviceId("of:0000000000000001"); - String key = "org.onosproject.segmentrouting"; - ObjectMapper mapper = new ObjectMapper(); - JsonNode jsonNode = mapper.readTree(jsonString); - ConfigApplyDelegate delegate = new MockDelegate(); - - config = new SegmentRoutingConfig(); - config.init(subject, key, jsonNode, mapper, delegate); - } - - @Test - public void testName() throws Exception { - assertTrue(config.name().isPresent()); - assertThat(config.name().get(), is("Leaf-R1")); - } - - @Test - public void testSetName() throws Exception { - config.setName("Spine-R1"); - assertTrue(config.name().isPresent()); - assertThat(config.name().get(), is("Spine-R1")); - } - - @Test - public void testRouterIp() throws Exception { - assertThat(config.routerIp(), is(IpAddress.valueOf("10.0.1.254"))); - } - - @Test - public void testSetRouterIp() throws Exception { - config.setRouterIp("10.0.2.254"); - assertThat(config.routerIp(), is(IpAddress.valueOf("10.0.2.254"))); - } - - @Test - public void testRouterMac() throws Exception { - assertThat(config.routerMac(), is(MacAddress.valueOf("00:00:00:00:01:80"))); - } - - @Test - public void testSetRouterMac() throws Exception { - config.setRouterMac("00:00:00:00:02:80"); - assertThat(config.routerMac(), is(MacAddress.valueOf("00:00:00:00:02:80"))); - } - - @Test - public void testNodeSid() throws Exception { - assertThat(config.nodeSid(), is(101)); - } - - @Test - public void testSetNodeSid() throws Exception { - config.setNodeSid(200); - assertThat(config.nodeSid(), is(200)); - } - - @Test - public void testIsEdgeRouter() throws Exception { - assertThat(config.isEdgeRouter(), is(true)); - } - - @Test - public void testSetIsEdgeRouter() throws Exception { - config.setIsEdgeRouter(false); - assertThat(config.isEdgeRouter(), is(false)); - } - - @Test - public void testAdjacencySids() throws Exception { - assertThat(config.adjacencySids(), is(adjacencySids1)); - } - - @Test - public void testSetAdjacencySids() throws Exception { - config.setAdjacencySids(adjacencySids2); - assertThat(config.adjacencySids(), is(adjacencySids2)); - } - - private class MockDelegate implements ConfigApplyDelegate { - @Override - public void onApply(Config config) { - } - } -}
\ No newline at end of file |