[ONOS] Cherry picked from master 1.7
Change-Id: I74a0c1634f9c425af2bcb646edc3d9170b3c087c
diff --git a/apps/pce/app/pom.xml b/apps/pce/app/pom.xml
index 1f5d837..a20469b 100644
--- a/apps/pce/app/pom.xml
+++ b/apps/pce/app/pom.xml
@@ -22,6 +22,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-pce</artifactId>
<version>1.6.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-pce</artifactId>
<packaging>bundle</packaging>
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
index 904371d..89a685b 100644
--- a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceManager.java
@@ -26,6 +26,12 @@
import java.util.Optional;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -35,6 +41,7 @@
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
+import org.onlab.packet.TCP;
import org.onlab.util.Bandwidth;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
@@ -52,6 +59,7 @@
import org.onosproject.incubator.net.tunnel.TunnelListener;
import org.onosproject.incubator.net.tunnel.TunnelName;
import org.onosproject.incubator.net.tunnel.TunnelService;
+import org.onosproject.mastership.MastershipService;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultAnnotations.Builder;
import org.onosproject.net.Device;
@@ -63,6 +71,7 @@
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
+import org.onosproject.net.link.LinkEvent;
import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
import org.onosproject.pce.pceservice.constraint.CapabilityConstraint.CapabilityType;
import org.onosproject.pce.pceservice.constraint.CostConstraint;
@@ -76,6 +85,9 @@
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathService;
import org.onosproject.net.topology.TopologyEdge;
+import org.onosproject.net.topology.TopologyEvent;
+import org.onosproject.net.topology.TopologyListener;
+import org.onosproject.net.topology.TopologyService;
import org.onosproject.pce.pceservice.api.PceService;
import org.onosproject.pce.pcestore.PcePathInfo;
import org.onosproject.pce.pcestore.PceccTunnelInfo;
@@ -131,6 +143,7 @@
private static final String TRUE = "true";
private static final String FALSE = "false";
private static final String END_OF_SYNC_IP_PREFIX = "0.0.0.0/32";
+ public static final int PCEP_PORT = 4189;
private IdGenerator localLspIdIdGen;
protected DistributedSet<Short> localLspIdFreeList;
@@ -171,12 +184,23 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowObjectiveService flowObjectiveService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MastershipService mastershipService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected TopologyService topologyService;
+
private TunnelListener listener = new InnerTunnelListener();
private BasicPceccHandler crHandler;
private PceccSrTeBeHandler srTeHandler;
private ApplicationId appId;
private final PcepPacketProcessor processor = new PcepPacketProcessor();
+ private final TopologyListener topologyListener = new InternalTopologyListener();
+ private ScheduledExecutorService executor;
+
+ public static final int INITIAL_DELAY = 30;
+ public static final int PERIODIC_DELAY = 30;
/**
* Creates new instance of PceManager.
@@ -204,6 +228,10 @@
.asDistributedSet();
packetService.addProcessor(processor, PacketProcessor.director(4));
+ topologyService.addListener(topologyListener);
+ executor = Executors.newSingleThreadScheduledExecutor();
+ //Start a timer when the component is up, with initial delay of 30min and periodic delays at 30min
+ executor.scheduleAtFixedRate(new GlobalOptimizationTimer(), INITIAL_DELAY, PERIODIC_DELAY, TimeUnit.MINUTES);
log.info("Started");
}
@@ -211,6 +239,9 @@
protected void deactivate() {
tunnelService.removeListener(listener);
packetService.removeProcessor(processor);
+ topologyService.removeListener(topologyListener);
+ //Shutdown the thread when component is deactivated
+ executor.shutdown();
log.info("Stopped");
}
@@ -395,6 +426,7 @@
List<Link> links = tunnel.path().links();
String lspSigType = tunnel.annotations().value(LSP_SIG_TYPE);
double bwConstraintValue = 0;
+ String costType = null;
SharedBandwidthConstraint shBwConstraint = null;
BandwidthConstraint bwConstraint = null;
CostConstraint costConstraint = null;
@@ -409,6 +441,7 @@
bwConstraintValue = bwConstraint.bandwidth().bps();
} else if (constraint instanceof CostConstraint) {
costConstraint = (CostConstraint) constraint;
+ costType = costConstraint.type().name();
}
}
@@ -454,6 +487,9 @@
Builder annotationBuilder = DefaultAnnotations.builder();
annotationBuilder.set(BANDWIDTH, String.valueOf(bwConstraintValue));
+ if (costType != null) {
+ annotationBuilder.set(COST_TYPE, costType);
+ }
annotationBuilder.set(LSP_SIG_TYPE, lspSigType);
annotationBuilder.set(PCE_INIT, TRUE);
annotationBuilder.set(DELEGATE, TRUE);
@@ -594,8 +630,66 @@
}
}
+ //TODO: annotations used for temporarily later projection/network config will be used
+ private class InternalTopologyListener implements TopologyListener {
+ @Override
+ public void event(TopologyEvent event) {
+ event.reasons().forEach(e -> {
+ //If event type is link removed, get the impacted tunnel
+ if (e instanceof LinkEvent) {
+ LinkEvent linkEvent = (LinkEvent) e;
+ if (linkEvent.type() == LinkEvent.Type.LINK_REMOVED) {
+ tunnelService.queryTunnel(MPLS).forEach(t -> {
+ if (t.path().links().contains((e.subject()))) {
+ // Check whether this ONOS instance is master for ingress device if yes,
+ // recompute and send update
+ checkForMasterAndUpdateTunnel(t.path().src().deviceId(), t);
+ }
+ });
+ }
+ }
+ });
+ }
+ }
- // Allocates the bandwidth locally for PCECC tunnels.
+ private boolean checkForMasterAndUpdateTunnel(DeviceId src, Tunnel tunnel) {
+ /**
+ * Master of ingress node will recompute and also delegation flag must be set.
+ */
+ if (mastershipService.isLocalMaster(src)
+ && Boolean.valueOf(tunnel.annotations().value(DELEGATE)) != null) {
+ LinkedList<Constraint> constraintList = new LinkedList<>();
+
+ if (tunnel.annotations().value(BANDWIDTH) != null) {
+ //Requested bandwidth will be same as previous allocated bandwidth for the tunnel
+ BandwidthConstraint localConst = new BandwidthConstraint(Bandwidth.bps(Double.parseDouble(tunnel
+ .annotations().value(BANDWIDTH))));
+ constraintList.add(localConst);
+ }
+ if (tunnel.annotations().value(COST_TYPE) != null) {
+ constraintList.add(CostConstraint.of(CostConstraint.Type.valueOf(tunnel.annotations().value(
+ COST_TYPE))));
+ }
+
+ /*
+ * If tunnel was UP after recomputation failed then store failed path in PCE store send PCIntiate(remove)
+ * and If tunnel is failed and computation fails nothing to do because tunnel status will be same[Failed]
+ */
+ if (!updatePath(tunnel.tunnelId(), constraintList) && !tunnel.state().equals(Tunnel.State.FAILED)) {
+ // If updation fails store in PCE store as failed path
+ // then PCInitiate (Remove)
+ pceStore.addFailedPathInfo(new PcePathInfo(tunnel.path().src().deviceId(), tunnel
+ .path().dst().deviceId(), tunnel.tunnelName().value(), constraintList,
+ LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE))));
+ //Release that tunnel calling PCInitiate
+ releasePath(tunnel.tunnelId());
+ }
+ }
+
+ return false;
+ }
+
+ // Allocates the bandwidth locally for PCECC tunnels.
private TunnelConsumerId reserveBandwidth(Path computedPath, double bandwidthConstraint,
SharedBandwidthConstraint shBwConstraint) {
checkNotNull(computedPath);
@@ -860,14 +954,72 @@
public void process(PacketContext context) {
// Stop processing if the packet has been handled, since we
// can't do any more to it.
-
if (context.isHandled()) {
return;
}
InboundPacket pkt = context.inPacket();
+ if (pkt == null) {
+ return;
+ }
+
+ Ethernet ethernet = pkt.parsed();
+ if (ethernet == null || ethernet.getEtherType() != Ethernet.TYPE_IPV4) {
+ return;
+ }
+
+ IPv4 ipPacket = (IPv4) ethernet.getPayload();
+ if (ipPacket == null || ipPacket.getProtocol() != IPv4.PROTOCOL_TCP) {
+ return;
+ }
+
+ TCP tcp = (TCP) ipPacket.getPayload();
+ if (tcp == null || tcp.getDestinationPort() != PCEP_PORT) {
+ return;
+ }
+
syncLabelDb(pkt.receivedFrom().deviceId());
}
}
+ //Computes path from tunnel store and also path failed to setup.
+ private void callForOptimization() {
+ //Recompute the LSPs which it was delegated [LSPs stored in PCE store (failed paths)]
+ for (PcePathInfo failedPathInfo : pceStore.getFailedPathInfos()) {
+ checkForMasterAndSetupPath(failedPathInfo);
+ }
+
+ //Recompute the LSPs for which it was delegated [LSPs stored in tunnel store]
+ tunnelService.queryTunnel(MPLS).forEach(t -> {
+ checkForMasterAndUpdateTunnel(t.path().src().deviceId(), t);
+ });
+ }
+
+ private boolean checkForMasterAndSetupPath(PcePathInfo failedPathInfo) {
+ /**
+ * Master of ingress node will setup the path failed stored in PCE store.
+ */
+ if (mastershipService.isLocalMaster(failedPathInfo.src())) {
+ if (setupPath(failedPathInfo.src(), failedPathInfo.dst(), failedPathInfo.name(),
+ failedPathInfo.constraints(), failedPathInfo.lspType())) {
+ // If computation is success remove that path
+ pceStore.removeFailedPathInfo(failedPathInfo);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ //Timer to call global optimization
+ private class GlobalOptimizationTimer implements Runnable {
+
+ public GlobalOptimizationTimer() {
+ }
+
+ @Override
+ public void run() {
+ callForOptimization();
+ }
+ }
}
\ No newline at end of file
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java
index 8c3de14..cd28f9e 100644
--- a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java
@@ -19,7 +19,6 @@
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
-
import static org.onosproject.net.Link.Type.DIRECT;
import java.util.Iterator;
@@ -29,7 +28,6 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-
import org.onlab.packet.IpAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
@@ -165,6 +163,7 @@
@After
public void tearDown() throws Exception {
+ PceManagerTest.flowsDownloaded = 0;
}
/**
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java
index 5b0d869..2da22e5 100644
--- a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceManagerTest.java
@@ -15,13 +15,17 @@
import static org.onosproject.pce.pceservice.PathComputationTest.D2;
import static org.onosproject.pce.pceservice.PathComputationTest.D3;
import static org.onosproject.pce.pceservice.PathComputationTest.D4;
+import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE1;
+import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE2;
+import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE3;
+import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE4;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID;
import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PLSP_ID;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.ESTABLISHED;
+import static org.onosproject.net.MastershipRole.MASTER;
import java.net.URISyntaxException;
-import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -35,14 +39,18 @@
import org.junit.Before;
import org.junit.Test;
import org.onlab.graph.GraphPathSearch;
+import org.onlab.junit.TestUtils;
+import org.onlab.junit.TestUtils.TestUtilsException;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
+import org.onlab.packet.TCP;
import org.onlab.util.Bandwidth;
import org.onosproject.common.DefaultTopologyGraph;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.core.IdGenerator;
+import org.onosproject.event.Event;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.incubator.net.resource.label.LabelResourceService;
import org.onosproject.incubator.net.tunnel.DefaultTunnel;
@@ -52,6 +60,7 @@
import org.onosproject.incubator.net.tunnel.TunnelEvent;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelListener;
+import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
@@ -60,6 +69,7 @@
import org.onosproject.net.DefaultLink;
import org.onosproject.net.Device;
import org.onosproject.net.DefaultAnnotations.Builder;
+import org.onosproject.net.MastershipRole;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.DeviceId;
@@ -71,6 +81,7 @@
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.IntentId;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
+import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.DefaultPacketContext;
import org.onosproject.net.packet.InboundPacket;
@@ -86,7 +97,9 @@
import org.onosproject.net.topology.PathServiceAdapter;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyEdge;
+import org.onosproject.net.topology.TopologyEvent;
import org.onosproject.net.topology.TopologyGraph;
+import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyServiceAdapter;
import org.onosproject.net.topology.TopologyVertex;
import org.onosproject.pce.pceservice.PathComputationTest.MockPathResourceService;
@@ -97,7 +110,9 @@
import org.onosproject.pce.util.TunnelServiceAdapter;
import org.onosproject.pce.util.FlowObjServiceAdapter;
import org.onosproject.store.service.TestStorageService;
+
import com.google.common.collect.ImmutableSet;
+import static org.onosproject.pce.pceservice.PceManager.PCEP_PORT;
/**
* Tests the functions of PceManager.
@@ -107,6 +122,7 @@
private PathComputationTest pathCompTest = new PathComputationTest();
private MockPathResourceService resourceService = pathCompTest.new MockPathResourceService();
private MockTopologyService topologyService = new MockTopologyService();
+ private MockMastershipService mastershipService = new MockMastershipService();
private MockPathService pathService = new MockPathService();
private PceManager pceManager = new PceManager();
private MockCoreService coreService = new MockCoreService();
@@ -129,13 +145,19 @@
private Device deviceD1, deviceD2, deviceD3, deviceD4;
private Device pcepDeviceD1, pcepDeviceD2, pcepDeviceD3, pcepDeviceD4;
private Link link1, link2, link3, link4;
- private static int flowsDownloaded;
+ protected static int flowsDownloaded;
private TunnelListener tunnelListener;
+ private TopologyListener listener;
+ private Topology topology;
+ private Set<TopologyEdge> edges;
+ private Set<TopologyVertex> vertexes;
@Before
- public void startUp() {
+ public void startUp() throws TestUtilsException {
+ listener = TestUtils.getField(pceManager, "topologyListener");
pceManager.pathService = pathService;
pceManager.resourceService = resourceService;
+ pceManager.topologyService = topologyService;
pceManager.tunnelService = tunnelService;
pceManager.coreService = coreService;
pceManager.storageService = storageService;
@@ -144,34 +166,52 @@
pceManager.labelRsrcService = labelResourceService;
pceManager.flowObjectiveService = flowObjectiveService;
pceManager.pceStore = pceStore;
+ pceManager.mastershipService = mastershipService;
pceManager.activate();
}
+ private class MockMastershipService extends MastershipServiceAdapter {
+ @Override
+ public MastershipRole getLocalRole(DeviceId deviceId) {
+ return MASTER;
+ }
+
+ @Override
+ public boolean isLocalMaster(DeviceId deviceId) {
+ return getLocalRole(deviceId) == MASTER;
+ }
+ }
+
private void build4RouterTopo(boolean setCost, boolean setPceccCap, boolean setSrCap,
boolean setLabelStackCap, int bandwidth) {
+ link1 = PathComputationTest.addLink(DEVICE1, 10, DEVICE2, 20, setCost, 50);
+ link2 = PathComputationTest.addLink(DEVICE2, 30, DEVICE4, 40, setCost, 20);
+ link3 = PathComputationTest.addLink(DEVICE1, 80, DEVICE3, 70, setCost, 100);
+ link4 = PathComputationTest.addLink(DEVICE3, 60, DEVICE4, 50, setCost, 80);
+
Set<TopologyVertex> vertexes = new HashSet<TopologyVertex>();
vertexes.add(D1);
vertexes.add(D2);
vertexes.add(D3);
vertexes.add(D4);
+ this.vertexes = vertexes;
+
Set<TopologyEdge> edges = new HashSet<TopologyEdge>();
- link1 = PathComputationTest.addLink(D1.deviceId().toString(), 10, D2.deviceId().toString(), 20, setCost, 50);
TopologyEdge edge1 = new DefaultTopologyEdge(D1, D2, link1);
edges.add(edge1);
- link2 = PathComputationTest.addLink(D2.deviceId().toString(), 30, D4.deviceId().toString(), 40, setCost, 20);
TopologyEdge edge2 = new DefaultTopologyEdge(D2, D4, link2);
edges.add(edge2);
- link3 = PathComputationTest.addLink(D1.deviceId().toString(), 80, D3.deviceId().toString(), 70, setCost, 100);
TopologyEdge edge3 = new DefaultTopologyEdge(D1, D3, link3);
edges.add(edge3);
- link4 = PathComputationTest.addLink(D3.deviceId().toString(), 60, D4.deviceId().toString(), 50, setCost, 80);
TopologyEdge edge4 = new DefaultTopologyEdge(D3, D4, link4);
edges.add(edge4);
+ this.edges = edges;
+
graph = new DefaultTopologyGraph(vertexes, edges);
DefaultAnnotations.Builder builderDev1 = DefaultAnnotations.builder();
@@ -636,21 +676,18 @@
* Tests packet in to trigger label DB sync.
*/
@Test
- public void packetProcessingTest() throws URISyntaxException {
+ public void packetProcessingTest1() throws URISyntaxException {
build4RouterTopo(false, true, true, true, 0); // This also initializes devices etc.
- final int srcHost = 2;
- final int dstHost = 5;
-
LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
- ConnectPoint src = new ConnectPoint(D1.deviceId(), PortNumber.portNumber(srcHost));
- ConnectPoint dst = new ConnectPoint(D2.deviceId(), PortNumber.portNumber(dstHost));
+ ConnectPoint src = new ConnectPoint(D1.deviceId(), PortNumber.portNumber(1));
+ ConnectPoint dst = new ConnectPoint(D2.deviceId(), PortNumber.portNumber(2));
Link link1 = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).type(DIRECT)
.providerId(new ProviderId("eth", "1")).build();
@@ -658,24 +695,66 @@
LabelResourceId link1Label = LabelResourceId.labelResourceId(5204);
pceManager.pceStore.addAdjLabel(link1, link1Label);
- Ethernet eth;
- IPv4 ipv4;
+ TCP tcp = new TCP();
+ tcp.setDestinationPort(PCEP_PORT);
- ipv4 = new IPv4();
- eth = new Ethernet();
+ IPv4 ipv4 = new IPv4();
+ ipv4.setProtocol(IPv4.PROTOCOL_TCP);
+ ipv4.setPayload(tcp);
+
+ Ethernet eth = new Ethernet();
eth.setEtherType(Ethernet.TYPE_IPV4);
eth.setPayload(ipv4);
- eth.setSourceMACAddress("00:00:00:10:00:0" + srcHost).setDestinationMACAddress("00:00:00:10:00:0" + dstHost);
-
- InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(D1.deviceId(), PortNumber.portNumber(srcHost)),
- eth, ByteBuffer.wrap(eth.serialize()));
+ InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(D1.deviceId(),
+ PortNumber.portNumber(PCEP_PORT)),
+ eth, null);
pktProcessor.process(new MockPcepPacketContext(inPkt, null));
assertThat(flowsDownloaded, is(4));
}
/**
+ * Tests faulty packet in to trigger label DB sync.
+ */
+ @Test
+ public void packetProcessingTest2() throws URISyntaxException {
+
+ build4RouterTopo(false, true, true, true, 0); // This also initializes devices etc.
+
+ LabelResourceId node1Label = LabelResourceId.labelResourceId(5200);
+ LabelResourceId node2Label = LabelResourceId.labelResourceId(5201);
+
+ pceManager.pceStore.addGlobalNodeLabel(D1.deviceId(), node1Label);
+ pceManager.pceStore.addGlobalNodeLabel(D2.deviceId(), node2Label);
+
+ ConnectPoint src = new ConnectPoint(D1.deviceId(), PortNumber.portNumber(1));
+ ConnectPoint dst = new ConnectPoint(D2.deviceId(), PortNumber.portNumber(2));
+
+ Link link1 = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).type(DIRECT)
+ .providerId(new ProviderId("eth", "1")).build();
+
+ LabelResourceId link1Label = LabelResourceId.labelResourceId(5204);
+ pceManager.pceStore.addAdjLabel(link1, link1Label);
+
+ TCP tcp = new TCP(); // Not set the pcep port.
+ IPv4 ipv4 = new IPv4();
+ ipv4.setProtocol(IPv4.PROTOCOL_TCP);
+ ipv4.setPayload(tcp);
+
+ Ethernet eth = new Ethernet();
+ eth.setEtherType(Ethernet.TYPE_IPV4);
+ eth.setPayload(ipv4);
+
+ InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(D1.deviceId(),
+ PortNumber.portNumber(PCEP_PORT)),
+ eth, null);
+
+ pktProcessor.process(new MockPcepPacketContext(inPkt, null));
+ assertThat(flowsDownloaded, is(0));
+ }
+
+ /**
* Tests tunnel events added and removed.
*/
@Test
@@ -800,6 +879,390 @@
assertThat(pceStore.getFailedPathInfoCount(), is(1));
}
+ /**
+ * Tests resilency when L2 link is down.
+ */
+ @Test
+ public void resilencyTest1() {
+ build4RouterTopo(true, false, false, false, 10);
+
+
+ List<Constraint> constraints = new LinkedList<Constraint>();
+ CostConstraint costConstraint = new CostConstraint(COST);
+ constraints.add(costConstraint);
+ BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
+ constraints.add(localBwConst);
+
+ //Setup the path , tunnel created
+ boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
+ assertThat(result, is(true));
+ assertThat(pceStore.getTunnelInfoCount(), is(1));
+ assertThat(pceStore.getFailedPathInfoCount(), is(0));
+
+ List<Event> reasons = new LinkedList<>();
+ final LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
+ reasons.add(linkEvent);
+ final TopologyEvent event = new TopologyEvent(
+ TopologyEvent.Type.TOPOLOGY_CHANGED,
+ topology,
+ reasons);
+
+ //Change Topology : remove link2
+ Set<TopologyEdge> tempEdges = new HashSet<>();
+ tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
+ topologyService.changeInTopology(getGraph(null, tempEdges));
+ listener.event(event);
+
+ List<Link> links = new LinkedList<>();
+ links.add(link3);
+ links.add(link4);
+
+ //Path is D1-D3-D4
+ assertThat(pathService.paths().iterator().next().links(), is(links));
+ assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
+ }
+
+ /**
+ * Tests resilency when L2 and L4 link is down.
+ */
+ @Test
+ public void resilencyTest2() {
+ build4RouterTopo(true, false, false, false, 10);
+
+ List<Constraint> constraints = new LinkedList<Constraint>();
+ CostConstraint costConstraint = new CostConstraint(COST);
+ constraints.add(costConstraint);
+ BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
+ constraints.add(localBwConst);
+
+ //Setup the path , tunnel created
+ boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
+ assertThat(result, is(true));
+
+ List<Event> reasons = new LinkedList<>();
+ LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
+ reasons.add(linkEvent);
+ linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
+ reasons.add(linkEvent);
+ final TopologyEvent event = new TopologyEvent(
+ TopologyEvent.Type.TOPOLOGY_CHANGED,
+ topology,
+ reasons);
+
+ //Change Topology : remove link2 and link4
+ Set<TopologyEdge> tempEdges = new HashSet<>();
+ tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
+ tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
+ topologyService.changeInTopology(getGraph(null, tempEdges));
+ listener.event(event);
+
+ //No Path
+ assertThat(pathService.paths().size(), is(0));
+ }
+
+ /**
+ * Tests resilency when D2 device is down.
+ */
+ @Test
+ public void resilencyTest3() {
+ build4RouterTopo(true, false, false, false, 10);
+
+ List<Constraint> constraints = new LinkedList<Constraint>();
+ CostConstraint costConstraint = new CostConstraint(COST);
+ constraints.add(costConstraint);
+ BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
+ constraints.add(localBwConst);
+
+ //Setup the path , tunnel created
+ boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
+ assertThat(result, is(true));
+
+ List<Event> reasons = new LinkedList<>();
+ LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
+ reasons.add(linkEvent);
+ linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
+ reasons.add(linkEvent);
+ final TopologyEvent event = new TopologyEvent(
+ TopologyEvent.Type.TOPOLOGY_CHANGED,
+ topology,
+ reasons);
+
+ //Change Topology : remove link2 and link1
+ Set<TopologyEdge> tempEdges = new HashSet<>();
+ tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
+ tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
+ topologyService.changeInTopology(getGraph(null, tempEdges));
+ listener.event(event);
+
+ List<Link> links = new LinkedList<>();
+ links.add(link3);
+ links.add(link4);
+
+ //Path is D1-D3-D4
+ assertThat(pathService.paths().iterator().next().links(), is(links));
+ assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
+ }
+
+ /**
+ * Tests resilency when ingress device is down.
+ */
+ @Test
+ public void resilencyTest4() {
+ build4RouterTopo(true, false, false, false, 10);
+
+ List<Constraint> constraints = new LinkedList<Constraint>();
+ CostConstraint costConstraint = new CostConstraint(COST);
+ constraints.add(costConstraint);
+ BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
+ constraints.add(localBwConst);
+
+ //Setup the path , tunnel created
+ boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
+ assertThat(result, is(true));
+
+ List<Event> reasons = new LinkedList<>();
+ LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link3);
+ reasons.add(linkEvent);
+ linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
+ reasons.add(linkEvent);
+ final TopologyEvent event = new TopologyEvent(
+ TopologyEvent.Type.TOPOLOGY_CHANGED,
+ topology,
+ reasons);
+
+ //Change Topology : remove link2 and link1
+ Set<TopologyEdge> tempEdges = new HashSet<>();
+ tempEdges.add(new DefaultTopologyEdge(D1, D3, link3));
+ tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
+ topologyService.changeInTopology(getGraph(null, tempEdges));
+ listener.event(event);
+
+ //No path
+ assertThat(pathService.paths().size(), is(0));
+ }
+
+ /**
+ * Tests resilency when D2 and D3 devices are down.
+ */
+ @Test
+ public void resilencyTest5() {
+ build4RouterTopo(true, false, false, false, 10);
+
+ List<Constraint> constraints = new LinkedList<Constraint>();
+ CostConstraint costConstraint = new CostConstraint(COST);
+ constraints.add(costConstraint);
+ BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
+ constraints.add(localBwConst);
+
+ //Setup the path , tunnel created
+ boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
+ assertThat(result, is(true));
+
+ List<Event> reasons = new LinkedList<>();
+ LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
+ reasons.add(linkEvent);
+ linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
+ reasons.add(linkEvent);
+ linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link3);
+ reasons.add(linkEvent);
+ linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
+ reasons.add(linkEvent);
+
+ final TopologyEvent event = new TopologyEvent(
+ TopologyEvent.Type.TOPOLOGY_CHANGED,
+ topology,
+ reasons);
+
+ //Change Topology : remove device2, device3 and all links
+ Set<TopologyEdge> tempEdges = new HashSet<>();
+ tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
+ tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
+ tempEdges.add(new DefaultTopologyEdge(D1, D3, link3));
+ tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
+ Set<TopologyVertex> tempVertexes = new HashSet<>();
+ tempVertexes.add(D2);
+ tempVertexes.add(D3);
+ topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
+ listener.event(event);
+
+ //No path
+ assertThat(pathService.paths().size(), is(0));
+ }
+
+ /**
+ * Tests resilency when egress device is down.
+ */
+ @Test
+ public void resilencyTest6() {
+ build4RouterTopo(true, false, false, false, 10);
+
+ List<Constraint> constraints = new LinkedList<Constraint>();
+ CostConstraint costConstraint = new CostConstraint(COST);
+ constraints.add(costConstraint);
+ BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
+ constraints.add(localBwConst);
+
+ //Setup the path , tunnel created
+ boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
+ assertThat(result, is(true));
+
+ List<Event> reasons = new LinkedList<>();
+ LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
+ reasons.add(linkEvent);
+ linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
+ reasons.add(linkEvent);
+
+ final TopologyEvent event = new TopologyEvent(
+ TopologyEvent.Type.TOPOLOGY_CHANGED,
+ topology,
+ reasons);
+
+ //Change Topology : remove device4 , link2 and link4
+ Set<TopologyEdge> tempEdges = new HashSet<>();
+ tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
+ tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
+ Set<TopologyVertex> tempVertexes = new HashSet<>();
+ tempVertexes.add(D4);
+ topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
+ listener.event(event);
+
+ //No path
+ assertThat(pathService.paths().size(), is(0));
+ }
+
+ /**
+ * Tests resilency when egress device is down.
+ */
+ @Test
+ public void resilencyTest7() {
+ build4RouterTopo(true, false, false, false, 10);
+
+ List<Constraint> constraints = new LinkedList<Constraint>();
+ CostConstraint costConstraint = new CostConstraint(COST);
+ constraints.add(costConstraint);
+ BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
+ constraints.add(localBwConst);
+
+ //Setup the path , tunnel created
+ boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
+ assertThat(result, is(true));
+
+ List<Event> reasons = new LinkedList<>();
+ LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
+ reasons.add(linkEvent);
+ linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
+ reasons.add(linkEvent);
+
+ final TopologyEvent event = new TopologyEvent(
+ TopologyEvent.Type.TOPOLOGY_CHANGED,
+ topology,
+ reasons);
+
+ //Change Topology : remove device4 , link2 and link4
+ Set<TopologyEdge> tempEdges = new HashSet<>();
+ tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
+ tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
+ Set<TopologyVertex> tempVertexes = new HashSet<>();
+ tempVertexes.add(D4);
+ topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
+ listener.event(event);
+
+ //No path
+ assertThat(pathService.paths().size(), is(0));
+ }
+
+ /**
+ * Tests resilency when D2 device is suspended.
+ */
+ @Test
+ public void resilencyTest8() {
+ build4RouterTopo(true, false, false, false, 10);
+
+ List<Constraint> constraints = new LinkedList<Constraint>();
+ CostConstraint costConstraint = new CostConstraint(COST);
+ constraints.add(costConstraint);
+ BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
+ constraints.add(localBwConst);
+
+ //Setup the path , tunnel created
+ boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
+ assertThat(result, is(true));
+
+ List<Event> reasons = new LinkedList<>();
+ LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
+ reasons.add(linkEvent);
+ linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
+ reasons.add(linkEvent);
+
+ final TopologyEvent event = new TopologyEvent(
+ TopologyEvent.Type.TOPOLOGY_CHANGED,
+ topology,
+ reasons);
+
+ //Change Topology : remove device2 , link1 and link2
+ Set<TopologyEdge> tempEdges = new HashSet<>();
+ tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
+ tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
+ Set<TopologyVertex> tempVertexes = new HashSet<>();
+ tempVertexes.add(D2);
+ topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
+ listener.event(event);
+
+ List<Link> links = new LinkedList<>();
+ links.add(link3);
+ links.add(link4);
+
+ //Path is D1-D3-D4
+ assertThat(pathService.paths().iterator().next().links(), is(links));
+ assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
+ }
+
+ /**
+ * Tests resilency when D2 device availability is changed.
+ */
+ @Test
+ public void resilencyTest11() {
+ build4RouterTopo(true, false, false, false, 10);
+
+ List<Constraint> constraints = new LinkedList<Constraint>();
+ CostConstraint costConstraint = new CostConstraint(COST);
+ constraints.add(costConstraint);
+ BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
+ constraints.add(localBwConst);
+
+ //Setup the path , tunnel created
+ boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
+ assertThat(result, is(true));
+
+ List<Event> reasons = new LinkedList<>();
+ LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
+ reasons.add(linkEvent);
+ linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
+ reasons.add(linkEvent);
+
+ final TopologyEvent event = new TopologyEvent(
+ TopologyEvent.Type.TOPOLOGY_CHANGED,
+ topology,
+ reasons);
+
+ //Change Topology : remove device2 , link1 and link2
+ Set<TopologyEdge> tempEdges = new HashSet<>();
+ tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
+ tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
+ Set<TopologyVertex> tempVertexes = new HashSet<>();
+ tempVertexes.add(D2);
+ topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
+ listener.event(event);
+
+ List<Link> links = new LinkedList<>();
+ links.add(link3);
+ links.add(link4);
+
+ //Path is D1-D3-D4
+ assertThat(pathService.paths().iterator().next().links(), is(links));
+ assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
+ }
+
@After
public void tearDown() {
pceManager.deactivate();
@@ -813,10 +1276,16 @@
pceManager.labelRsrcService = null;
pceManager.flowObjectiveService = null;
pceManager.pceStore = null;
+ pceManager.topologyService = null;
+ pceManager.mastershipService = null;
flowsDownloaded = 0;
}
private class MockTopologyService extends TopologyServiceAdapter {
+ private void changeInTopology(TopologyGraph graphModified) {
+ graph = graphModified;
+ }
+
@Override
public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
@@ -837,8 +1306,27 @@
}
}
- private class MockPathService extends PathServiceAdapter {
+ private TopologyGraph getGraph(Set<TopologyVertex> removedVertex, Set<TopologyEdge> removedEdges) {
+ if (removedVertex != null) {
+ vertexes.remove(removedVertex);
+ removedVertex.forEach(v ->
+ {
+ vertexes.remove(v);
+ });
+ }
+ if (removedEdges != null) {
+ removedEdges.forEach(e ->
+ {
+ edges.remove(e);
+ });
+ }
+
+ return new DefaultTopologyGraph(vertexes, edges);
+ }
+
+ private class MockPathService extends PathServiceAdapter {
+ Set<Path> computedPaths;
@Override
public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
// If either edge is null, bail with no paths.
@@ -848,7 +1336,12 @@
// Otherwise get all paths between the source and destination edge
// devices.
- return topologyService.getPaths(null, (DeviceId) src, (DeviceId) dst, weight);
+ computedPaths = topologyService.getPaths(null, (DeviceId) src, (DeviceId) dst, weight);
+ return computedPaths;
+ }
+
+ private Set<Path> paths() {
+ return computedPaths;
}
}
@@ -946,6 +1439,31 @@
return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
}
+
+ @Override
+ public Collection<Tunnel> queryAllTunnels() {
+ Collection<Tunnel> result = new HashSet<Tunnel>();
+
+ for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
+ result.add(tunnelIdAsKeyStore.get(tunnelId));
+ }
+
+ return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
+ }
+ @Override
+ public Iterable<Tunnel> getTunnels(DeviceId deviceId) {
+ List<Tunnel> tunnelList = new LinkedList<>();
+
+ for (Tunnel t : tunnelIdAsKeyStore.values()) {
+ for (Link l : t.path().links()) {
+ if (l.src().deviceId().equals(deviceId) || l.dst().deviceId().equals(deviceId)) {
+ tunnelList.add(t);
+ break;
+ }
+ }
+ }
+ return tunnelList;
+ }
}
public static class MockCoreService extends CoreServiceAdapter {
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java
index 2a419b5..a49bb0b 100644
--- a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java
@@ -158,6 +158,7 @@
@After
public void tearDown() throws Exception {
+ PceManagerTest.flowsDownloaded = 0;
}
/**
diff --git a/apps/pce/pceweb/app.png b/apps/pce/pceweb/app.png
index abe34eb..01ea558 100644
--- a/apps/pce/pceweb/app.png
+++ b/apps/pce/pceweb/app.png
Binary files differ
diff --git a/apps/pce/pceweb/pom.xml b/apps/pce/pceweb/pom.xml
index b9b1435..9e815a0 100644
--- a/apps/pce/pceweb/pom.xml
+++ b/apps/pce/pceweb/pom.xml
@@ -23,6 +23,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-pce</artifactId>
<version>1.6.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-pceweb</artifactId>
@@ -42,6 +43,11 @@
<artifactId>onos-cli</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-app-pce</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<properties>
diff --git a/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java b/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java
index 0c1a5b5..95e9f1f 100644
--- a/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java
+++ b/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovMessageHandler.java
@@ -17,33 +17,48 @@
package org.onosproject.pceweb;
import com.fasterxml.jackson.databind.node.ObjectNode;
-
-
import com.google.common.collect.ImmutableSet;
+
import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onlab.util.DataRateUnit;
+import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
-import org.onosproject.net.DisjointPath;
import org.onosproject.net.ElementId;
import org.onosproject.net.HostId;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.topology.LinkWeight;
-import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.TopologyEvent;
+import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyService;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.topo.DeviceHighlight;
import org.onosproject.ui.topo.Highlights;
-import org.onosproject.ui.topo.HostHighlight;
import org.onosproject.ui.topo.NodeBadge;
import org.onosproject.ui.topo.TopoJson;
-
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.pce.pceservice.LspType;
+import org.onosproject.pce.pceservice.api.PceService;
+import org.onosproject.pce.pceservice.constraint.CostConstraint;
+import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
+import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
+import org.onosproject.incubator.net.tunnel.TunnelEvent;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.tunnel.TunnelListener;
+import org.onosproject.incubator.net.tunnel.TunnelService;
+import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
import java.util.Collection;
+import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@@ -56,47 +71,66 @@
private static final String PCEWEB_SET_SRC = "pceTopovSetSrc";
private static final String PCEWEB_SET_DST = "pceTopovSetDst";
private static final String PCEWEB_SET_PATH = "pceTopovSetMode";
-
+ private static final String PCEWEB_UPDATE_PATH_QUERY = "pceTopovUpdateQuery";
+ private static final String PCEWEB_UPDATE_PATH = "pceTopovUpdate";
+ private static final String PCEWEB_REMOVE_PATH_QUERY = "pceTopovRemQuery";
+ private static final String PCEWEB_REMOVE_PATH = "pceTopovRem";
+ private static final String PCEWEB_QUERY_TUNNELS = "pceTopovTunnelDisplay";
+ private static final String PCEWEB_SHOW_TUNNEL = "pceTopovShowTunnels";
+ private static final String PCEWEB_SHOW_TUNNEL_REMOVE = "pceTopovShowTunnelsRem";
private static final String ID = "id";
- private static final String MODE = "mode";
private static final String TYPE = "type";
- private static final String SWITCH = "switch";
- private static final String ENDSTATION = "endstation";
- public static final String DST = "Dst";
- public static final String SRC = "Src";
+ private static final String ROUTER = "router";
+ private static final String DST = "Egress";
+ private static final String SRC = "Ingress";
+ private static final String BANDWIDTH = "bw";
+ private static final String BANDWIDTHTYPE = "bwtype";
+ private static final String COSTTYPE = "ctype";
+ private static final String LSPTYPE = "lsptype";
+ private static final String SRCID = "srid";
+ private static final String DSTID = "dsid";
+ private static final String TUNNEL_ID = "tunnelid";
+ private static final String TUNNEL_NAME = "tunnelname";
+ private static final String COST_TYPE_IGP = "igp";
+ private static final String COST_TYPE_TE = "te";
+ private static final String BANDWIDTH_TYPE_KBPS = "kbps";
+ private static final String BUFFER_ARRAY = "a";
+ private static final String BANDWIDTH_BPS = "BPS";
+ private static final String LSP_TYPE_CR = "cr";
+ private static final String LSP_TYPE_SRBE = "srbe";
+ private static final String LSP_TYPE_SRTE = "srte";
+ private static final String STRING_NULL = "null";
// Delay for showHighlights event processing on GUI client side to
// account for addLink animation.
- public static final int DELAY_MS = 1100;
-
- private static final String CLASS = "class";
- private static final String UNKNOWN = "unknown";
- private static final String DEVICE = "device";
+ private static final int DELAY_MS = 1100;
+ private static final double BANDWIDTH_KBPS = 1_000;
+ private static final double BANDWIDTH_MBPS = 1_000_000;
private Set<Link> allPathLinks;
- private boolean listenersRemoved;
- private LinkWeight linkData;
private int highlightDelay;
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- private PathService pathService;
-
private ElementId src, dst;
private String srcType, dstType;
private List<Path> paths;
private int pathIndex;
+ private final Logger log = LoggerFactory.getLogger(getClass());
+ private final TopologyListener topologyListener = new InternalTopologyListener();
+ private final TunnelListener tunnelListener = new InnerPceWebTunnelListener();
+
protected TopologyService topologyService;
+ protected TunnelService tunnelService;
+ protected PceService pceService;
protected DeviceService deviceService;
-
-
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
- //TODO: Need add listeners.
- //topologyService = directory.get(TopologyService.class);
- //addListeners();
+ topologyService = directory.get(TopologyService.class);
+ tunnelService = directory.get(TunnelService.class);
+ pceService = directory.get(PceService.class);
+ deviceService = directory.get(DeviceService.class);
+ topologyService.addListener(topologyListener);
+ tunnelService.addListener(tunnelListener);
}
@Override
@@ -105,7 +139,19 @@
new ClearHandler(),
new SetSrcHandler(),
new SetDstHandler(),
- new SetPathHandler());
+ new SetPathHandler(),
+ new UpdatePathQueryHandler(),
+ new UpdatePathHandler(),
+ new RemovePathQueryHandler(),
+ new RemovePathHandler(),
+ new ShowTunnelHandler());
+ }
+
+ @Override
+ public void destroy() {
+ topologyService.removeListener(topologyListener);
+ tunnelService.removeListener(tunnelListener);
+ super.destroy();
}
// Handler classes
@@ -137,7 +183,6 @@
@Override
public void process(long sid, ObjectNode payload) {
- log.info("PCE WEB Set source process method invoked");
String id = string(payload, ID);
src = elementId(id);
srcType = string(payload, TYPE);
@@ -146,7 +191,6 @@
}
sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(),
srcType, src.toString(), SRC)));
-
}
}
@@ -167,7 +211,6 @@
if (src.equals(dst)) {
src = null;
}
-
sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(),
dstType, dst.toString(), DST)));
@@ -175,7 +218,7 @@
}
/**
- * Handles the 'patchcalculation' event received from the client.
+ * Handles the 'path calculation' event received from the client.
*/
private final class SetPathHandler extends RequestHandler {
@@ -185,15 +228,168 @@
@Override
public void process(long sid, ObjectNode payload) {
- String mode = string(payload, MODE);
+ String bandWidth = string(payload, BANDWIDTH);
+ String bandWidthType = string(payload, BANDWIDTHTYPE);
+ String costType = string(payload, COSTTYPE);
+ String lspType = string(payload, LSPTYPE);
+ String tunnelName = string(payload, TUNNEL_NAME);
- // TODO: Read user input[constraints] and call the path calculation based on
- //given constrainsts.
- findAndSendPaths();
+ if (tunnelName.equals(STRING_NULL)) {
+ log.error("tunnel name should not be empty");
+ return;
+ }
+
+ if (pceService == null) {
+ log.error("PCE service is not active");
+ return;
+ }
+
+ if (lspType == null) {
+ log.error("PCE setup path is failed.");
+ }
+
+ if ((src != null) && (dst != null)) {
+ findAndSendPaths(src, dst, bandWidth, bandWidthType, costType, lspType, tunnelName);
+ }
}
}
- // === ------------
+ /**
+ * Handles the 'update path query' event received from the client.
+ */
+ private final class UpdatePathQueryHandler extends RequestHandler {
+
+ public UpdatePathQueryHandler() {
+ super(PCEWEB_UPDATE_PATH_QUERY);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String srcId = string(payload, SRCID);
+ ElementId src = elementId(srcId);
+ String dstId = string(payload, DSTID);
+ ElementId dst = elementId(dstId);
+ Device srcDevice = deviceService.getDevice((DeviceId) src);
+ Device dstDevice = deviceService.getDevice((DeviceId) dst);
+
+ TunnelEndPoint tunSrc = IpTunnelEndPoint.ipTunnelPoint(IpAddress
+ .valueOf(srcDevice.annotations().value("lsrId")));
+ TunnelEndPoint tunDst = IpTunnelEndPoint.ipTunnelPoint(IpAddress
+ .valueOf(dstDevice.annotations().value("lsrId")));
+
+ Collection<Tunnel> tunnelSet = tunnelService.queryTunnel(tunSrc, tunDst);
+ ObjectNode result = objectNode();
+ ArrayNode arrayNode = arrayNode();
+ for (Tunnel tunnel : tunnelSet) {
+ if (tunnel.type() == MPLS) {
+ arrayNode.add(tunnel.tunnelId().toString());
+ }
+ }
+
+ result.putArray(BUFFER_ARRAY).addAll(arrayNode);
+ sendMessage(PCEWEB_SHOW_TUNNEL, sid, result);
+ }
+ }
+
+ /**
+ * Handles the 'update path' event received from the client.
+ */
+ private final class UpdatePathHandler extends RequestHandler {
+
+ public UpdatePathHandler() {
+ super(PCEWEB_UPDATE_PATH);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String bandWidth = string(payload, BANDWIDTH);
+ String bandWidthType = string(payload, BANDWIDTHTYPE);
+ String costType = string(payload, COSTTYPE);
+ String tunnelId = string(payload, TUNNEL_ID);
+
+ if (tunnelId == null) {
+ log.error("PCE update path is failed.");
+ }
+
+ findAndSendPathsUpdate(bandWidth, bandWidthType, costType, tunnelId);
+ }
+ }
+
+ /**
+ * Handles the 'remove path query' event received from the client.
+ */
+ private final class RemovePathQueryHandler extends RequestHandler {
+
+ public RemovePathQueryHandler() {
+ super(PCEWEB_REMOVE_PATH_QUERY);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String srcId = string(payload, SRCID);
+ ElementId src = elementId(srcId);
+ String dstId = string(payload, DSTID);
+ ElementId dst = elementId(dstId);
+
+ Device srcDevice = deviceService.getDevice((DeviceId) src);
+ Device dstDevice = deviceService.getDevice((DeviceId) dst);
+
+ TunnelEndPoint tunSrc = IpTunnelEndPoint.ipTunnelPoint(IpAddress
+ .valueOf(srcDevice.annotations().value("lsrId")));
+ TunnelEndPoint tunDst = IpTunnelEndPoint.ipTunnelPoint(IpAddress
+ .valueOf(dstDevice.annotations().value("lsrId")));
+
+ Collection<Tunnel> tunnelSet = tunnelService.queryTunnel(tunSrc, tunDst);
+ ObjectNode result = objectNode();
+ ArrayNode arrayNode = arrayNode();
+
+ for (Tunnel tunnel : tunnelSet) {
+ if (tunnel.type() == MPLS) {
+ arrayNode.add(tunnel.tunnelId().toString());
+ }
+ }
+
+ result.putArray(BUFFER_ARRAY).addAll(arrayNode);
+ sendMessage(PCEWEB_SHOW_TUNNEL_REMOVE, sid, result);
+ }
+ }
+
+ /**
+ * Handles the 'remove path' event received from the client.
+ */
+ private final class RemovePathHandler extends RequestHandler {
+
+ public RemovePathHandler() {
+ super(PCEWEB_REMOVE_PATH);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String tunnelId = string(payload, TUNNEL_ID);
+
+ if (tunnelId == null) {
+ log.error("PCE update path is failed.");
+ }
+
+ findAndSendPathsRemove(tunnelId);
+ }
+ }
+
+ /**
+ * Handles the 'show the existed tunnels' event received from the client.
+ */
+ private final class ShowTunnelHandler extends RequestHandler {
+
+ public ShowTunnelHandler() {
+ super(PCEWEB_QUERY_TUNNELS);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ findTunnelAndHighlights();
+ }
+ }
+
/**
* provides the element id.
*/
@@ -204,45 +400,170 @@
return HostId.hostId(id);
}
}
- //TODO: Need to pass constraints to this method
- private void findAndSendPaths() {
- log.info("src={}; dst={};", src, dst);
- if (src != null && dst != null) {
- //TBD: Need to call pathcalulation API here
- hilightAndSendPaths();
+ /**
+ * Handles the setup path and highlights the path.
+ *
+ * @param bandWidth
+ * @param bandWidthType is the kbps or mbps
+ * @param costType is igp or te
+ * @param lspType is WITH_SIGNALLING,WITHOUT_SIGNALLING_AND_WITHOUT_SR or SR_WITHOUT_SIGNALLING
+ * @param tunnelName tunnel id
+ */
+ private void findAndSendPaths(ElementId src, ElementId dst, String bandWidth, String bandWidthType,
+ String costType, String lspType, String tunnelName) {
+ log.debug("src={}; dst={};", src, dst);
+ boolean path;
+ List<Constraint> listConstrnt;
+
+ listConstrnt = addBandwidthCostTypeConstraints(bandWidth, bandWidthType, costType);
+
+ //LSP type
+ LspType lspTypeVal = null;
+ switch (lspType) {
+ case LSP_TYPE_CR:
+ lspTypeVal = LspType.WITH_SIGNALLING;
+ break;
+ case LSP_TYPE_SRBE:
+ lspTypeVal = LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
+ break;
+ case LSP_TYPE_SRTE:
+ lspTypeVal = LspType.SR_WITHOUT_SIGNALLING;
+ break;
+ default:
+ log.error("Invalid LSP type");
+ break;
}
+ path = pceService.setupPath((DeviceId) src, (DeviceId) dst, tunnelName, listConstrnt, lspTypeVal);
+ if (!path) {
+ log.error("setup path is failed");
+ return;
+ }
+
+ return;
}
- //TODO: The below code is not used. Once get path from PCE app then below code will be use.
- // the below code will get path and it will highlight the selected path.
- //Currently primary path in use, there is no use of secondary path.
- //secondary path need to remove based on path received by PCE app.
- private ImmutableSet.Builder<Link> buildPaths(
- ImmutableSet.Builder<Link> pathBuilder) {
+ /**
+ * Handles the update path and highlights the path.
+ *
+ * @param bandWidth bandWidth
+ * @param bandWidthType is the kbps or mbps
+ * @param costType is igp or te
+ * @param tunnelName tunnel id
+ */
+ private void findAndSendPathsUpdate(String bandWidth, String bandWidthType, String costType, String tunnelIdStr) {
+ if (tunnelIdStr != null) {
+ List<Constraint> listConstrnt;
+
+ if (tunnelIdStr.equals(STRING_NULL)) {
+ log.error("update path is failed");
+ return;
+ }
+
+ if (pceService == null) {
+ log.error("PCE service is not active");
+ return;
+ }
+
+ listConstrnt = addBandwidthCostTypeConstraints(bandWidth, bandWidthType, costType);
+ TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr);
+ boolean path = pceService.updatePath(tunnelId, listConstrnt);
+
+ if (!path) {
+ log.error("update path is failed");
+ return;
+ }
+ }
+ return;
+ }
+
+ /**
+ * Handles the remove path and highlights the paths if existed.
+ *
+ * @param tunnelIdName tunnelId
+ */
+ private void findAndSendPathsRemove(String tunnelIdStr) {
+ if (tunnelIdStr != null) {
+ if (pceService == null) {
+ log.error("PCE service is not active");
+ return;
+ }
+
+ TunnelId tunnelId = TunnelId.valueOf(tunnelIdStr);
+ boolean path = pceService.releasePath(tunnelId);
+ if (!path) {
+ log.error("remove path is failed");
+ return;
+ }
+ }
+ return;
+ }
+
+ private ImmutableSet.Builder<Link> buildPaths(ImmutableSet.Builder<Link> pathBuilder) {
paths.forEach(path -> path.links().forEach(pathBuilder::add));
return pathBuilder;
}
- private ImmutableSet.Builder<Link> buildDisjointPaths(
- ImmutableSet.Builder<Link> pathBuilder) {
- paths.forEach(path -> {
- DisjointPath dp = (DisjointPath) path;
- pathBuilder.addAll(dp.primary().links());
- pathBuilder.addAll(dp.backup().links());
- });
- return pathBuilder;
+ /**
+ * Handles the preparation of constraints list with given bandwidth and cost-type.
+ *
+ * @param bandWidth bandWidth
+ * @param bandWidthType is the kbps or mbps
+ * @param costType is igp or te
+ * @param listConstrnt list of constraints
+ * @return
+ */
+ private List<Constraint> addBandwidthCostTypeConstraints(String bandWidth,
+ String bandWidthType,
+ String costType) {
+ List<Constraint> listConstrnt = new LinkedList<>();
+ //bandwidth
+ double bwValue = 0.0;
+ if (!bandWidth.equals(STRING_NULL)) {
+ bwValue = Double.parseDouble(bandWidth);
+ }
+ if (bandWidthType.equals(BANDWIDTH_TYPE_KBPS)) {
+ bwValue = bwValue * BANDWIDTH_KBPS;
+ } else {
+ bwValue = bwValue * BANDWIDTH_MBPS;
+ }
+
+ //Cost type
+ CostConstraint.Type costTypeVal = null;
+ switch (costType) {
+ case COST_TYPE_IGP:
+ costTypeVal = CostConstraint.Type.COST;
+ break;
+ case COST_TYPE_TE:
+ costTypeVal = CostConstraint.Type.TE_COST;
+ break;
+ default:
+ log.error("Invalid cost type");
+ break;
+ }
+
+ if (bwValue != 0.0) {
+ listConstrnt.add(BandwidthConstraint.of(bwValue, DataRateUnit.valueOf(BANDWIDTH_BPS)));
+ }
+
+ if (costTypeVal != null) {
+ listConstrnt.add(CostConstraint.of(costTypeVal));
+ }
+
+ return listConstrnt;
}
+ /**
+ * Handles the highlights of selected path.
+ */
private void hilightAndSendPaths() {
PceWebLinkMap linkMap = new PceWebLinkMap();
allPathLinks.forEach(linkMap::add);
-
Set<Link> selectedPathLinks;
- selectedPathLinks = paths.isEmpty() ? ImmutableSet.of()
- : ImmutableSet.copyOf(paths.get(pathIndex).links());
+ selectedPathLinks = paths.isEmpty() ?
+ ImmutableSet.of() : ImmutableSet.copyOf(paths.get(pathIndex).links());
Highlights highlights = new Highlights();
if (highlightDelay > 0) {
@@ -261,16 +582,32 @@
sendMessage(TopoJson.highlightsMessage(highlights));
}
+ /**
+ * Handles the addition of badge and highlights.
+ *
+ * @param highlights highlights
+ * @param type device type
+ * @param elemId device to be add badge
+ * @param src device to be add badge
+ * @return
+ */
private Highlights addBadge(Highlights highlights, String type,
String elemId, String src) {
- if (SWITCH.equals(type)) {
+ if (ROUTER.equals(type)) {
highlights = addDeviceBadge(highlights, elemId, src);
- } else if (ENDSTATION.equals(type)) {
- highlights = addHostBadge(highlights, elemId, src);
}
+
return highlights;
}
+ /**
+ * Handles the badge add and highlights.
+ *
+ * @param h highlights
+ * @param elemId device to be add badge
+ * @param type device type
+ * @return highlights
+ */
private Highlights addDeviceBadge(Highlights h, String elemId, String type) {
DeviceHighlight dh = new DeviceHighlight(elemId);
dh.setBadge(createBadge(type));
@@ -278,18 +615,59 @@
return h;
}
- private Highlights addHostBadge(Highlights h, String elemId, String type) {
- HostHighlight hh = new HostHighlight(elemId);
- hh.setBadge(createBadge(type));
- h.add(hh);
- return h;
- }
-
+ /**
+ * Handles the node badge add and highlights.
+ *
+ * @param type device type
+ * @return badge of given node
+ */
private NodeBadge createBadge(String type) {
return NodeBadge.text(type);
}
- //TODO: Listeners need to add.
- //If topology changes then path need to be re calculate.
+ /**
+ * Handles the event of topology listeners.
+ */
+ private class InternalTopologyListener implements TopologyListener {
+ @Override
+ public void event(TopologyEvent event) {
+ highlightDelay = DELAY_MS;
+ findTunnelAndHighlights();
+ highlightDelay = 0;
+ }
+ }
+ /**
+ * Handles the event of tunnel listeners.
+ */
+ private class InnerPceWebTunnelListener implements TunnelListener {
+ @Override
+ public void event(TunnelEvent event) {
+ Tunnel tunnel = event.subject();
+ if (tunnel.type() == MPLS) {
+ highlightDelay = DELAY_MS;
+ findTunnelAndHighlights();
+ highlightDelay = 0;
+ }
+ }
+ }
+
+ /**
+ * Handles the event of topology listeners.
+ */
+ private void findTunnelAndHighlights() {
+ Collection<Tunnel> tunnelSet = null;
+ tunnelSet = tunnelService.queryTunnel(MPLS);
+ for (Tunnel tunnel : tunnelSet) {
+ if (tunnel.path() == null) {
+ log.info("path does not exist");
+ return;
+ }
+ paths.add(tunnel.path());
+ }
+
+ ImmutableSet.Builder<Link> builder = ImmutableSet.builder();
+ allPathLinks = buildPaths(builder).build();
+ hilightAndSendPaths();
+ }
}
diff --git a/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovOverlay.java b/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovOverlay.java
index 087f4bc..41f3243 100644
--- a/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovOverlay.java
+++ b/apps/pce/pceweb/src/main/java/org/onosproject/pceweb/PceWebTopovOverlay.java
@@ -63,7 +63,6 @@
public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) {
pp.title(MY_TITLE);
- log.info("Modify device details called.");
DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
diff --git a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js
index 096f872..e16e15b 100644
--- a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js
+++ b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovDemo.js
@@ -21,16 +21,23 @@
// injected refs
var $log, fs, flash, wss, tps, ns, tds, ds;
-
+ var tunnelNameData, tunnelNameDataRemove;
// constants
var srcMessage = 'pceTopovSetSrc',
dstMessage = 'pceTopovSetDst',
clearMessage = 'pceTopovClear',
- setModemsg = 'pceTopovSetMode',
- L3dev = 'requestIpDevDetails';
+ setPathmsg = 'pceTopovSetMode',
+ updatePathmsgQuery = 'pceTopovUpdateQuery',
+ remPathmsgQuery = 'pceTopovRemQuery',
+ updatePathmsg = 'pceTopovUpdate',
+ remPathmsg = 'pceTopovRem',
+ showTunnelInfoMsg = 'pceTopovShowTunnels',
+ queryDisplayTunnelMsg = 'pceTopovTunnelDisplay',
+ showTunnelInfoRemoveMsg = 'pceTopovShowTunnelsRem';
// internal state
var currentMode = null;
-
+ var handlerMap = {},
+ handlerMapRem = {};
// === ---------------------------
// === Helper functions
@@ -58,153 +65,326 @@
flash.flash('Cleared source and destination');
}
- function dOk() {
- var bandWidth = d3.select('#band-width-box').property("checked");
- var bandValue = null;
- var bandType = null;
-
- if (bandWidth) {
-
- bandValue = d3.select('#band-width-value').property("value");
-
- if (d3.select("#band-kpbs-val").property("checked")) {
- bandType = 'kbps';
- } else if (d3.select('#band-mpbs-val').property("checked")) {
- bandType = 'mbps';
- }
- }
-
- var costType = d3.select('#pce-cost-type').property("checked");
- var costTypeVal = null;
-
- if (costType) {
-
- if (d3.select("#pce-cost-type-igp").property("checked")) {
- costTypeVal = 'igp';
- } else if (d3.select('#pce-cost-type-te').property("checked")) {
- costTypeVal = 'te';
- }
- }
-
- var lspType = d3.select('#pce-lsp-type').property("checked");
- var lspTypeVal = null;
-
- if (lspType) {
-
- if (d3.select("#pce-lsp-type-cr").property("checked")) {
- lspTypeVal = 'cr';
- } else if (d3.select('#pce-lsp-type-srbe').property("checked")) {
- lspTypeVal = 'srbe';
- } else if (d3.select('#pce-lsp-type-srte').property("checked")) {
- lspTypeVal = 'srte';
- }
- }
-
- //TBD: Read the user inputs and need to send the event for calculating the path based on constrainsts.
- // TBD: Need to read IGP cost type and LSP type.
- //wss.sendEvent(setModemsg);
- //flash.flash('creat path message');
-
- $log.debug('Dialog OK button clicked');
- }
-
function dClose() {
$log.debug('Dialog Close button clicked (or Esc pressed)');
}
function createUserText() {
- var content = ds.createDiv();
- var form = content.append('form');
- var p = form.append('p');
+ var content = ds.createDiv('constraints-input'),
+ form = content.append('form'),
+ p = form.append('p');
+
+ function addAttribute(name, id, nameField, type) {
+ p.append('input').attr({
+ type: type,
+ name: name,
+ id: id
+ });
+
+ p.append('span').text(nameField);
+ p.append('br');
+ }
//Add the bandwidth related inputs.
- p.append('input').attr({
- id: 'band-width-box',
- type: 'checkbox',
- name: 'band-width-name'
- });
- p.append('span').text('Band Width');
- p.append('br');
- p.append('input').attr({
- id: 'band-width-value',
- type: 'number',
- name: 'band-width-value-name'
- });
- p.append('input').attr({
- id: 'band-kpbs-val',
- type: 'radio',
- name: 'pce-band-type'
- });
- p.append('span').text('kpbs');
- p.append('input').attr({
- id: 'band-mpbs-val',
- type: 'radio',
- name: 'pce-band-type'
- });
- p.append('span').text('mpbs');
- p.append('br');
-
+ addAttribute('band-width-name', 'band-width-box', 'Band Width', 'checkbox');
+ addAttribute('band-width-value-name', 'band-width-value', null, 'number');
+ addAttribute('pce-band-type', 'band-kpbs-val', 'kbps', 'radio');
+ addAttribute('pce-band-type', 'band-mpbs-val', 'mbps', 'radio');
//Add the cost type related inputs.
- p.append('input').attr({
- id: 'pce-cost-type',
- type: 'checkbox',
- name: 'pce-cost-type-name'
- });
- p.append('span').text('Cost Type');
- p.append('br');
- p.append('input').attr({
- id: 'pce-cost-type-igp',
- type: 'radio',
- name: 'pce-cost-type-valname'
- });
- p.append('span').text('IGP');
- p.append('input').attr({
- id: 'pce-cost-type-te',
- type: 'radio',
- name: 'pce-cost-type-valname'
- });
- p.append('span').text('TE');
- p.append('br');
-
+ addAttribute('pce-cost-type-name', 'pce-cost-type', 'Cost Type', 'checkbox');
+ addAttribute('pce-cost-type-valname', 'pce-cost-type-igp', 'IGP', 'radio');
+ addAttribute('pce-cost-type-valname', 'pce-cost-type-te', 'TE', 'radio');
//Add the LSP type related inputs.
- p.append('input').attr({
- id: 'pce-lsp-type',
- type: 'checkbox',
- name: 'pce-lsp-type-name'
- });
- p.append('span').text('Lsp Type');
- p.append('br');
- p.append('input').attr({
- id: 'pce-lsp-type-cr',
- type: 'radio',
- name: 'pce-lsp-type-valname'
- });
- p.append('span').text('CR');
- p.append('input').attr({
- id: 'pce-lsp-type-srbe',
- type: 'radio',
- name: 'pce-lsp-type-valname'
- });
- p.append('span').text('SR BE');
- p.append('input').attr({
- id: 'pce-lsp-type-srte',
- type: 'radio',
- name: 'pce-lsp-type-valname'
- });
- p.append('span').text('SR TE');
+ addAttribute('pce-lsp-type-name', 'pce-lsp-type', 'Lsp Type', 'checkbox');
+ addAttribute('pce-lsp-type-valname', 'pce-lsp-type-cr', 'WITH SIGNALLING', 'radio');
+ addAttribute('pce-lsp-type-valname', 'pce-lsp-type-srbe', 'WITHOUT SR WITHOUT SIGNALLING', 'radio');
+ addAttribute('pce-lsp-type-valname', 'pce-lsp-type-srte', 'WITH SR WITHOUT SIGNALLING', 'radio');
+ //Add the tunnel name
+ addAttribute('pce-tunnel-name', 'pce-tunnel-name-id', 'Tunnel Name', 'text');
return content;
}
- function setMode() {
+ function createUserTextUpdate(data) {
+ var content = ds.createDiv(),
+ form = content.append('form'),
+ p = form.append('p');
+
+ p.append('span').text('Tunnel IDs');
+ p.append('br');
+
+ data.a.forEach( function (val, idx) {
+ p.append('input').attr({
+ id: 'tunnel-id-'+idx,
+ type: 'radio',
+ name: 'tunnel-id-name',
+ value: val
+ });
+
+ p.append('span').text(val);
+ p.append('br');
+
+ } );
+
+ return content;
+ }
+
+ function createUserTextUpdatePathEvent() {
+ var content = ds.createDiv(),
+ form = content.append('form'),
+ p = form.append('p');
+
+ function addAttribute(name, id, nameField, type) {
+ p.append('input').attr({
+ type: type,
+ name: name,
+ id: id
+ });
+
+ p.append('span').text(nameField);
+ p.append('br');
+ }
+
+ //Add the bandwidth related inputs.
+ addAttribute('band-width-name', 'update-band-width-box', 'Band Width', 'checkbox');
+ addAttribute('band-width-value-name', 'update-band-width-value', null, 'number');
+ addAttribute('pce-band-type', 'update-band-kpbs-val', 'kbps', 'radio');
+ addAttribute('pce-band-type', 'update-band-mpbs-val', 'mbps', 'radio');
+ //Add the cost type related inputs.
+ addAttribute('pce-cost-type', 'update-pce-cost-type', 'Cost Type', 'checkbox');
+ addAttribute('pce-cost-type-value', 'update-pce-cost-type-igp', 'IGP', 'radio');
+ addAttribute('pce-cost-type-value', 'update-pce-cost-type-te', 'TE', 'radio');
+
+ return content;
+ }
+
+ function createUserTextRemove(data) {
+
+ var content = ds.createDiv(),
+ form = content.append('form'),
+ p = form.append('p');
+
+ p.append('span').text('Tunnel IDs');
+ p.append('br');
+
+ data.a.forEach( function (val, idx) {
+ p.append('input').attr({
+ id: 'tunnel-id-remove-'+idx,
+ type: 'checkbox',
+ name: 'tunnel-id-name-remove',
+ value: val
+ });
+
+ p.append('span').text(val);
+ p.append('br');
+ } );
+
+ return content;
+ }
+
+ function isChecked(viewId) {
+ return d3.select('#' + viewId).property('checked');
+ }
+
+ function getCheckedValue(viewId) {
+ return d3.select('#' + viewId).property('value');
+ }
+
+ function showTunnelInformation(data) {
+ wss.unbindHandlers(handlerMap);
+ tunnelNameData = data;
+
+ function dOkUpdate() {
+ var tdString = '' ;
+ tunnelNameData.a.forEach( function (val, idx) {
+ var tunnelName = isChecked('tunnel-id-'+idx);
+ if (tunnelName)
+ {
+ tdString = val;
+ }
+ } );
+
+ if (tdString) {
+ constraintsUpdateDialog(tdString);
+ } else {
+ $log.debug("No tunnel id is selected.");
+ }
+
+ $log.debug('Dialog OK button clicked');
+ }
+
tds.openDialog()
- .setTitle('constraints user')
+ .setTitle('Available LSPs with selected device')
+ .addContent(createUserTextUpdate(data))
+ .addOkChained(dOkUpdate, 'GOTO Selection of constraints')
+ .addCancel(dClose, 'Close')
+ .bindKeys();
+ }
+
+ function constraintsUpdateDialog(tunnelId) {
+
+ // invoked when the OK button is pressed on this dialog
+ function dOkUpdateEvent() {
+ $log.debug('Select constraints for update path Dialog OK button pressed');
+
+ var bandWidth = isChecked('update-band-width-box'),
+ bandValue = null,
+ bandType = null;
+
+ if (bandWidth) {
+ bandValue = d3.select('#update-band-width-value');
+
+ if (isChecked('update-band-kpbs-val')) {
+ bandType = 'kbps';
+ } else if (isChecked('update-band-mpbs-val')) {
+ bandType = 'mbps';
+ }
+ }
+
+ var costType = isChecked('update-pce-cost-type'),
+ costTypeVal = null;
+
+ if (costType) {
+ if (isChecked('update-pce-cost-type-igp')) {
+ costTypeVal = 'igp';
+ } else if (isChecked('update-pce-cost-type-te')) {
+ costTypeVal = 'te';
+ }
+ }
+
+ wss.sendEvent(updatePathmsg, {
+ bw: bandValue,
+ ctype: costTypeVal,
+ tunnelname: tunnelId
+ });
+
+ flash.flash('update path message');
+
+ }
+
+ tds.openDialog()
+ .setTitle('Select constraints for update path')
+ .addContent(createUserTextUpdatePathEvent())
+ .addCancel()
+ .addOk(dOkUpdateEvent, 'Update Path') // NOTE: NOT the "chained" version!
+ .bindKeys();
+
+ }
+
+ function showTunnelInformationRemove(data) {
+
+ wss.unbindHandlers(handlerMapRem);
+ tunnelNameDataRemove = data;
+ tds.openDialog()
+ .setTitle('Available Tunnels for remove')
+ .addContent(createUserTextRemove(data))
+ .addOk(dOkRemove, 'Remove')
+ .addCancel(dClose, 'Close')
+ .bindKeys();
+ }
+
+ //setup path
+ function setMode() {
+
+ function dOk() {
+ var bandWidth = isChecked('band-width-box'),
+ bandValue = null,
+ bandType = null;
+
+ if (bandWidth) {
+ bandValue = getCheckedValue('band-width-value');
+
+ if (isChecked('band-kpbs-val')) {
+ bandType = 'kbps';
+ } else if (isChecked('band-mpbs-val')) {
+ bandType = 'mbps';
+ }
+ }
+
+ var costType = isChecked('pce-cost-type'),
+ costTypeVal = null;
+
+ if (costType) {
+ if (isChecked('pce-cost-type-igp')) {
+ costTypeVal = 'igp';
+ } else if (isChecked('pce-cost-type-te')) {
+ costTypeVal = 'te';
+ }
+ }
+
+ var lspType = isChecked('pce-lsp-type'),
+ lspTypeVal = null;
+
+ if (lspType) {
+ if (isChecked('pce-lsp-type-cr')) {
+ lspTypeVal = 'cr';
+ } else if (isChecked('pce-lsp-type-srbe')) {
+ lspTypeVal = 'srbe';
+ } else if (isChecked('pce-lsp-type-srte')) {
+ lspTypeVal = 'srte';
+ }
+ }
+
+ wss.sendEvent(setPathmsg, {
+ bw: bandValue,
+ bwtype: bandType,
+ ctype: costTypeVal,
+ lsptype: lspTypeVal,
+ tunnelname: getCheckedValue('pce-tunnel-name-id')
+ });
+
+ flash.flash('create path message');
+ $log.debug('Dialog OK button clicked');
+ }
+
+ tds.openDialog()
+ .setTitle('constraints selection')
.addContent(createUserText())
.addOk(dOk, 'OK')
.addCancel(dClose, 'Close')
.bindKeys();
}
+ function updatePath(node) {
+
+ wss.sendEvent(updatePathmsgQuery, {
+ srid: node[0],
+ dsid: node[1]
+ });
+
+ handlerMap[showTunnelInfoMsg] = showTunnelInformation;
+ wss.bindHandlers(handlerMap);
+
+ flash.flash('update path message');
+ }
+
+ function dOkRemove() {
+
+ tunnelNameDataRemove.a.forEach( function (val, idx) {
+ var tunnelNameVal = isChecked('tunnel-id-remove-'+idx);
+ if (tunnelNameVal) {
+ wss.sendEvent(remPathmsg, {
+ tunnelid: val
+ });
+ }
+ } );
+
+ flash.flash('remove path message');
+ }
+
+ function remPath(node) {
+ wss.sendEvent(remPathmsgQuery, {
+ srid: node[0],
+ dsid: node[1]
+ });
+
+ handlerMapRem[showTunnelInfoRemoveMsg] = showTunnelInformationRemove;
+ wss.bindHandlers(handlerMapRem);
+ }
+
+ function queryTunnelDisplay() {
+ wss.sendEvent(queryDisplayTunnelMsg);
+ }
// === ---------------------------
// === Module Factory Definition
@@ -227,8 +407,10 @@
setSrc: setSrc,
setDst: setDst,
clear: clear,
- setMode: setMode
-
+ setMode: setMode,
+ updatePath: updatePath,
+ remPath: remPath,
+ queryTunnelDisplay: queryTunnelDisplay
};
}]);
}());
diff --git a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovOverlay.js b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovOverlay.js
index 63a4d2d..4ad40a0 100644
--- a/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovOverlay.js
+++ b/apps/pce/pceweb/src/main/resources/app/view/pcewebTopov/pcewebTopovOverlay.js
@@ -34,7 +34,6 @@
glyphId: 'topo',
tooltip: 'PCE web Topo Overlay',
-
activate: function () {
$log.debug("PCE web topology overlay ACTIVATED");
},
@@ -112,11 +111,32 @@
},
1: {
cb: function () {
- pps.setMode("shortest");
+ pps.setMode();
},
- tt: 'Select constraints for LSP',
+ tt: 'Setup path',
+ gid: 'plus'
+ },
+ 2: {
+ cb: function () {
+ pps.updatePath(selection);
+ },
+ tt: 'Update path',
gid: '*jp'
},
+ 3: {
+ cb: function () {
+ pps.remPath(selection);
+ },
+ tt: 'Remove path',
+ gid: 'minus'
+ },
+ 4: {
+ cb: function () {
+ pps.queryTunnelDisplay();
+ },
+ tt: 'Show Tunnels',
+ gid: 'checkMark'
+ },
0: {
cb: function () {
pps.clear();
@@ -126,7 +146,7 @@
},
_keyOrder: [
- 'openBracket', 'closeBracket', '1', '0'
+ 'openBracket', 'closeBracket', '1', '2', '3', '4', '0'
]
},
hooks: {
@@ -145,6 +165,9 @@
},
single: function (data) {
selectionCallback(data);
+ },
+ multi: function (selectOrder) {
+ selectionCallback(selectOrder);
}
}
};
diff --git a/apps/pce/pom.xml b/apps/pce/pom.xml
index 7ba4bca..e6e6163 100644
--- a/apps/pce/pom.xml
+++ b/apps/pce/pom.xml
@@ -21,6 +21,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-apps</artifactId>
<version>1.6.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/protocols/bgp/api/pom.xml b/protocols/bgp/api/pom.xml
old mode 100755
new mode 100644
index af2c2d0..e2241c8
--- a/protocols/bgp/api/pom.xml
+++ b/protocols/bgp/api/pom.xml
@@ -23,6 +23,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-bgp</artifactId>
<version>1.6.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-bgp-api</artifactId>
diff --git a/protocols/bgp/bgpio/pom.xml b/protocols/bgp/bgpio/pom.xml
old mode 100755
new mode 100644
index f351205..74a53d5
--- a/protocols/bgp/bgpio/pom.xml
+++ b/protocols/bgp/bgpio/pom.xml
@@ -23,6 +23,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-bgp</artifactId>
<version>1.6.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-bgpio</artifactId>
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
index 4c3d4a1..7062a7d 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/ver4/BgpUpdateMsgVer4.java
@@ -241,12 +241,11 @@
afi = mpUnReach.afi();
safi = mpUnReach.safi();
}
+ }
- if ((afi == Constants.AFI_FLOWSPEC_VALUE) && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
- || (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
- //unfeasible route length
- cb.writeShort(0);
- }
+ if ((afi == Constants.AFI_FLOWSPEC_VALUE) || (afi == Constants.AFI_VALUE)) {
+ //unfeasible route length
+ cb.writeShort(0);
}
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java
index 19f3126..d766f0d 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/As4Path.java
@@ -171,15 +171,17 @@
if ((as4pathSet != null) && (as4pathSeq != null)) {
int iAsLenIndex = cb.writerIndex();
cb.writeByte(0);
- cb.writeByte(AsPath.ASPATH_SEQ_TYPE);
- cb.writeByte(as4pathSeq.size());
+ if (as4pathSeq.size() != 0) {
+ cb.writeByte(AsPath.ASPATH_SEQ_TYPE);
+ cb.writeByte(as4pathSeq.size());
- for (int j = 0; j < as4pathSeq.size(); j++) {
- cb.writeInt(as4pathSeq.get(j));
+ for (int j = 0; j < as4pathSeq.size(); j++) {
+ cb.writeInt(as4pathSeq.get(j));
+ }
+
+ int asLen = cb.writerIndex() - iAsLenIndex;
+ cb.setByte(iAsLenIndex, (byte) (asLen - 1));
}
-
- int asLen = cb.writerIndex() - iAsLenIndex;
- cb.setByte(iAsLenIndex, (byte) (asLen - 1));
} else {
cb.writeByte(0);
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java
index 2c0f0b8..f6442d9 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/AsPath.java
@@ -208,15 +208,16 @@
if (isaspathSet()) {
int iAsLenIndex = cb.writerIndex();
cb.writeByte(0);
- cb.writeByte(ASPATH_SEQ_TYPE);
- cb.writeByte(aspathSeq.size());
+ if (aspathSeq.size() != 0) {
+ cb.writeByte(ASPATH_SEQ_TYPE);
+ cb.writeByte(aspathSeq.size());
- for (int j = 0; j < aspathSeq.size(); j++) {
- cb.writeShort(aspathSeq.get(j));
+ for (int j = 0; j < aspathSeq.size(); j++) {
+ cb.writeShort(aspathSeq.get(j));
+ }
+ int asLen = cb.writerIndex() - iAsLenIndex;
+ cb.setByte(iAsLenIndex, (byte) (asLen - 1));
}
-
- int asLen = cb.writerIndex() - iAsLenIndex;
- cb.setByte(iAsLenIndex, (byte) (asLen - 1));
} else {
cb.writeByte(0);
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java
index 0367f24..e6ba8b7 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/LinkStateAttributes.java
@@ -106,7 +106,7 @@
*
* @param linkStateAttribList Linked list of Link, Node and Prefix TLVs
*/
- LinkStateAttributes(List<BgpValueType> linkStateAttribList) {
+ public LinkStateAttributes(List<BgpValueType> linkStateAttribList) {
this.linkStateAttribList = linkStateAttribList;
this.isLinkStateAttribute = true;
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityAttrHeader.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityAttrHeader.java
index 47e1014..e49ef71 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityAttrHeader.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityAttrHeader.java
@@ -163,7 +163,6 @@
c.writeShort(TYPE);
c.writeByte(flag);
c.writeByte(hopCount);
- c.writeShort(length);
return c.writerIndex() - iLenStartIndex;
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityIpV4Neighbour.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityIpV4Neighbour.java
index 92464f4..5fc16cc 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityIpV4Neighbour.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/WideCommunityIpV4Neighbour.java
@@ -97,8 +97,8 @@
while (listIterator.hasNext()) {
IpV4Neighbour speaker = listIterator.next();
if (speaker instanceof IpV4Neighbour) {
- c.writeInt(Integer.valueOf(speaker.localSpeaker.toString()));
- c.writeInt(Integer.valueOf(speaker.remoteSpeaker.toString()));
+ c.writeBytes(speaker.localSpeaker().toOctets());
+ c.writeBytes(speaker.remoteSpeaker().toOctets());
}
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidth.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidth.java
index 4d74702..3cc4bc6 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidth.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMaxLinkBandwidth.java
@@ -96,7 +96,7 @@
*
* @return Maximum link bandwidth
*/
- float linkAttrMaxLinkBandwidth() {
+ public float linkAttrMaxLinkBandwidth() {
return maxBandwidth;
}
diff --git a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/WideCommunity.java b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/WideCommunity.java
index 25afd95..1867959 100644
--- a/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/WideCommunity.java
+++ b/protocols/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/WideCommunity.java
@@ -43,10 +43,10 @@
public class WideCommunity implements BgpValueType {
private static final Logger log = LoggerFactory.getLogger(WideCommunity.class);
- public static final byte TYPE = (byte) 254; /* TODO: IANA Assigned */
+ public static final byte TYPE = (byte) 129;
public static final short LENGTH = 4;
public static final byte TYPE_LENGTH_SIZE = 3;
- public static final byte FLAGS = (byte) 0x40;
+ public static final byte FLAGS = (byte) 0x90;
private WideCommunityAttrHeader wideCommunityHeader;
private int community;
private int localAsn;
@@ -238,6 +238,9 @@
wideCommunityHeader.write(c);
+ int iComLengthIndex = c.writerIndex();
+ c.writeShort(0);
+
c.writeInt(community);
c.writeInt(localAsn);
c.writeInt(contextAsn);
@@ -275,6 +278,9 @@
c.setShort(iTargetLenIndex, (short) (length - 2));
}
+ length = c.writerIndex() - iComLengthIndex;
+ c.setShort(iComLengthIndex, (short) (length - 2));
+
length = c.writerIndex() - iLengthIndex;
c.setShort(iLengthIndex, (short) (length - 2));
diff --git a/protocols/bgp/ctl/pom.xml b/protocols/bgp/ctl/pom.xml
old mode 100755
new mode 100644
index 3df6fb0..bf4fa61
--- a/protocols/bgp/ctl/pom.xml
+++ b/protocols/bgp/ctl/pom.xml
@@ -46,6 +46,11 @@
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-common</artifactId>
+ <version>4.0.36.Final</version>
+ </dependency>
</dependencies>
<build>
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
old mode 100755
new mode 100644
index bbeea48..a0bac3e
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
@@ -205,7 +205,7 @@
lspeer.setSelfInnitConnection(true);
if (lspeer.connectPeer() == null) {
- connectPeer = new BgpConnectPeerImpl(bgpController, routerid, Controller.getBgpPortNum());
+ connectPeer = new BgpConnectPeerImpl(bgpController, routerid, Controller.BGP_PORT_NUM);
lspeer.setConnectPeer(connectPeer);
connectPeer.connectPeer();
}
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java
old mode 100755
new mode 100644
index 4f2735f..aef8055
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java
@@ -135,7 +135,7 @@
BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
// Compare local RIB entry with the current attribute
decisionResult = selectionAlgo.compare(nodeTree.get(nodeLsIdentifier), detailsLocRib);
- if (decisionResult < 0) {
+ if (decisionResult <= 0) {
for (BgpNodeListener l : bgpController.listener()) {
l.addNode((BgpNodeLSNlriVer4) nlri, details);
}
@@ -155,7 +155,7 @@
BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
// Compare local RIB entry with the current attribute
decisionResult = selectionAlgo.compare(linkTree.get(linkLsIdentifier), detailsLocRib);
- if (decisionResult < 0) {
+ if (decisionResult <= 0) {
linkTree.replace(linkLsIdentifier, detailsLocRib);
for (BgpLinkListener l : bgpController.linkListener()) {
l.addLink((BgpLinkLsNlriVer4) nlri, details);
@@ -175,7 +175,7 @@
BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
// Compare local RIB entry with the current attribute
decisionResult = selectionAlgo.compare(prefixTree.get(prefixIdentifier), detailsLocRib);
- if (decisionResult < 0) {
+ if (decisionResult <= 0) {
prefixTree.replace(prefixIdentifier, detailsLocRib);
log.debug("Local RIB update prefix: {}", detailsLocRib.toString());
}
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
index 3d14465..02a4321 100644
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
@@ -159,15 +159,16 @@
* Send flow specification update message to peer.
*
* @param operType operation type
+ * @param routeKey flow rule key
* @param flowSpec flow specification details
- * @param wideCommunity for route policy
+ * @param wideCommunity for route policy
*/
public final void sendFlowSpecUpdateMessageToPeer(FlowSpecOperation operType, BgpFlowSpecRouteKey routeKey,
BgpFlowSpecNlri flowSpec, WideCommunity wideCommunity) {
List<BgpValueType> attributesList = new LinkedList<>();
byte sessionType = sessionInfo.isIbgpSession() ? (byte) 0 : (byte) 1;
- byte sAfi = Constants.VPN_SAFI_FLOWSPEC_VALUE;
+ byte sAfi = Constants.SAFI_FLOWSPEC_VALUE;
boolean isFsCapabilitySet = isCapabilitySupported(MultiProtocolExtnCapabilityTlv.TYPE,
Constants.AFI_FLOWSPEC_VALUE,
@@ -190,10 +191,10 @@
return;
}
- if ((wideCommunity != null) && (isVpnRpdCapabilitySet)) {
- sAfi = Constants.VPN_SAFI_FLOWSPEC_RDP_VALUE;
- } else if (isVpnFsCapabilitySet) {
+ if (isVpnFsCapabilitySet) {
sAfi = Constants.VPN_SAFI_FLOWSPEC_VALUE;
+ } else if (isVpnRpdCapabilitySet) {
+ sAfi = Constants.VPN_SAFI_FLOWSPEC_RDP_VALUE;
}
attributesList.add(new Origin((byte) 0));
@@ -222,7 +223,9 @@
}
attributesList.add(new BgpExtendedCommunity(flowSpec.fsActionTlv()));
- attributesList.add(wideCommunity);
+ if (wideCommunity != null) {
+ attributesList.add(wideCommunity);
+ }
if (operType == FlowSpecOperation.ADD) {
attributesList.add(new MpReachNlri(flowSpec, Constants.AFI_FLOWSPEC_VALUE, sAfi));
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java
old mode 100755
new mode 100644
index 32f03f9..72f803d
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java
@@ -16,7 +16,7 @@
package org.onosproject.bgp.controller.impl;
import static org.onlab.util.Tools.groupedThreads;
-
+import io.netty.util.internal.PlatformDependent;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.InetSocketAddress;
@@ -53,9 +53,11 @@
public Channel serverChannel;
// Configuration options
- private static final short BGP_PORT_NUM = 179;
+ protected static final short BGP_PORT_NUM = 179;
+ private static final short BGP_PRIVILEGED_PORT = 1790; // server port used for non root users in linux
private static final short PORT_NUM_ZERO = 0;
private static boolean isPortNumSet = false;
+ private static short portNumber = BGP_PORT_NUM;
private final int workerThreads = 16;
private final int peerWorkerThreads = 16;
@@ -219,6 +221,11 @@
*/
public void start() {
log.info("Started");
+ if (!PlatformDependent.isWindows() && !PlatformDependent.isRoot()) {
+ portNumber = BGP_PRIVILEGED_PORT;
+ } else {
+ portNumber = BGP_PORT_NUM;
+ }
this.init();
this.run();
}
@@ -242,7 +249,8 @@
if (isPortNumSet) {
return PORT_NUM_ZERO;
}
- return BGP_PORT_NUM;
+
+ return portNumber;
}
/**
diff --git a/protocols/pcep/api/BUCK b/protocols/pcep/api/BUCK
index ae80b3a..5ced968 100644
--- a/protocols/pcep/api/BUCK
+++ b/protocols/pcep/api/BUCK
@@ -1,6 +1,8 @@
COMPILE_DEPS = [
'//lib:CORE_DEPS',
'//protocols/pcep/pcepio:onos-protocols-pcep-pcepio',
+ '//apps/pcep-api:onos-apps-pcep-api',
+ '//incubator/api:onos-incubator-api',
]
osgi_jar_with_tests (
diff --git a/protocols/pcep/api/pom.xml b/protocols/pcep/api/pom.xml
index 5563eae..7903b98 100644
--- a/protocols/pcep/api/pom.xml
+++ b/protocols/pcep/api/pom.xml
@@ -23,6 +23,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-pcep-controller</artifactId>
<version>1.6.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-pcep-controller-api</artifactId>
@@ -51,5 +52,9 @@
<groupId>org.onosproject</groupId>
<artifactId>onlab-misc</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-incubator-api</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/ClientCapability.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/ClientCapability.java
index e2b5092..e9cafef 100644
--- a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/ClientCapability.java
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/ClientCapability.java
@@ -26,6 +26,8 @@
private boolean pceccCapability;
private boolean statefulPceCapability;
private boolean pcInstantiationCapability;
+ private boolean labelStackCapability;
+ private boolean srCapability;
/**
* Creates new instance of client capability.
@@ -33,11 +35,34 @@
* @param pceccCapability represents PCECC capability
* @param statefulPceCapability represents stateful PCE capability
* @param pcInstantiationCapability represents PC initiation capability
+ * @param labelStackCapability represents S bit is set in PCECC capability
+ * @param srCapability represents SR capability
*/
- public ClientCapability(boolean pceccCapability, boolean statefulPceCapability, boolean pcInstantiationCapability) {
+ public ClientCapability(boolean pceccCapability, boolean statefulPceCapability, boolean pcInstantiationCapability,
+ boolean labelStackCapability, boolean srCapability) {
this.pceccCapability = pceccCapability;
this.statefulPceCapability = statefulPceCapability;
this.pcInstantiationCapability = pcInstantiationCapability;
+ this.labelStackCapability = labelStackCapability;
+ this.srCapability = srCapability;
+ }
+
+ /**
+ * Obtains label stack capability.
+ *
+ * @return true if client supports PCECC capability with S bit set otherwise false
+ */
+ public boolean labelStackCapability() {
+ return labelStackCapability;
+ }
+
+ /**
+ * Obtains segment routing capability.
+ *
+ * @return true if client supports SR capability otherwise false
+ */
+ public boolean srCapability() {
+ return srCapability;
}
/**
@@ -69,7 +94,8 @@
@Override
public int hashCode() {
- return Objects.hash(pceccCapability, statefulPceCapability, pcInstantiationCapability);
+ return Objects.hash(pceccCapability, statefulPceCapability, pcInstantiationCapability, labelStackCapability,
+ srCapability);
}
@Override
@@ -81,7 +107,9 @@
ClientCapability other = (ClientCapability) obj;
return Objects.equals(pceccCapability, other.pceccCapability)
&& Objects.equals(statefulPceCapability, other.statefulPceCapability)
- && Objects.equals(pcInstantiationCapability, other.pcInstantiationCapability);
+ && Objects.equals(pcInstantiationCapability, other.pcInstantiationCapability)
+ && Objects.equals(labelStackCapability, other.labelStackCapability)
+ && Objects.equals(srCapability, other.srCapability);
}
return false;
}
@@ -92,6 +120,8 @@
.add("pceccCapability", pceccCapability)
.add("statefulPceCapability", statefulPceCapability)
.add("pcInstantiationCapability", pcInstantiationCapability)
+ .add("labelStackCapability", labelStackCapability)
+ .add("srCapability", srCapability)
.toString();
}
}
\ No newline at end of file
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/LspKey.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/LspKey.java
new file mode 100644
index 0000000..5dee845
--- /dev/null
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/LspKey.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pcep.controller;
+
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Representation of LSP info, it will be unique for each LSP.
+ */
+public class LspKey {
+ private int plspId;
+ private short localLspId;
+
+ /**
+ * Creates new instance of LspInfo.
+ *
+ * @param plspId LSP id assigned per tunnel per session
+ * @param localLspId LSP id assigned per tunnel
+ */
+ public LspKey(int plspId, short localLspId) {
+ this.plspId = plspId;
+ this.localLspId = localLspId;
+ }
+
+ /**
+ * Obtains PLSP id.
+ *
+ * @return LSP id assigned per tunnel per session
+ */
+ public int plspId() {
+ return plspId;
+ }
+
+ /**
+ * Obtains local LSP id.
+ *
+ * @return LSP id assigned per tunnel
+ */
+ public short localLspId() {
+ return localLspId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(plspId, localLspId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof LspKey) {
+ LspKey other = (LspKey) obj;
+ return Objects.equals(plspId, other.plspId)
+ && Objects.equals(localLspId, other.localLspId);
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("plspId", plspId)
+ .add("localLspId", localLspId)
+ .toString();
+ }
+}
\ No newline at end of file
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java
index afeeae8..c5cf003 100644
--- a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClient.java
@@ -19,6 +19,7 @@
import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepStateReport;
/**
* Represents to provider facing side of a path computation client(pcc).
@@ -135,4 +136,64 @@
* @return capability supported by client
*/
ClientCapability capability();
+
+ /**
+ * Adds PCEP device when session is successfully established.
+ *
+ * @param pc PCEP client details
+ */
+ void addNode(PcepClient pc);
+
+ /**
+ * Removes PCEP device when session is disconnected.
+ *
+ * @param pccId PCEP client ID
+ */
+ void deleteNode(PccId pccId);
+
+ /**
+ * Sets D flag for the given LSP and its LSP info.
+ *
+ * @param lspKey contains LSP info
+ * @param dFlag delegation flag in LSP object
+ */
+ void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag);
+
+ /**
+ * Returns delegation flag for the given LSP info.
+ *
+ * @param lspKey contains LSP info
+ * @return delegation flag
+ */
+ Boolean delegationInfo(LspKey lspKey);
+
+ /**
+ * Creates a temporary cache to hold report messages received during LSPDB sync.
+ *
+ * @param pccId PCC id which is the key to store report messages
+ */
+ void initializeSyncMsgList(PccId pccId);
+
+ /**
+ * Returns the list of report messages received during LSPDB sync.
+ *
+ * @param pccId PCC id which is the key for all the report messages
+ * @return list of report messages received during LSPDB sync
+ */
+ List<PcepStateReport> getSyncMsgList(PccId pccId);
+
+ /**
+ * Removes the list of report messages received during LSPDB sync.
+ *
+ * @param pccId PCC id which is the key for all the report messages
+ */
+ void removeSyncMsgList(PccId pccId);
+
+ /**
+ * Adds report message received during LSPDB sync into temporary cache.
+ *
+ * @param pccId PCC id which is the key to store report messages
+ * @param rptMsg the report message to be stored
+ */
+ void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg);
}
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientController.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientController.java
index befc3f0..0f14778 100644
--- a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientController.java
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepClientController.java
@@ -57,7 +57,7 @@
void removeListener(PcepClientListener listener);
/**
- * Register a listener for OF msg events.
+ * Register a listener for PCEP msg events.
*
* @param listener the listener to notify
*/
@@ -71,6 +71,34 @@
void removeEventListener(PcepEventListener listener);
/**
+ * Register a listener for PCEP msg events[carrying node descriptor details].
+ *
+ * @param listener the listener to notify
+ */
+ void addNodeListener(PcepNodeListener listener);
+
+ /**
+ * Unregister a listener.
+ *
+ * @param listener the listener to be unregistered
+ */
+ void removeNodeListener(PcepNodeListener listener);
+
+ /**
+ * Register a listener for packet events.
+ *
+ * @param listener the listener to notify
+ */
+ void addPacketListener(PcepPacketListener listener);
+
+ /**
+ * Unregister a packet listener.
+ *
+ * @param listener the listener to unregister
+ */
+ void removePacketListener(PcepPacketListener listener);
+
+ /**
* Send a message to a particular pcc client.
*
* @param pccId the id of the client to send message.
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepEventListener.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepEventListener.java
index 7ba8ca7..c7c347a 100644
--- a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepEventListener.java
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepEventListener.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.pcep.controller;
+import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.pcepio.protocol.PcepMessage;
/**
* Notifies providers about PCEP message events.
@@ -28,4 +29,21 @@
* @param msg the message
*/
void handleMessage(PccId pccId, PcepMessage msg);
+
+ /**
+ * Handles end of LSPDB sync actions.
+ *
+ * @param tunnel the tunnel on which action needs to be taken
+ * @param endOfSyncAction the action that needs to be taken for the tunnel
+ */
+ void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction);
+
+ /**
+ * Handles sending PCEP message to client on end of LSPDB sync.
+ *
+ * @param pccId id of the pcc
+ * @param msg the message to be sent
+ * @param endOfSyncAction the action that needs to be taken in the message
+ */
+ void handleEndOfSyncAction(PccId pccId, PcepMessage msg, PcepLspSyncAction endOfSyncAction);
}
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepLspSyncAction.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepLspSyncAction.java
new file mode 100644
index 0000000..92ce8e6
--- /dev/null
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepLspSyncAction.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pcep.controller;
+
+/**
+ * Representation of actions to be taken for LSPs on end of LSP-DB sync.
+ */
+public enum PcepLspSyncAction {
+
+ /**
+ * Specifies that delete message for PCE intiiated tunnel should be sent.
+ */
+ SEND_DELETE(0),
+
+ /**
+ * Specifies that update message should be sent.
+ */
+ SEND_UPDATE(1),
+
+ /**
+ * Specifies that the tunnel should be removed from PCE.
+ */
+ REMOVE(2),
+
+ /**
+ * Specifies that the status of the tunnel should be set as unstable.
+ */
+ UNSTABLE(3);
+
+ int value;
+
+ /**
+ * Assigns val with the value for actions to be taken for LSPs on end of LSP-DB sync.
+ *
+ * @param val sync status
+ */
+ PcepLspSyncAction(int val) {
+ value = val;
+ }
+}
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepNodeListener.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepNodeListener.java
new file mode 100644
index 0000000..a02a744
--- /dev/null
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepNodeListener.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pcep.controller;
+
+/**
+ * Notifies providers about PCEP node events.
+ */
+public interface PcepNodeListener {
+
+ /**
+ * Notifies that the node was added.
+ *
+ * @param pc PCEP client details
+ */
+ void addNode(PcepClient pc);
+
+ /**
+ * Notifies that the node was removed.
+ *
+ * @param pccId PCEP client ID
+ */
+ void deleteNode(PccId pccId);
+}
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepPacketListener.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepPacketListener.java
new file mode 100644
index 0000000..c2017ae
--- /dev/null
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/PcepPacketListener.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pcep.controller;
+
+public interface PcepPacketListener {
+
+ void sendPacketIn(PccId pccId);
+
+}
diff --git a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepAgent.java b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepAgent.java
old mode 100755
new mode 100644
index 2dc3e75..55d5614
--- a/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepAgent.java
+++ b/protocols/pcep/api/src/main/java/org/onosproject/pcep/controller/driver/PcepAgent.java
@@ -60,4 +60,25 @@
*/
void processPcepMessage(PccId pccId, PcepMessage m);
+ /**
+ * Adds PCEP device when session is successfully established.
+ *
+ * @param pc PCEP client details
+ */
+ void addNode(PcepClient pc);
+
+ /**
+ * Removes PCEP device when session is disconnected.
+ *
+ * @param pccId PCEP client ID
+ */
+ void deleteNode(PccId pccId);
+
+ /**
+ * Analyzes report messages received during LSP DB sync again tunnel store and takes necessary actions.
+ *
+ * @param pccId the id of pcc client
+ * @return success or failure
+ */
+ boolean analyzeSyncMsgList(PccId pccId);
}
diff --git a/protocols/pcep/ctl/BUCK b/protocols/pcep/ctl/BUCK
index dd7e29c..ae62881 100644
--- a/protocols/pcep/ctl/BUCK
+++ b/protocols/pcep/ctl/BUCK
@@ -2,6 +2,7 @@
'//lib:CORE_DEPS',
'//protocols/pcep/pcepio:onos-protocols-pcep-pcepio',
'//protocols/pcep/api:onos-protocols-pcep-api',
+ '//incubator/api:onos-incubator-api',
]
osgi_jar_with_tests (
diff --git a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java
index 744731f..bbad497 100644
--- a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java
+++ b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepChannelHandler.java
@@ -55,6 +55,7 @@
import org.onosproject.pcepio.types.IPv4RouterIdOfLocalNodeSubTlv;
import org.onosproject.pcepio.types.NodeAttributesTlv;
import org.onosproject.pcepio.types.PceccCapabilityTlv;
+import org.onosproject.pcepio.types.SrPceCapabilityTlv;
import org.onosproject.pcepio.types.StatefulPceCapabilityTlv;
import org.onosproject.pcepio.types.PcepErrorDetailInfo;
import org.onosproject.pcepio.types.PcepValueType;
@@ -260,6 +261,8 @@
disconnectDuplicate(h);
} else {
h.setState(ESTABLISHED);
+ //Session is established, add a PCEP device
+ h.addNode();
}
}
}
@@ -469,6 +472,20 @@
}
/**
+ * Adds PCEP device once session is established.
+ */
+ private void addNode() {
+ pc.addNode(pc);
+ }
+
+ /**
+ * Deletes PCEP device when session is disconnected.
+ */
+ private void deleteNode() {
+ pc.deleteNode(pc.getPccId());
+ }
+
+ /**
* Return a string describing this client based on the already available
* information (ip address and/or remote socket).
*
@@ -523,6 +540,8 @@
boolean pceccCapability = false;
boolean statefulPceCapability = false;
boolean pcInstantiationCapability = false;
+ boolean labelStackCapability = false;
+ boolean srCapability = false;
ListIterator<PcepValueType> listIterator = tlvList.listIterator();
while (listIterator.hasNext()) {
@@ -531,6 +550,9 @@
switch (tlv.getType()) {
case PceccCapabilityTlv.TYPE:
pceccCapability = true;
+ if (((PceccCapabilityTlv) tlv).sBit()) {
+ labelStackCapability = true;
+ }
break;
case StatefulPceCapabilityTlv.TYPE:
statefulPceCapability = true;
@@ -539,11 +561,15 @@
pcInstantiationCapability = true;
}
break;
+ case SrPceCapabilityTlv.TYPE:
+ srCapability = true;
+ break;
default:
continue;
}
}
- this.capability = new ClientCapability(pceccCapability, statefulPceCapability, pcInstantiationCapability);
+ this.capability = new ClientCapability(pceccCapability, statefulPceCapability, pcInstantiationCapability,
+ labelStackCapability, srCapability);
}
/**
@@ -563,6 +589,8 @@
*/
private void sendErrMsgAndCloseChannel() {
// TODO send error message
+ //Remove PCEP device from topology
+ deleteNode();
channel.close();
}
diff --git a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java
index 1f58bed..20c2856 100644
--- a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java
+++ b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientControllerImpl.java
@@ -15,34 +15,66 @@
*/
package org.onosproject.pcep.controller.impl;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
+import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.incubator.net.tunnel.TunnelService;
+import org.onosproject.incubator.net.tunnel.Tunnel.State;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcep.controller.PcepClientListener;
import org.onosproject.pcep.controller.PcepEventListener;
+import org.onosproject.pcep.controller.PcepNodeListener;
+import org.onosproject.pcep.controller.PcepPacketListener;
+import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcep.controller.driver.PcepAgent;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
import org.onosproject.pcepio.protocol.PcepError;
import org.onosproject.pcepio.protocol.PcepErrorInfo;
import org.onosproject.pcepio.protocol.PcepErrorMsg;
import org.onosproject.pcepio.protocol.PcepErrorObject;
import org.onosproject.pcepio.protocol.PcepFactory;
+import org.onosproject.pcepio.protocol.PcepInitiateMsg;
+import org.onosproject.pcepio.protocol.PcepLspObject;
import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepReportMsg;
+import org.onosproject.pcepio.protocol.PcepStateReport;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
+import org.onosproject.pcepio.types.SymbolicPathNameTlv;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
+import static org.onosproject.pcep.controller.PcepLspSyncAction.REMOVE;
+import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_UPDATE;
+import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_DELETE;
+import static org.onosproject.pcep.controller.PcepLspSyncAction.UNSTABLE;
import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_TYPE_19;
import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_VALUE_5;
@@ -55,6 +87,9 @@
private static final Logger log = LoggerFactory.getLogger(PcepClientControllerImpl.class);
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
protected ConcurrentHashMap<PccId, PcepClient> connectedClients =
new ConcurrentHashMap<>();
@@ -62,9 +97,23 @@
protected Set<PcepClientListener> pcepClientListener = new HashSet<>();
protected Set<PcepEventListener> pcepEventListener = Sets.newHashSet();
+ protected Set<PcepNodeListener> pcepNodeListener = Sets.newHashSet();
+ protected Set<PcepPacketListener> pcepPacketListener = Sets.newHashSet();
private final Controller ctrl = new Controller();
+ public static final String BANDWIDTH = "bandwidth";
+ public static final String LSP_SIG_TYPE = "lspSigType";
+ public static final String PCC_TUNNEL_ID = "PccTunnelId";
+ public static final String PLSP_ID = "PLspId";
+ public static final String LOCAL_LSP_ID = "localLspId";
+ public static final String PCE_INIT = "pceInit";
+ public static final String COST_TYPE = "costType";
+ public static final String DELEGATE = "delegation";
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected TunnelService tunnelService;
+
@Activate
public void activate() {
ctrl.start(agent);
@@ -112,11 +161,31 @@
}
@Override
+ public void addPacketListener(PcepPacketListener listener) {
+ pcepPacketListener.add(listener);
+ }
+
+ @Override
+ public void removePacketListener(PcepPacketListener listener) {
+ pcepPacketListener.remove(listener);
+ }
+
+ @Override
public void writeMessage(PccId pccId, PcepMessage msg) {
this.getClient(pccId).sendMessage(msg);
}
@Override
+ public void addNodeListener(PcepNodeListener listener) {
+ pcepNodeListener.add(listener);
+ }
+
+ @Override
+ public void removeNodeListener(PcepNodeListener listener) {
+ pcepNodeListener.remove(listener);
+ }
+
+ @Override
public void processClientMessage(PccId pccId, PcepMessage msg) {
PcepClient pc = getClient(pccId);
@@ -162,8 +231,48 @@
case REPORT:
//Only update the listener if respective capability is supported else send PCEP-ERR msg
if (pc.capability().statefulPceCapability()) {
- for (PcepEventListener l : pcepEventListener) {
- l.handleMessage(pccId, msg);
+
+ ListIterator<PcepStateReport> listIterator = ((PcepReportMsg) msg).getStateReportList().listIterator();
+ while (listIterator.hasNext()) {
+ PcepStateReport stateRpt = listIterator.next();
+ if (stateRpt.getLspObject().getSFlag()) {
+ if (pc.lspDbSyncStatus() != PcepSyncStatus.IN_SYNC) {
+ // Initialize LSP DB sync and temporary cache.
+ pc.setLspDbSyncStatus(PcepSyncStatus.IN_SYNC);
+ pc.initializeSyncMsgList(pccId);
+ }
+ // Store stateRpt in temporary cache.
+ pc.addSyncMsgToList(pccId, stateRpt);
+
+ // Don't send to provider as of now.
+ continue;
+ } else {
+ if (pc.lspDbSyncStatus() == PcepSyncStatus.IN_SYNC) {
+ // Set end of LSPDB sync.
+ pc.setLspDbSyncStatus(PcepSyncStatus.SYNCED);
+
+ // Call packet provider to initiate label DB sync (only if PCECC capable).
+ if (pc.capability().pceccCapability()) {
+ pc.setLabelDbSyncStatus(IN_SYNC);
+ for (PcepPacketListener l : pcepPacketListener) {
+ l.sendPacketIn(pccId);
+ }
+ } else {
+ // If label db sync is not to be done, handle end of LSPDB sync actions.
+ agent.analyzeSyncMsgList(pccId);
+ }
+ continue;
+ }
+ }
+
+ // It's a usual report message while sync is not undergoing. So process it immediately.
+ LinkedList<PcepStateReport> llPcRptList = new LinkedList<>();
+ llPcRptList.add(stateRpt);
+ PcepMessage pcReportMsg = pc.factory().buildReportMsg().setStateReportList((llPcRptList))
+ .build();
+ for (PcepEventListener l : pcepEventListener) {
+ l.handleMessage(pccId, pcReportMsg);
+ }
}
} else {
// Send PCEP-ERROR message.
@@ -173,6 +282,8 @@
break;
case LABEL_RANGE_RESERV:
break;
+ case LS_REPORT: //TODO: need to handle LS report to add or remove node
+ break;
case MAX:
break;
case END:
@@ -270,5 +381,176 @@
public void processPcepMessage(PccId pccId, PcepMessage m) {
processClientMessage(pccId, m);
}
+
+ @Override
+ public void addNode(PcepClient pc) {
+ for (PcepNodeListener l : pcepNodeListener) {
+ l.addNode(pc);
+ }
+ }
+
+ @Override
+ public void deleteNode(PccId pccId) {
+ for (PcepNodeListener l : pcepNodeListener) {
+ l.deleteNode(pccId);
+ }
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public boolean analyzeSyncMsgList(PccId pccId) {
+ PcepClient pc = getClient(pccId);
+ /*
+ * PLSP_ID is null while tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by PCC and
+ * in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic path name must be
+ * carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be included in the LSP object in
+ * the LSP State Report (PCRpt) message when during a given PCEP session an LSP is "first" reported to a
+ * PCE. So two separate lists with separate keys are maintained.
+ */
+ Map<LspKey, Tunnel> preSyncLspDbByKey = new HashMap<>();
+ Map<String, Tunnel> preSyncLspDbByName = new HashMap<>();
+
+ // Query tunnel service and fetch all the tunnels with this PCC as ingress.
+ // Organize into two maps, with LSP key if known otherwise with symbolic path name, for quick search.
+ Collection<Tunnel> queriedTunnels = tunnelService.queryTunnel(Tunnel.Type.MPLS);
+ for (Tunnel tunnel : queriedTunnels) {
+ if (((IpTunnelEndPoint) tunnel.src()).ip().equals(pccId.ipAddress())) {
+ String pLspId = tunnel.annotations().value(PLSP_ID);
+ if (pLspId != null) {
+ String localLspId = tunnel.annotations().value(LOCAL_LSP_ID);
+ checkNotNull(localLspId);
+ LspKey lspKey = new LspKey(Integer.valueOf(pLspId), Short.valueOf(localLspId));
+ preSyncLspDbByKey.put(lspKey, tunnel);
+ } else {
+ preSyncLspDbByName.put(tunnel.tunnelName().value(), tunnel);
+ }
+ }
+ }
+
+ List<PcepStateReport> syncStateRptList = pc.getSyncMsgList(pccId);
+ Iterator<PcepStateReport> stateRptListIterator = syncStateRptList.iterator();
+
+ // For every report, fetch PLSP id, local LSP id and symbolic path name from the message.
+ while (syncStateRptList.iterator().hasNext()) {
+ PcepStateReport stateRpt = stateRptListIterator.next();
+ Tunnel tunnel = null;
+
+ PcepLspObject lspObj = stateRpt.getLspObject();
+ ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
+ StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
+ SymbolicPathNameTlv pathNameTlv = null;
+
+ while (listTlvIterator.hasNext()) {
+ PcepValueType tlv = listTlvIterator.next();
+ switch (tlv.getType()) {
+ case StatefulIPv4LspIdentifiersTlv.TYPE:
+ ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
+ break;
+
+ case SymbolicPathNameTlv.TYPE:
+ pathNameTlv = (SymbolicPathNameTlv) tlv;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ LspKey lspKeyOfRpt = new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId());
+ tunnel = preSyncLspDbByKey.get(lspKeyOfRpt);
+ // PCE tunnel is matched with PCRpt LSP. Now delete it from the preSyncLspDb list as the residual
+ // non-matching list will be processed at the end.
+ if (tunnel != null) {
+ preSyncLspDbByKey.remove(lspKeyOfRpt);
+ } else if (pathNameTlv != null) {
+ tunnel = preSyncLspDbByName.get(Arrays.toString(pathNameTlv.getValue()));
+ if (tunnel != null) {
+ preSyncLspDbByName.remove(tunnel.tunnelName());
+ }
+ }
+
+ if (tunnel == null) {
+ // If remove flag is set, and tunnel is not known to PCE, ignore it.
+ if (lspObj.getCFlag() && !lspObj.getRFlag()) {
+ // For initiated LSP, need to send PCInit delete msg.
+ try {
+ PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest()
+ .setLspObject(lspObj).build();
+ LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList
+ = new LinkedList<PcInitiatedLspRequest>();
+ llPcInitiatedLspRequestList.add(releaseLspRequest);
+
+ PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
+ .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
+
+ for (PcepEventListener l : pcepEventListener) {
+ l.handleEndOfSyncAction(pccId, pcInitiateMsg, SEND_DELETE);
+ }
+
+ } catch (PcepParseException e) {
+ log.error("Exception occured while sending initiate delete message {}", e.getMessage());
+ }
+ }
+ continue;
+ }
+
+ if (!lspObj.getCFlag()) {
+ // For learned LSP process both add/update PCRpt.
+ LinkedList<PcepStateReport> llPcRptList = new LinkedList<>();
+ llPcRptList.add(stateRpt);
+ PcepMessage pcReportMsg = pc.factory().buildReportMsg().setStateReportList((llPcRptList))
+ .build();
+
+ for (PcepEventListener l : pcepEventListener) {
+ l.handleMessage(pccId, pcReportMsg);
+ }
+ continue;
+ }
+
+ // Implied that tunnel != null and lspObj.getCFlag() is set
+ // State different for PCC sent LSP and PCE known LSP, send PCUpd msg.
+ State tunnelState = PcepLspStatus
+ .getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
+ if (tunnelState != tunnel.state()) {
+ for (PcepEventListener l : pcepEventListener) {
+ l.handleEndOfSyncAction(tunnel, SEND_UPDATE);
+ }
+ }
+ }
+
+ // Check which tunnels are extra at PCE that were not reported by PCC.
+ Map<Object, Tunnel> preSyncLspDb = (Map) preSyncLspDbByKey;
+ handleResidualTunnels(preSyncLspDb);
+ preSyncLspDbByKey = null;
+
+ preSyncLspDb = (Map) preSyncLspDbByName;
+ handleResidualTunnels(preSyncLspDb);
+ preSyncLspDbByName = null;
+ preSyncLspDb = null;
+
+ pc.removeSyncMsgList(pccId);
+ return true;
+ }
+
+ /*
+ * Go through the tunnels which are known by PCE but were not reported by PCC during LSP DB sync and take
+ * appropriate actions.
+ */
+ private void handleResidualTunnels(Map<Object, Tunnel> preSyncLspDb) {
+ for (Tunnel pceExtraTunnel : preSyncLspDb.values()) {
+ if (pceExtraTunnel.annotations().value(PCE_INIT) == null
+ || "false".equalsIgnoreCase(pceExtraTunnel.annotations().value(PCE_INIT))) {
+ // PCC initiated tunnels should be removed from tunnel store.
+ for (PcepEventListener l : pcepEventListener) {
+ l.handleEndOfSyncAction(pceExtraTunnel, REMOVE);
+ }
+ } else {
+ // PCE initiated tunnels should be initiated again.
+ for (PcepEventListener l : pcepEventListener) {
+ l.handleEndOfSyncAction(pceExtraTunnel, UNSTABLE);
+ }
+ }
+ }
+ }
}
}
diff --git a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java
index 8328f2b..a62a611 100644
--- a/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java
+++ b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepClientImpl.java
@@ -19,13 +19,18 @@
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.jboss.netty.channel.Channel;
import org.onlab.packet.IpAddress;
import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepPacketStats;
import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcep.controller.driver.PcepAgent;
@@ -33,6 +38,7 @@
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepStateReport;
import org.onosproject.pcepio.protocol.PcepVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -66,6 +72,8 @@
private byte deadTime;
private byte sessionId;
private PcepPacketStatsImpl pktStats;
+ private Map<LspKey, Boolean> lspDelegationInfo;
+ private Map<PccId, List<PcepStateReport>> sycRptCache = new HashMap<>();
@Override
public void init(PccId pccId, PcepVersion pcepVersion, PcepPacketStats pktStats) {
@@ -188,7 +196,14 @@
@Override
public void setLabelDbSyncStatus(PcepSyncStatus syncStatus) {
+
+ PcepSyncStatus syncOldStatus = labelDbSyncStatus();
this.labelDbSyncStatus = syncStatus;
+
+ if ((syncOldStatus == PcepSyncStatus.IN_SYNC) && (syncStatus == PcepSyncStatus.SYNCED)) {
+ // Perform end of LSP DB sync actions.
+ this.agent.analyzeSyncMsgList(pccId);
+ }
}
@Override
@@ -203,6 +218,16 @@
}
@Override
+ public void addNode(PcepClient pc) {
+ this.agent.addNode(pc);
+ }
+
+ @Override
+ public void deleteNode(PccId pccId) {
+ this.agent.deleteNode(pccId);
+ }
+
+ @Override
public final boolean connectClient() {
return this.agent.addConnectedClient(pccId, this);
}
@@ -230,6 +255,39 @@
}
@Override
+ public void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag) {
+ lspDelegationInfo.put(lspKey, dFlag);
+ }
+
+ @Override
+ public Boolean delegationInfo(LspKey lspKey) {
+ return lspDelegationInfo.get(lspKey);
+ }
+
+ @Override
+ public void initializeSyncMsgList(PccId pccId) {
+ List<PcepStateReport> rptMsgList = new LinkedList<>();
+ sycRptCache.put(pccId, rptMsgList);
+ }
+
+ @Override
+ public List<PcepStateReport> getSyncMsgList(PccId pccId) {
+ return sycRptCache.get(pccId);
+ }
+
+ @Override
+ public void removeSyncMsgList(PccId pccId) {
+ sycRptCache.remove(pccId);
+ }
+
+ @Override
+ public void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg) {
+ List<PcepStateReport> rptMsgList = sycRptCache.get(pccId);
+ rptMsgList.add(rptMsg);
+ sycRptCache.put(pccId, rptMsgList);
+ }
+
+ @Override
public boolean isOptical() {
return false;
}
diff --git a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepLspStatus.java b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepLspStatus.java
similarity index 94%
rename from providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepLspStatus.java
rename to protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepLspStatus.java
index ef628ed..79ed9fe 100644
--- a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepLspStatus.java
+++ b/protocols/pcep/ctl/src/main/java/org/onosproject/pcep/controller/impl/PcepLspStatus.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.provider.pcep.tunnel.impl;
+package org.onosproject.pcep.controller.impl;
import org.onosproject.incubator.net.tunnel.Tunnel.State;
@@ -51,6 +51,7 @@
* Returns the applicable PCEP LSP status corresponding to ONOS tunnel state.
*
* @param tunnelState ONOS tunnel state
+ * @return LSP status as per protocol
*/
public static PcepLspStatus getLspStatusFromTunnelStatus(State tunnelState) {
@@ -76,6 +77,7 @@
* Returns the applicable ONOS tunnel state corresponding to PCEP LSP status.
*
* @param lspState PCEP LSP status
+ * @return tunnel state
*/
public static State getTunnelStatusFromLspStatus(PcepLspStatus lspState) {
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java
old mode 100755
new mode 100644
index b8e108e..b8d2695
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/PcepBandwidthObject.java
@@ -29,14 +29,14 @@
*
* @return bandwidth value
*/
- int getBandwidth();
+ float getBandwidth();
/**
* Sets bandwidth with specified value.
*
* @param iBandwidth Bandwidth's value
*/
- void setBandwidth(int iBandwidth);
+ void setBandwidth(float iBandwidth);
/**
* Writes the BandwidthObject into channel buffer.
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java
index 3621572..83973b4 100644
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepBandwidthObjectVer1.java
@@ -51,6 +51,7 @@
public static final byte BANDWIDTH_OBJ_TYPE = 1;
public static final byte BANDWIDTH_OBJ_CLASS = 5;
public static final byte BANDWIDTH_OBJECT_VERSION = 1;
+ public static final int NO_OF_BITS = 8;
public static final short BANDWIDTH_OBJ_MINIMUM_LENGTH = 8;
static final PcepObjectHeader DEFAULT_BANDWIDTH_OBJECT_HEADER = new PcepObjectHeader(BANDWIDTH_OBJ_CLASS,
@@ -58,7 +59,7 @@
BANDWIDTH_OBJ_MINIMUM_LENGTH);
private PcepObjectHeader bandwidthObjHeader;
- private int iBandwidth;
+ private float iBandwidth;
/**
* Constructor to bandwidth object header and bandwidth.
@@ -66,7 +67,7 @@
* @param bandwidthObjHeader bandwidth object header
* @param iBandwidth bandwidth value
*/
- public PcepBandwidthObjectVer1(PcepObjectHeader bandwidthObjHeader, int iBandwidth) {
+ public PcepBandwidthObjectVer1(PcepObjectHeader bandwidthObjHeader, float iBandwidth) {
this.bandwidthObjHeader = bandwidthObjHeader;
this.iBandwidth = iBandwidth;
}
@@ -76,7 +77,7 @@
*
* @param iBandwidth bandwidth value
*/
- public PcepBandwidthObjectVer1(int iBandwidth) {
+ public PcepBandwidthObjectVer1(float iBandwidth) {
this.bandwidthObjHeader = DEFAULT_BANDWIDTH_OBJECT_HEADER;
this.iBandwidth = iBandwidth;
}
@@ -100,12 +101,12 @@
}
@Override
- public int getBandwidth() {
+ public float getBandwidth() {
return this.iBandwidth;
}
@Override
- public void setBandwidth(int iBandwidth) {
+ public void setBandwidth(float iBandwidth) {
this.iBandwidth = iBandwidth;
}
@@ -119,12 +120,25 @@
public static PcepBandwidthObject read(ChannelBuffer cb) throws PcepParseException {
PcepObjectHeader bandwidthObjHeader;
- int iBandwidth;
+ float bandwidth;
bandwidthObjHeader = PcepObjectHeader.read(cb);
- iBandwidth = cb.readInt();
+ bandwidth = ieeeToFloatRead(cb.readInt()) * NO_OF_BITS;
- return new PcepBandwidthObjectVer1(bandwidthObjHeader, iBandwidth);
+ return new PcepBandwidthObjectVer1(bandwidthObjHeader, bandwidth);
+ }
+
+ /**
+ * Parse the IEEE floating point notation and returns it in normal float.
+ *
+ * @param iVal IEEE floating point number
+ * @return normal float
+ */
+ public static float ieeeToFloatRead(int iVal) {
+ iVal = (((iVal & 0xFF) << 24) | ((iVal & 0xFF00) << 8)
+ | ((iVal & 0xFF0000) >> 8) | ((iVal >> 24) & 0xFF));
+
+ return Float.intBitsToFloat(iVal);
}
@Override
@@ -138,7 +152,7 @@
throw new PcepParseException("Failed to write bandwidth object header. Index " + objLenIndex);
}
- cb.writeInt(iBandwidth);
+ cb.writeInt(Float.floatToIntBits(iBandwidth));
short hLength = (short) (cb.writerIndex() - objStartIndex);
cb.setShort(objLenIndex, hLength);
//will be helpful during print().
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java
index 4b97d05..d680ff4 100644
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java
@@ -16,8 +16,10 @@
package org.onosproject.pcepio.protocol.ver1;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
+import java.util.Objects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.pcepio.exceptions.PcepParseException;
@@ -399,10 +401,47 @@
}
@Override
+ public int hashCode() {
+ return Objects.hash(eroObjHeader, subObjectList);
+ }
+
+ @Override
public String toString() {
return MoreObjects.toStringHelper(getClass()).omitNullValues()
.add("EroObjHeader", eroObjHeader)
.add("SubObjects", subObjectList)
.toString();
}
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof PcepEroObjectVer1) {
+ int countObjSubTlv = 0;
+ int countOtherSubTlv = 0;
+ boolean isCommonSubTlv = true;
+ PcepEroObjectVer1 other = (PcepEroObjectVer1) obj;
+ Iterator<PcepValueType> objListIterator = other.subObjectList.iterator();
+ countOtherSubTlv = other.subObjectList.size();
+ countObjSubTlv = subObjectList.size();
+ if (countObjSubTlv != countOtherSubTlv) {
+ return false;
+ } else {
+ while (objListIterator.hasNext() && isCommonSubTlv) {
+ PcepValueType subTlv = objListIterator.next();
+ if (subObjectList.contains(subTlv)) {
+ isCommonSubTlv = Objects.equals(subObjectList.get(subObjectList.indexOf(subTlv)),
+ other.subObjectList.get(other.subObjectList.indexOf(subTlv)));
+ } else {
+ isCommonSubTlv = false;
+ }
+ }
+ return isCommonSubTlv && Objects.equals(eroObjHeader, other.eroObjHeader);
+ }
+ }
+ return false;
+ }
}
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMetricObjectVer1.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMetricObjectVer1.java
index 1ac1340..6e82ffd 100644
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMetricObjectVer1.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMetricObjectVer1.java
@@ -57,6 +57,10 @@
public static final int BFLAG_RESET = 0;
public static final byte CFLAG_CHECK = 0x02;
+ public static final byte IGP_METRIC = 0x01;
+ public static final byte TE_METRIC = 0x02;
+ public static final byte HOP_COUNT_METRIC = 0x03;
+
static final PcepObjectHeader DEFAULT_METRIC_OBJECT_HEADER = new PcepObjectHeader(METRIC_OBJ_CLASS,
METRIC_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
METRIC_OBJ_MINIMUM_LENGTH);
diff --git a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepObjectHeader.java b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepObjectHeader.java
index cfe2fe3..7062076 100644
--- a/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepObjectHeader.java
+++ b/protocols/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepObjectHeader.java
@@ -16,6 +16,8 @@
package org.onosproject.pcepio.types;
+import java.util.Objects;
+
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -212,6 +214,27 @@
}
@Override
+ public int hashCode() {
+ return Objects.hash(objClass, objType, bPFlag, bIFlag, objLen);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof PcepObjectHeader) {
+ PcepObjectHeader other = (PcepObjectHeader) obj;
+ return Objects.equals(objClass, other.objClass)
+ && Objects.equals(objType, other.objType)
+ && Objects.equals(bPFlag, other.bPFlag)
+ && Objects.equals(bIFlag, other.bIFlag)
+ && Objects.equals(objLen, other.objLen);
+ }
+ return false;
+ }
+
+ @Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("ObjectClass", objClass)
diff --git a/providers/bgp/pom.xml b/providers/bgp/pom.xml
old mode 100755
new mode 100644
index e758768..572e9e4
--- a/providers/bgp/pom.xml
+++ b/providers/bgp/pom.xml
@@ -40,6 +40,11 @@
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
+ <artifactId>onos-incubator-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
diff --git a/providers/bgp/topology/BUCK b/providers/bgp/topology/BUCK
index 657ed56..ee79b20 100644
--- a/providers/bgp/topology/BUCK
+++ b/providers/bgp/topology/BUCK
@@ -3,6 +3,7 @@
'//protocols/bgp/api:onos-protocols-bgp-api',
'//protocols/bgp/bgpio:onos-protocols-bgp-bgpio',
'//incubator/store:onos-incubator-store',
+ '//incubator/api:onos-incubator-api',
]
TEST_DEPS = [
diff --git a/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java b/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java
index 0ac494c..be90682 100644
--- a/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java
+++ b/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java
@@ -17,11 +17,16 @@
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Device.Type.ROUTER;
import static org.onosproject.net.Device.Type.VIRTUAL;
+import static org.onosproject.incubator.net.resource.label.LabelResourceId.labelResourceId;
+import static java.util.stream.Collectors.toList;
+import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ip4Address;
+import org.onlab.util.Bandwidth;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -45,9 +50,21 @@
import org.onosproject.bgpio.types.IsIsNonPseudonode;
import org.onosproject.bgpio.types.IsIsPseudonode;
import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
+import org.onosproject.bgpio.types.LinkStateAttributes;
import org.onosproject.bgpio.types.OspfNonPseudonode;
import org.onosproject.bgpio.types.OspfPseudonode;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId;
+import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipListener;
+import org.onosproject.mastership.MastershipService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
@@ -56,12 +73,15 @@
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.PortDescription;
import org.onosproject.net.link.DefaultLinkDescription;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.LinkProvider;
@@ -70,6 +90,7 @@
import org.onosproject.net.link.LinkService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.config.basics.BandwidthCapacity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -106,16 +127,39 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MastershipService mastershipService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LabelResourceAdminService labelResourceAdminService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigService networkConfigService;
+
private DeviceProviderService deviceProviderService;
private LinkProviderService linkProviderService;
+ private InternalMastershipListener masterListener = new InternalMastershipListener();
private InternalBgpProvider listener = new InternalBgpProvider();
private static final String UNKNOWN = "unknown";
public static final long IDENTIFIER_SET = 0x100000000L;
public static final String AS_NUMBER = "asNumber";
public static final String DOMAIN_IDENTIFIER = "domainIdentifier";
public static final String ROUTING_UNIVERSE = "routingUniverse";
+
+ public static final String EXTERNAL_BIT = "externalBit";
+ public static final String ABR_BIT = "abrBit";
+ public static final String INTERNAL_BIT = "internalBit";
+ public static final String PSEUDO = "psuedo";
+ public static final String AREAID = "areaId";
+ public static final String LSRID = "lsrId";
+ public static final String COST = "cost";
+ public static final String TE_COST = "teCost";
+
public static final long PSEUDO_PORT = 0xffffffff;
+ public static final int DELAY = 2;
+ private LabelResourceId beginLabel = labelResourceId(5122);
+ private LabelResourceId endLabel = labelResourceId(9217);
@Activate
public void activate() {
@@ -123,6 +167,7 @@
deviceProviderService = deviceProviderRegistry.register(this);
linkProviderService = linkProviderRegistry.register(this);
controller.addListener(listener);
+ mastershipService.addListener(masterListener);
controller.addLinkListener(listener);
}
@@ -135,6 +180,27 @@
linkProviderService = null;
controller.removeListener(listener);
controller.removeLinkListener(listener);
+ mastershipService.removeListener(masterListener);
+ }
+
+ private class InternalMastershipListener implements MastershipListener {
+ @Override
+ public void event(MastershipEvent event) {
+ if (event.type() == MastershipEvent.Type.MASTER_CHANGED) {
+ if (mastershipService.getMasterFor(event.subject()) != null) {
+ //Only for L3 device create label pool for that device
+ Device device = deviceService.getDevice(event.subject());
+ if (device == null) {
+ log.debug("Device {} doesn't exist", event.subject());
+ return;
+ }
+ //Reserve device label pool for L3 devices
+ if (device.annotations().value(LSRID) != null) {
+ createDevicePool(event.subject());
+ }
+ }
+ }
+ }
}
/*
@@ -146,7 +212,7 @@
public void addNode(BgpNodeLSNlriVer4 nodeNlri, PathAttrNlriDetails details) {
log.debug("Add node {}", nodeNlri.toString());
- if (deviceProviderService == null) {
+ if (deviceProviderService == null || deviceService == null) {
return;
}
Device.Type deviceType = ROUTER;
@@ -154,6 +220,13 @@
DeviceId deviceId = deviceId(uri(nodeUri.toString()));
ChassisId cId = new ChassisId();
+ /*
+ * Check if device is already there (available) , if yes not updating to core.
+ */
+ if (deviceService.isAvailable(deviceId)) {
+ return;
+ }
+
DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
newBuilder.set(AnnotationKeys.TYPE, "L3");
@@ -183,11 +256,13 @@
}
}
}
+ DefaultAnnotations.Builder anntotations = DefaultAnnotations.builder();
+ anntotations = getAnnotations(newBuilder, true, details);
DeviceDescription description = new DefaultDeviceDescription(uri(nodeUri.toString()), deviceType, UNKNOWN,
- UNKNOWN, UNKNOWN, UNKNOWN, cId, newBuilder.build());
- deviceProviderService.deviceConnected(deviceId, description);
+ UNKNOWN, UNKNOWN, UNKNOWN, cId, anntotations.build());
+ deviceProviderService.deviceConnected(deviceId, description);
}
@Override
@@ -200,6 +275,12 @@
BgpDpid deviceUri = new BgpDpid(nodeNlri);
DeviceId deviceId = deviceId(uri(deviceUri.toString()));
+
+ if (labelResourceAdminService != null) {
+ //Destroy local device label pool reserved for that device
+ labelResourceAdminService.destroyDevicePool(deviceId);
+ }
+
deviceProviderService.deviceDisconnected(deviceId);
}
@@ -211,6 +292,24 @@
return;
}
LinkDescription linkDes = buildLinkDes(linkNlri, details, true);
+
+ /*
+ * Update link ports and configure bandwidth on source and destination port using networkConfig service
+ * Only master of source link registers for bandwidth
+ */
+ if (mastershipService.isLocalMaster(linkDes.src().deviceId())) {
+ registerBandwidth(linkDes, details);
+ }
+
+ //Updating ports of the link
+ List<PortDescription> srcPortDescriptions = new LinkedList<>();
+ srcPortDescriptions.add(new DefaultPortDescription(linkDes.src().port(), true));
+ deviceProviderService.updatePorts(linkDes.src().deviceId(), srcPortDescriptions);
+
+ List<PortDescription> dstPortDescriptions = new LinkedList<>();
+ dstPortDescriptions.add(new DefaultPortDescription(linkDes.dst().port(), true));
+ deviceProviderService.updatePorts(linkDes.dst().deviceId(), dstPortDescriptions);
+
linkProviderService.linkDetected(linkDes);
}
@@ -273,7 +372,12 @@
addOrDeletePseudoNode(isAddLink, localPseduo, remotePseduo, srcNodeNlri,
dstNodeNlri, srcId, dstId, details);
- return new DefaultLinkDescription(src, dst, Link.Type.DIRECT, false);
+ DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
+ if (details != null) {
+ annotationBuilder = getAnnotations(annotationBuilder, false, details);
+ }
+
+ return new DefaultLinkDescription(src, dst, Link.Type.DIRECT, false, annotationBuilder.build());
}
private void addOrDeletePseudoNode(boolean isAddLink, boolean localPseduo, boolean remotePseduo,
@@ -322,10 +426,140 @@
}
LinkDescription linkDes = buildLinkDes(linkNlri, null, false);
+
+ /*
+ * Only master for the link src will release the bandwidth resource.
+ */
+ if (networkConfigService != null && mastershipService.isLocalMaster(linkDes.src().deviceId())) {
+ // Releases registered resource for this link
+ networkConfigService.removeConfig(linkDes.src(), BandwidthCapacity.class);
+ networkConfigService.removeConfig(linkDes.dst(), BandwidthCapacity.class);
+ }
+
linkProviderService.linkVanished(linkDes);
}
}
+ // Creates label resource pool for the specific device. For all devices label range is 5122-9217
+ private void createDevicePool(DeviceId deviceId) {
+ if (labelResourceAdminService == null) {
+ return;
+ }
+
+ labelResourceAdminService.createDevicePool(deviceId, beginLabel, endLabel);
+ }
+
+ private void registerBandwidth(LinkDescription linkDes, PathAttrNlriDetails details) {
+ if (details == null) {
+ log.error("Couldnot able to register bandwidth ");
+ return;
+ }
+
+ List<BgpValueType> attribute = details.pathAttributes().stream()
+ .filter(attr -> attr instanceof LinkStateAttributes).collect(toList());
+ if (attribute.isEmpty()) {
+ return;
+ }
+
+ List<BgpValueType> tlvs = ((LinkStateAttributes) attribute.iterator().next()).linkStateAttributes();
+ float maxReservableBw = 0;
+
+ for (BgpValueType tlv : tlvs) {
+ switch (tlv.getType()) {
+ case LinkStateAttributes.ATTR_LINK_MAX_RES_BANDWIDTH:
+ maxReservableBw = ((BgpLinkAttrMaxLinkBandwidth) tlv).linkAttrMaxLinkBandwidth();
+ break;
+ default: // do nothing
+ }
+ }
+
+ if (maxReservableBw == 0.0) {
+ return;
+ }
+
+ //Configure bandwidth for src and dst port
+ BandwidthCapacity config = networkConfigService.addConfig(linkDes.src(), BandwidthCapacity.class);
+ config.capacity(Bandwidth.bps(maxReservableBw)).apply();
+
+ config = networkConfigService.addConfig(linkDes.dst(), BandwidthCapacity.class);
+ config.capacity(Bandwidth.bps(maxReservableBw)).apply();
+ }
+
+ private DefaultAnnotations.Builder getAnnotations(DefaultAnnotations.Builder annotationBuilder, boolean isNode,
+ PathAttrNlriDetails details) {
+
+ List<BgpValueType> attribute = details.pathAttributes().stream()
+ .filter(attr -> attr instanceof LinkStateAttributes).collect(toList());
+ if (attribute.isEmpty()) {
+ return annotationBuilder;
+ }
+ List<BgpValueType> tlvs = ((LinkStateAttributes) attribute.iterator().next()).linkStateAttributes();
+ boolean abrBit = false;
+ boolean externalBit = false;
+ boolean pseudo = false;
+ int igpMetric = 0;
+ int teMetric = 0;
+ byte[] areaId = null;
+ Ip4Address routerId = null;
+ for (BgpValueType tlv : tlvs) {
+ switch (tlv.getType()) {
+ case LinkStateAttributes.ATTR_NODE_FLAG_BITS:
+ abrBit = ((BgpAttrNodeFlagBitTlv) tlv).abrBit();
+ externalBit = ((BgpAttrNodeFlagBitTlv) tlv).externalBit();
+ break;
+ case NodeDescriptors.IGP_ROUTERID_TYPE:
+ if (tlv instanceof IsIsPseudonode || tlv instanceof OspfPseudonode) {
+ pseudo = true;
+ }
+ break;
+ case LinkStateAttributes.ATTR_NODE_ISIS_AREA_ID:
+ areaId = ((BgpAttrNodeIsIsAreaId) tlv).attrNodeIsIsAreaId();
+ break;
+ case LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID:
+ routerId = ((BgpAttrRouterIdV4) tlv).attrRouterId();
+ break;
+ case LinkStateAttributes.ATTR_LINK_IGP_METRIC:
+ igpMetric = ((BgpLinkAttrIgpMetric) tlv).attrLinkIgpMetric();
+ break;
+ case LinkStateAttributes.ATTR_LINK_TE_DEFAULT_METRIC:
+ teMetric = ((BgpLinkAttrTeDefaultMetric) tlv).attrLinkDefTeMetric();
+ break;
+ default: // do nothing
+ }
+ }
+
+ // Annotations for device
+ if (isNode) {
+ boolean internalBit = false;
+ if (!abrBit && !externalBit) {
+ internalBit = true;
+ }
+
+ annotationBuilder.set(EXTERNAL_BIT, String.valueOf(externalBit));
+ annotationBuilder.set(ABR_BIT, String.valueOf(abrBit));
+ annotationBuilder.set(INTERNAL_BIT, String.valueOf(internalBit));
+ annotationBuilder.set(PSEUDO, String.valueOf(pseudo));
+
+ if (areaId != null) {
+ annotationBuilder.set(AREAID, new String(areaId));
+ }
+ if (routerId != null) {
+ // LsrID
+ annotationBuilder.set(LSRID, String.valueOf(routerId));
+ }
+ } else {
+ // Annotations for link
+ if (igpMetric != 0) {
+ annotationBuilder.set(COST, String.valueOf(igpMetric));
+ }
+
+ if (teMetric != 0) {
+ annotationBuilder.set(TE_COST, String.valueOf(teMetric));
+ }
+ }
+ return annotationBuilder;
+ }
+
@Override
public void triggerProbe(DeviceId deviceId) {
// TODO Auto-generated method stub
diff --git a/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java b/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
index 7401fa5..4c3b097 100644
--- a/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
+++ b/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
@@ -16,6 +16,8 @@
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.onosproject.net.Link.State.ACTIVE;
+import static org.onosproject.net.MastershipRole.MASTER;
+import static org.hamcrest.Matchers.nullValue;
import java.util.Collection;
import java.util.HashMap;
@@ -29,7 +31,11 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.junit.TestUtils.TestUtilsException;
import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ip4Address;
+import org.onlab.util.Bandwidth;
import org.onosproject.bgp.controller.BgpLinkListener;
import org.onosproject.bgp.controller.BgpNodeListener;
import org.onosproject.bgpio.exceptions.BgpParseException;
@@ -43,9 +49,26 @@
import org.onosproject.bgpio.types.AutonomousSystemTlv;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.IsIsNonPseudonode;
+import org.onosproject.bgpio.types.LinkStateAttributes;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourcePool;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipListener;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.mastership.MastershipEvent.Type;
+import org.onosproject.net.link.LinkServiceAdapter;
import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
import org.onosproject.bgpio.types.RouteDistinguisher;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId;
+import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
import org.onosproject.bgpio.util.Constants;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.cluster.RoleInfo;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
@@ -53,6 +76,11 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
@@ -65,6 +93,15 @@
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.config.basics.BandwidthCapacity;
+import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.ResourceAdminService;
+import org.onosproject.net.resource.ResourceId;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Test for BGP topology provider.
@@ -73,21 +110,31 @@
private static final DeviceId DID2 = DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10");
private static final String UNKNOWN = new String("unknown");
public static ProviderId providerId = new ProviderId("l3", "foo");
+ private static final NodeId NODE1 = new NodeId("Master1");
private final BgpTopologyProvider provider = new BgpTopologyProvider();
private final TestDeviceRegistry nodeRegistry = new TestDeviceRegistry();
private final TestLinkRegistry linkRegistry = new TestLinkRegistry();
private final MockBgpController controller = new MockBgpController();
private MockDeviceService deviceService = new MockDeviceService();
+ private MockLinkService linkService = new MockLinkService();
+ private MockMastershipService mastershipService = new MockMastershipService();
+ private MockNetConfigRegistryAdapter networkConfigService = new MockNetConfigRegistryAdapter();
+ private MockLabelResourceService labelResourceAdminService = new MockLabelResourceService();
private Map<DeviceId, Device> deviceMap = new HashMap<>();
-
+ private MastershipListener listener;
@Before
- public void startUp() {
+ public void startUp() throws TestUtilsException {
provider.deviceProviderRegistry = nodeRegistry;
provider.linkProviderRegistry = linkRegistry;
provider.controller = controller;
provider.deviceService = deviceService;
+ provider.linkService = linkService;
+ provider.labelResourceAdminService = labelResourceAdminService;
+ provider.mastershipService = mastershipService;
+ provider.networkConfigService = networkConfigService;
+ listener = TestUtils.getField(provider, "masterListener");
provider.activate();
assertThat("device provider should be registered", not(nodeRegistry.provider));
assertThat("link provider should be registered", not(linkRegistry.linkProvider));
@@ -101,15 +148,177 @@
provider.controller = null;
provider.deviceService = null;
provider.deviceProviderRegistry = null;
+ provider.linkService = null;
+ provider.mastershipService = null;
+ provider.networkConfigService = null;
+ provider.labelResourceAdminService = null;
assertThat(controller.nodeListener, is(new HashSet<BgpNodeListener>()));
assertThat(controller.linkListener, is(new HashSet<BgpLinkListener>()));
}
+ private class MockLabelResourceService implements LabelResourceAdminService {
+
+ Map<DeviceId, LabelResourcePool> resourcePool = new HashMap<>();
+
+ @Override
+ public boolean createDevicePool(DeviceId deviceId, LabelResourceId beginLabel, LabelResourceId endLabel) {
+ LabelResourcePool labelResource = new LabelResourcePool(deviceId.toString(),
+ beginLabel.labelId(),
+ endLabel.labelId());
+ if (resourcePool.containsValue(labelResource)) {
+ return false;
+ }
+
+ resourcePool.put(deviceId, labelResource);
+ return true;
+ }
+
+ @Override
+ public boolean createGlobalPool(LabelResourceId beginLabel, LabelResourceId endLabel) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean destroyDevicePool(DeviceId deviceId) {
+ LabelResourcePool devicePool = resourcePool.get(deviceId);
+
+ if (devicePool == null) {
+ return false;
+ }
+
+ resourcePool.remove(deviceId);
+ return true;
+ }
+
+ @Override
+ public boolean destroyGlobalPool() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+ }
+
+ /* Mock test for device service */
+ private class MockNetConfigRegistryAdapter extends NetworkConfigRegistryAdapter {
+ private ConfigFactory cfgFactory;
+ private Map<ConnectPoint, BandwidthCapacity> classConfig = new HashMap<>();
+
+ @Override
+ public void registerConfigFactory(ConfigFactory configFactory) {
+ cfgFactory = configFactory;
+ }
+
+ @Override
+ public void unregisterConfigFactory(ConfigFactory configFactory) {
+ cfgFactory = null;
+ }
+
+ @Override
+ public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) {
+ if (configClass == BandwidthCapacity.class) {
+ BandwidthCapacity devCap = new BandwidthCapacity();
+ classConfig.put((ConnectPoint) subject, devCap);
+
+ JsonNode node = new ObjectNode(new MockJsonNode());
+ ObjectMapper mapper = new ObjectMapper();
+ ConfigApplyDelegate delegate = new InternalApplyDelegate();
+ devCap.init((ConnectPoint) subject, null, node, mapper, delegate);
+ return (C) devCap;
+ }
+
+ return null;
+ }
+
+ @Override
+ public <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass) {
+ classConfig.remove(subject);
+ }
+
+ @Override
+ public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+ if (configClass == BandwidthCapacity.class) {
+ return (C) classConfig.get(subject);
+ }
+ return null;
+ }
+
+ private class MockJsonNode extends JsonNodeFactory {
+ }
+
+ // Auxiliary delegate to receive notifications about changes applied to
+ // the network configuration - by the apps.
+ private class InternalApplyDelegate implements ConfigApplyDelegate {
+ @Override
+ public void onApply(Config config) {
+ }
+ }
+ }
+
+ private class MockMastershipService extends MastershipServiceAdapter {
+ @Override
+ public MastershipRole getLocalRole(DeviceId deviceId) {
+ return MASTER;
+ }
+
+ @Override
+ public boolean isLocalMaster(DeviceId deviceId) {
+ return getLocalRole(deviceId) == MASTER;
+ }
+
+ @Override
+ public NodeId getMasterFor(DeviceId deviceId) {
+ return NODE1;
+ }
+ }
+
+ private class MockResourceAdminService implements ResourceAdminService {
+ Map<ResourceId, List<Resource>> registeredRes = new HashMap<>();
+
+ @Override
+ public boolean register(List<Resource> resources) {
+ for (Resource res : resources) {
+ List<Resource> resource = new LinkedList<>();
+ resource.add(res);
+ if (registeredRes.containsKey(res.id())) {
+ resource.addAll(registeredRes.get(res.id()));
+ }
+ registeredRes.put(res.id(), resource);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean unregister(List<ResourceId> ids) {
+ for (ResourceId id : ids) {
+ if (registeredRes.containsKey(id)) {
+ registeredRes.remove(id);
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ private class MockLinkService extends LinkServiceAdapter {
+
+ @Override
+ public Link getLink(ConnectPoint src, ConnectPoint dst) {
+ for (Link link : linkRegistry.links) {
+ if (link.src().equals(src) && link.dst().equals(dst)) {
+ return link;
+ }
+ }
+ return null;
+ }
+ }
+
/* Class implement device test registry */
private class TestDeviceRegistry implements DeviceProviderRegistry {
DeviceProvider provider;
Set<DeviceId> connected = new HashSet<>();
+ Map<DeviceId, List<PortDescription>> portUpdated = new HashMap<>();
@Override
public DeviceProviderService register(DeviceProvider provider) {
@@ -138,7 +347,7 @@
if (!deviceId.equals(DID2)) {
connected.add(deviceId);
Device device = new DefaultDevice(BgpTopologyProviderTest.providerId, deviceId, Device.Type.ROUTER,
- UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, new ChassisId());
+ UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, new ChassisId(), deviceDescription.annotations());
deviceMap.put(deviceId, device);
}
}
@@ -153,8 +362,7 @@
@Override
public void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
- // TODO Auto-generated method stub
-
+ portUpdated.put(deviceId, portDescriptions);
}
@Override
@@ -202,9 +410,14 @@
@Override
public void linkDetected(LinkDescription linkDescription) {
- links.add(DefaultLink.builder().src(linkDescription.src())
- .dst(linkDescription.dst()).state(ACTIVE).type(linkDescription.type())
- .providerId(BgpTopologyProviderTest.providerId).build());
+ links.add(DefaultLink.builder()
+ .src(linkDescription.src())
+ .dst(linkDescription.dst())
+ .state(ACTIVE)
+ .type(linkDescription.type())
+ .providerId(BgpTopologyProviderTest.providerId)
+ .annotations(linkDescription.annotations())
+ .build());
}
@Override
@@ -349,6 +562,59 @@
}
}
+
+ /**
+ * Validate node is added to the device with all device annotations.
+ */
+ @Test
+ public void bgpTopologyProviderTestAddDevice4() {
+ LinkedList<BgpValueType> subTlvs = new LinkedList<>();
+ BgpValueType tlv = new AutonomousSystemTlv(100);
+ short deslength = AutonomousSystemTlv.LENGTH;
+ short desType = AutonomousSystemTlv.TYPE;
+
+ subTlvs.add(tlv);
+ BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(new NodeDescriptors(subTlvs, deslength,
+ desType));
+ BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
+ new RouteDistinguisher());
+
+ PathAttrNlriDetails details = new PathAttrNlriDetails();
+ details.setIdentifier(0);
+ details.setProtocolID(ProtocolType.DIRECT);
+ List<BgpValueType> pathAttributes = new LinkedList<>();
+ List<BgpValueType> linkStateAttr = new LinkedList<>();
+ tlv = BgpAttrNodeFlagBitTlv.of(true, true, true, false);
+ linkStateAttr.add(tlv);
+ tlv = BgpAttrNodeIsIsAreaId.of(new byte[] {01, 01, 01, 01});
+ linkStateAttr.add(tlv);
+ tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
+ linkStateAttr.add(tlv);
+ pathAttributes.add(new LinkStateAttributes(linkStateAttr));
+ details.setPathAttribute(pathAttributes);
+
+ for (BgpNodeListener l : controller.nodeListener) {
+ l.addNode(nodeNlri, details);
+
+ assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.ABR_BIT),
+ is("false"));
+ assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.EXTERNAL_BIT),
+ is("true"));
+ assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.INTERNAL_BIT),
+ is("false"));
+ assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.PSEUDO),
+ is("false"));
+ assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.AREAID).getBytes(),
+ is(new byte[] {01, 01, 01, 01}));
+ assertThat(deviceMap.values().iterator().next().annotations().value(BgpTopologyProvider.LSRID),
+ is("1.1.1.1"));
+
+ assertThat(nodeRegistry.connected.size(), is(1));
+ l.deleteNode(nodeNlri);
+ assertThat(nodeRegistry.connected.size(), is(0));
+ }
+ }
+
/**
* Add a link and two devices.
*
@@ -460,6 +726,82 @@
}
/**
+ * Add a link and delete a link with registering/unregistering bandwidth.
+ *
+ * @throws BgpParseException while adding or removing the link
+ * @throws InterruptedException while registering for bandwidth
+ */
+ @Test
+ public void bgpTopologyProviderTestAddLink3() throws BgpParseException, InterruptedException {
+ LinkedList<BgpValueType> localTlvs = new LinkedList<>();
+ LinkedList<BgpValueType> remoteTlvs = new LinkedList<>();
+ LinkedList<BgpValueType> linkdes = new LinkedList<>();
+ BgpValueType tlv = new AutonomousSystemTlv(10);
+ short deslength = AutonomousSystemTlv.LENGTH;
+ short desType = AutonomousSystemTlv.TYPE;
+
+ localTlvs.add(tlv);
+ remoteTlvs.add(tlv);
+ tlv = IsIsNonPseudonode.of(new byte[] {20, 20, 20, 20, 00, 20});
+ localTlvs.add(tlv);
+ tlv = IsIsNonPseudonode.of(new byte[] {30, 30, 30, 30, 00, 30});
+ remoteTlvs.add(tlv);
+ NodeDescriptors localNode = new NodeDescriptors(localTlvs, deslength, desType);
+ NodeDescriptors remoteNode = new NodeDescriptors(remoteTlvs, deslength, desType);
+ BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(localNode);
+ BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
+ new RouteDistinguisher());
+
+ BgpNodeLSIdentifier remoteNodeDescriptors = new BgpNodeLSIdentifier(remoteNode);
+ BgpNodeLSNlriVer4 remNodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, remoteNodeDescriptors, false,
+ new RouteDistinguisher());
+
+ PathAttrNlriDetails details = new PathAttrNlriDetails();
+ details.setIdentifier(0);
+ details.setProtocolID(ProtocolType.DIRECT);
+ List<BgpValueType> pathAttributes = new LinkedList<>();
+ details.setPathAttribute(pathAttributes);
+
+ tlv = LinkLocalRemoteIdentifiersTlv.of(99, 100);
+ linkdes.add(tlv);
+ BgpLinkLSIdentifier linkId = new BgpLinkLSIdentifier(localNode, remoteNode, linkdes);
+ BgpLinkLsNlriVer4 linkNlri = new BgpLinkLsNlriVer4((byte) Constants.DIRECT, 0, linkId,
+ new RouteDistinguisher(), false);
+
+ for (BgpNodeListener l : controller.nodeListener) {
+ l.addNode(nodeNlri, details);
+ assertThat(nodeRegistry.connected.size(), is(1));
+ l.addNode(remNodeNlri, details);
+ assertThat(nodeRegistry.connected.size(), is(2));
+ l.deleteNode(remNodeNlri);
+ assertThat(nodeRegistry.connected.size(), is(1));
+ }
+
+ List<BgpValueType> linkPathAttributes = new LinkedList<>();
+ List<BgpValueType> linkStateAttr = new LinkedList<>();
+ tlv = BgpLinkAttrIgpMetric.of(10, 4);
+ linkStateAttr.add(tlv);
+ tlv = BgpLinkAttrTeDefaultMetric.of(20);
+ linkStateAttr.add(tlv);
+ tlv = BgpLinkAttrMaxLinkBandwidth.of(30, LinkStateAttributes.ATTR_LINK_MAX_RES_BANDWIDTH);
+ linkStateAttr.add(tlv);
+ linkPathAttributes.add(new LinkStateAttributes(linkStateAttr));
+ details.setPathAttribute(linkPathAttributes);
+
+ for (BgpLinkListener l : controller.linkListener) {
+ l.addLink(linkNlri, details);
+ assertThat(linkRegistry.links.size(), is(1));
+ assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.COST),
+ is("10"));
+ assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.TE_COST),
+ is("20"));
+
+ l.deleteLink(linkNlri);
+ assertThat(linkRegistry.links.size(), is(0));
+ }
+ }
+
+ /**
* Invalid link.
*
* @throws BgpParseException while adding or deleting a link
@@ -512,4 +854,188 @@
assertThat(linkRegistry.links.size(), is(0));
}
}
+
+ /**
+ * Add device check label registration is done.
+ *
+ * @throws BgpParseException while adding a device
+ */
+ @Test
+ public void bgpTopologyProviderDeviceTestLabel1() throws BgpParseException {
+ LinkedList<BgpValueType> subTlvs = new LinkedList<>();
+ BgpValueType tlv = new AutonomousSystemTlv(100);
+ short deslength = AutonomousSystemTlv.LENGTH;
+ short desType = AutonomousSystemTlv.TYPE;
+
+ subTlvs.add(tlv);
+ BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(new NodeDescriptors(subTlvs, deslength,
+ desType));
+ BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
+ new RouteDistinguisher());
+
+ PathAttrNlriDetails details = new PathAttrNlriDetails();
+ details.setIdentifier(0);
+ details.setProtocolID(ProtocolType.DIRECT);
+ List<BgpValueType> pathAttributes = new LinkedList<>();
+ List<BgpValueType> linkStateAttributes = new LinkedList<>();
+ tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
+ linkStateAttributes.add(tlv);
+ pathAttributes.add(new LinkStateAttributes(linkStateAttributes));
+ details.setPathAttribute(pathAttributes);
+
+ for (BgpNodeListener l : controller.nodeListener) {
+ l.addNode(nodeNlri, details);
+ assertThat(nodeRegistry.connected.size(), is(1));
+ }
+
+ MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
+ new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
+
+ listener.event(event);
+ assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
+ }
+
+ /**
+ * Add device check label registration is done and delete node destroy label pool.
+ *
+ * @throws BgpParseException while adding a device
+ */
+ @Test
+ public void bgpTopologyProviderDeviceTestLabel2() throws BgpParseException {
+ LinkedList<BgpValueType> subTlvs = new LinkedList<>();
+ BgpValueType tlv = new AutonomousSystemTlv(100);
+ short deslength = AutonomousSystemTlv.LENGTH;
+ short desType = AutonomousSystemTlv.TYPE;
+
+ subTlvs.add(tlv);
+ BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(new NodeDescriptors(subTlvs, deslength,
+ desType));
+ BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
+ new RouteDistinguisher());
+
+ PathAttrNlriDetails details = new PathAttrNlriDetails();
+ details.setIdentifier(0);
+ details.setProtocolID(ProtocolType.DIRECT);
+ List<BgpValueType> pathAttributes = new LinkedList<>();
+ List<BgpValueType> linkStateAttributes = new LinkedList<>();
+ tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
+ linkStateAttributes.add(tlv);
+ pathAttributes.add(new LinkStateAttributes(linkStateAttributes));
+ details.setPathAttribute(pathAttributes);
+
+ for (BgpNodeListener l : controller.nodeListener) {
+ l.addNode(nodeNlri, details);
+ assertThat(nodeRegistry.connected.size(), is(1));
+ // Check label resource reserved for that device
+ MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
+ new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
+ listener.event(event);
+ assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
+
+ l.deleteNode(nodeNlri);
+ assertThat(nodeRegistry.connected.size(), is(0));
+ assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(0));
+ }
+ }
+
+ /**
+ * Add a link register bandwidth and remove link unregister bandwidth.
+ *
+ * @throws BgpParseException while registering/unregistering bandwidth
+ */
+ @Test
+ public void bgpTopologyProviderDeviceTestLabel3() throws BgpParseException {
+ LinkedList<BgpValueType> localTlvs = new LinkedList<>();
+ LinkedList<BgpValueType> remoteTlvs = new LinkedList<>();
+ LinkedList<BgpValueType> linkdes = new LinkedList<>();
+ BgpValueType tlv = new AutonomousSystemTlv(10);
+ short deslength = AutonomousSystemTlv.LENGTH;
+ short desType = AutonomousSystemTlv.TYPE;
+
+ localTlvs.add(tlv);
+ remoteTlvs.add(tlv);
+ tlv = IsIsNonPseudonode.of(new byte[] {20, 20, 20, 20, 00, 20});
+ localTlvs.add(tlv);
+ tlv = IsIsNonPseudonode.of(new byte[] {30, 30, 30, 30, 00, 30});
+ remoteTlvs.add(tlv);
+ NodeDescriptors localNode = new NodeDescriptors(localTlvs, deslength, desType);
+ NodeDescriptors remoteNode = new NodeDescriptors(remoteTlvs, deslength, desType);
+ BgpNodeLSIdentifier localNodeDescriptors = new BgpNodeLSIdentifier(localNode);
+ BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, localNodeDescriptors, false,
+ new RouteDistinguisher());
+
+ BgpNodeLSIdentifier remoteNodeDescriptors = new BgpNodeLSIdentifier(remoteNode);
+ BgpNodeLSNlriVer4 remNodeNlri = new BgpNodeLSNlriVer4(0, (byte) Constants.DIRECT, remoteNodeDescriptors, false,
+ new RouteDistinguisher());
+
+ PathAttrNlriDetails details = new PathAttrNlriDetails();
+ details.setIdentifier(0);
+ details.setProtocolID(ProtocolType.DIRECT);
+ List<BgpValueType> pathAttributes = new LinkedList<>();
+ List<BgpValueType> linkStateAttributes = new LinkedList<>();
+ tlv = BgpAttrRouterIdV4.of(Ip4Address.valueOf("1.1.1.1"), LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID);
+ linkStateAttributes.add(tlv);
+ pathAttributes.add(new LinkStateAttributes(linkStateAttributes));
+ details.setPathAttribute(pathAttributes);
+
+ tlv = LinkLocalRemoteIdentifiersTlv.of(99, 100);
+ linkdes.add(tlv);
+ BgpLinkLSIdentifier linkId = new BgpLinkLSIdentifier(localNode, remoteNode, linkdes);
+ BgpLinkLsNlriVer4 linkNlri = new BgpLinkLsNlriVer4((byte) Constants.DIRECT, 0, linkId,
+ new RouteDistinguisher(), false);
+
+ for (BgpNodeListener l : controller.nodeListener) {
+ l.addNode(nodeNlri, details);
+ assertThat(nodeRegistry.connected.size(), is(1));
+ //Check label resource reserved for that device
+ MastershipEvent event = new MastershipEvent(Type.MASTER_CHANGED, nodeRegistry.connected.iterator().next(),
+ new RoleInfo(NodeId.nodeId("Node1"), new LinkedList<>()));
+ listener.event(event);
+ assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
+ l.addNode(remNodeNlri, details);
+ assertThat(nodeRegistry.connected.size(), is(2));
+ l.deleteNode(remNodeNlri);
+ assertThat(nodeRegistry.connected.size(), is(1));
+ assertThat(labelResourceAdminService.resourcePool.keySet().size(), is(1));
+ }
+
+ List<BgpValueType> linkPathAttributes = new LinkedList<>();
+ List<BgpValueType> linkStateAttr = new LinkedList<>();
+ tlv = BgpLinkAttrIgpMetric.of(10, 4);
+ linkStateAttr.add(tlv);
+ tlv = BgpLinkAttrTeDefaultMetric.of(20);
+ linkStateAttr.add(tlv);
+ tlv = BgpLinkAttrMaxLinkBandwidth.of(70, LinkStateAttributes.ATTR_LINK_MAX_RES_BANDWIDTH);
+ linkStateAttr.add(tlv);
+ linkPathAttributes.add(new LinkStateAttributes(linkStateAttr));
+ details.setPathAttribute(linkPathAttributes);
+
+ for (BgpLinkListener l : controller.linkListener) {
+ l.addLink(linkNlri, details);
+ assertThat(linkRegistry.links.size(), is(1));
+ assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.COST),
+ is("10"));
+ assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.TE_COST),
+ is("20"));
+
+ ConnectPoint src = new ConnectPoint(
+ DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10:isoid=1414.1414.0014"),
+ PortNumber.portNumber(4294967395L));
+ ConnectPoint dst = new ConnectPoint(
+ DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10:isoid=1e1e.1e1e.001e"),
+ PortNumber.portNumber(4294967396L));
+ BandwidthCapacity bandwidth = networkConfigService.getConfig(src, BandwidthCapacity.class);
+ assertThat(bandwidth.capacity().bps(), is(70.0 * 1_000_000L));
+
+ bandwidth = networkConfigService.getConfig(dst, BandwidthCapacity.class);
+ assertThat(bandwidth.capacity(), is(Bandwidth.bps(70.0 * 1_000_000L)));
+
+ l.deleteLink(linkNlri);
+ assertThat(linkRegistry.links.size(), is(0));
+ bandwidth = networkConfigService.getConfig(src, BandwidthCapacity.class);
+ assertThat(bandwidth, is(nullValue()));
+ bandwidth = networkConfigService.getConfig(dst, BandwidthCapacity.class);
+ assertThat(bandwidth, is(nullValue()));
+ }
+ }
}
diff --git a/providers/pcep/packet/pom.xml b/providers/pcep/packet/pom.xml
new file mode 100644
index 0000000..9f3bd5e
--- /dev/null
+++ b/providers/pcep/packet/pom.xml
@@ -0,0 +1,33 @@
+<!--
+ ~ Copyright 2016-present Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT 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>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-pcep-providers</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>onos-pcep-provider-packet</artifactId>
+ <packaging>bundle</packaging>
+ <description>PCEP packet provider</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-pcep-controller-api</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/PcepPacketProvider.java b/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/PcepPacketProvider.java
new file mode 100644
index 0000000..48f2408
--- /dev/null
+++ b/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/PcepPacketProvider.java
@@ -0,0 +1,140 @@
+package org.onosproject.provider.pcep.packet.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.TCP;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.DefaultPacketContext;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketProvider;
+import org.onosproject.net.packet.PacketProviderRegistry;
+import org.onosproject.net.packet.PacketProviderService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepClientController;
+import org.onosproject.pcep.controller.PcepPacketListener;
+import org.slf4j.Logger;
+
+/**
+ * Provider which uses an PCEP controller to process packets.
+ */
+@Component(immediate = true)
+@Service
+public class PcepPacketProvider extends AbstractProvider implements PacketProvider {
+
+ private static final Logger log = getLogger(PcepPacketProvider.class);
+ static final String PROVIDER_ID = "org.onosproject.provider.packet.pcep";
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PacketProviderRegistry packetProviderRegistry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PcepClientController pcepClientController;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ PacketProviderService packetProviderService;
+
+ private InnerPacketProvider listener = new InnerPacketProvider();
+ public static final String LSRID = "lsrId";
+ public static final int PCEP_PORT = 4189;
+
+ /**
+ * Creates a Packet provider.
+ */
+ public PcepPacketProvider() {
+ super(new ProviderId("pcep", PROVIDER_ID));
+ }
+
+ @Activate
+ public void activate() {
+ packetProviderService = packetProviderRegistry.register(this);
+ pcepClientController.addPacketListener(listener);
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ packetProviderRegistry.unregister(this);
+ pcepClientController.removePacketListener(listener);
+ log.info("Stopped");
+ }
+
+ private class InnerPacketProvider implements PcepPacketListener {
+ @Override
+ public void sendPacketIn(PccId pccId) {
+ TCP tcp = new TCP();
+ // Set the well known PCEP port. To be used to decide to process/discard the packet while processing.
+ tcp.setDestinationPort(PCEP_PORT);
+
+ IPv4 ipv4 = new IPv4();
+ ipv4.setProtocol(IPv4.PROTOCOL_TCP);
+ ipv4.setPayload(tcp);
+
+ Ethernet eth = new Ethernet();
+ eth.setEtherType(Ethernet.TYPE_IPV4);
+ eth.setPayload(ipv4);
+
+ // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
+ String lsrId = String.valueOf(pccId.ipAddress());
+ DeviceId pccDeviceId = null;
+
+ // Find PCC deviceID from lsrId stored as annotations
+ Iterable<Device> devices = deviceService.getAvailableDevices();
+ for (Device dev : devices) {
+ if ("L3".equals(dev.annotations().value(AnnotationKeys.TYPE))
+ && lsrId.equals(dev.annotations().value(LSRID))) {
+ pccDeviceId = dev.id();
+ break;
+ }
+ }
+
+ if (pccDeviceId == null) {
+ return;
+ }
+
+ InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(pccDeviceId,
+ PortNumber.portNumber(PCEP_PORT)),
+ eth, null);
+
+ packetProviderService.processPacket(new PcepPacketContext(inPkt, null));
+ }
+ }
+
+ // Minimal PacketContext to make core and applications happy.
+ private final class PcepPacketContext extends DefaultPacketContext {
+ private PcepPacketContext(InboundPacket inPkt, OutboundPacket outPkt) {
+ super(System.currentTimeMillis(), inPkt, outPkt, false);
+ }
+
+ @Override
+ public void send() {
+ // We don't send anything out.
+ return;
+ }
+ }
+
+ @Override
+ public void emit(OutboundPacket packet) {
+ // Nothing to emit
+ return;
+
+ }
+}
diff --git a/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/package-info.java b/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/package-info.java
new file mode 100644
index 0000000..8e1ab9a
--- /dev/null
+++ b/providers/pcep/packet/src/main/java/org/onosproject/provider/pcep/packet/impl/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *Provider that uses PCEP controller as a means to send packets.
+ */
+package org.onosproject.provider.pcep.packet.impl;
\ No newline at end of file
diff --git a/providers/pcep/pom.xml b/providers/pcep/pom.xml
index 2569ca6..f193c67 100644
--- a/providers/pcep/pom.xml
+++ b/providers/pcep/pom.xml
@@ -27,5 +27,6 @@
<module>topology</module>
<module>tunnel</module>
<module>app</module>
+ <module>packet</module>
</modules>
</project>
\ No newline at end of file
diff --git a/providers/pcep/topology/BUCK b/providers/pcep/topology/BUCK
index 56ba605..7a64a61 100644
--- a/providers/pcep/topology/BUCK
+++ b/providers/pcep/topology/BUCK
@@ -3,6 +3,9 @@
'//protocols/ovsdb/api:onos-protocols-ovsdb-api',
'//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc',
'//apps/pcep-api:onos-apps-pcep-api',
+ '//protocols/pcep/api:onos-protocols-pcep-api',
+ '//protocols/pcep/pcepio:onos-protocols-pcep-pcepio',
+ '//core/api:onos-api-tests',
]
osgi_jar_with_tests (
diff --git a/providers/pcep/topology/pom.xml b/providers/pcep/topology/pom.xml
index 6f017ce..adcebba 100644
--- a/providers/pcep/topology/pom.xml
+++ b/providers/pcep/topology/pom.xml
@@ -23,10 +23,20 @@
<artifactId>onos-pcep-provider-topology</artifactId>
<packaging>bundle</packaging>
<description>PCEP topology provider</description>
- <dependencies>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-app-pcep-api</artifactId>
- </dependency>
- </dependencies>
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-app-pcep-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-pcep-controller-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
</project>
\ No newline at end of file
diff --git a/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java b/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java
index 75a53f3..38239ed 100644
--- a/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java
+++ b/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java
@@ -62,6 +62,10 @@
import org.onosproject.pcep.api.PcepOperator.OperationType;
import org.onosproject.pcep.api.PcepSwitch;
import org.onosproject.pcep.api.PcepSwitchListener;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepClient;
+import org.onosproject.pcep.controller.PcepClientController;
+import org.onosproject.pcep.controller.PcepNodeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -115,18 +119,40 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterService clusterService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PcepClientController pcepClientController;
+
private DeviceProviderService deviceProviderService;
private LinkProviderService linkProviderService;
private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
private InternalLinkProvider listener = new InternalLinkProvider();
+ /*
+ * For the client supporting SR capability.
+ */
+ public static final String SR_CAPABILITY = "srCapability";
+
+ /*
+ * For the client supporting PCECC capability.
+ */
+ public static final String PCECC_CAPABILITY = "pceccCapability";
+
+ /*
+ * For the client supporting label stack capability.
+ */
+ public static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
+
+ public static final String LSRID = "lsrId";
+ private static final String UNKNOWN = "unknown";
+
@Activate
public void activate() {
linkProviderService = linkProviderRegistry.register(this);
deviceProviderService = deviceProviderRegistry.register(this);
controller.addListener(listener);
controller.addLinkListener(listener);
+ pcepClientController.addNodeListener(listener);
}
@Deactivate
@@ -135,6 +161,7 @@
linkProviderService = null;
controller.removeListener(listener);
controller.removeLinkListener(listener);
+ pcepClientController.removeNodeListener(listener);
}
private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
@@ -225,7 +252,7 @@
}
private class InternalLinkProvider
- implements PcepSwitchListener, PcepLinkListener {
+ implements PcepSwitchListener, PcepLinkListener, PcepNodeListener {
@Override
public void switchAdded(PcepDpid dpid) {
@@ -306,6 +333,51 @@
}
}
+ @Override
+ public void addNode(PcepClient pc) {
+ if (deviceProviderService == null) {
+ return;
+ }
+
+ //Right now device URI for PCEP devices is their LSRID
+ DeviceId deviceId = deviceId(uri(new PcepDpid(pc.getPccId().id().getIp4Address().toInt())));
+ ChassisId cId = new ChassisId();
+
+ Device.Type deviceType = Device.Type.ROUTER;
+
+ DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
+ //PCC capabilities (SR, PCECC and PCECC-SR)
+ annotationBuilder.set(SR_CAPABILITY, String.valueOf(pc.capability().srCapability()));
+ annotationBuilder.set(PCECC_CAPABILITY, String.valueOf(pc.capability().pceccCapability()));
+ annotationBuilder.set(LABEL_STACK_CAPABILITY, String.valueOf(pc.capability().labelStackCapability()));
+ //PccId is the lsrId contained in openMsg, if not present it will be the socket address
+ annotationBuilder.set(LSRID, String.valueOf(pc.getPccId().id()));
+
+ DeviceDescription description = new DefaultDeviceDescription(
+ deviceId.uri(),
+ deviceType,
+ UNKNOWN,
+ UNKNOWN,
+ UNKNOWN,
+ UNKNOWN,
+ cId,
+ annotationBuilder.build());
+
+ deviceProviderService.deviceConnected(deviceId, description);
+ }
+
+ @Override
+ public void deleteNode(PccId pccId) {
+ if (deviceProviderService == null || deviceService == null) {
+ return;
+ }
+ //TODO: In device manager, in deviceDisconnected() method, get the device but null check is not validated
+ if (deviceService.getDevice(DeviceId.deviceId(uri(new PcepDpid(pccId.id()
+ .getIp4Address().toInt())))) == null) {
+ return;
+ }
+ deviceProviderService.deviceDisconnected(deviceId(uri(new PcepDpid(pccId.id().getIp4Address().toInt()))));
+ }
}
@Override
diff --git a/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientAdapter.java b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientAdapter.java
new file mode 100644
index 0000000..853bfd5
--- /dev/null
+++ b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientAdapter.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.pcep.topology.impl;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.jboss.netty.channel.Channel;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.LspKey;
+import org.onosproject.pcep.controller.PcepClient;
+import org.onosproject.pcep.controller.PcepSyncStatus;
+import org.onosproject.pcepio.protocol.PcepFactories;
+import org.onosproject.pcepio.protocol.PcepFactory;
+import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepStateReport;
+import org.onosproject.pcepio.protocol.PcepVersion;
+
+/**
+ * Representation of PCEP client adapter.
+ */
+public class PcepClientAdapter implements PcepClient {
+
+ private Channel channel;
+ protected String channelId;
+
+ private boolean connected;
+ private PccId pccId;
+ private ClientCapability capability;
+
+ private PcepVersion pcepVersion;
+ private PcepSyncStatus lspDbSyncStatus;
+ private PcepSyncStatus labelDbSyncStatus;
+ private Map<LspKey, Boolean> lspDelegationInfo = new HashMap<>();
+
+ /**
+ * Initialize instance with specified parameters.
+ *
+ * @param pccId PCC id
+ * @param pcepVersion PCEP message version
+ */
+ public void init(PccId pccId, PcepVersion pcepVersion) {
+ this.pccId = pccId;
+ this.pcepVersion = pcepVersion;
+ }
+
+ @Override
+ public final void disconnectClient() {
+ this.channel.close();
+ }
+
+ @Override
+ public final void sendMessage(PcepMessage m) {
+ }
+
+ @Override
+ public final void sendMessage(List<PcepMessage> msgs) {
+ try {
+ PcepMessage pcepMsg = msgs.get(0);
+ assertNotNull("PCEP MSG should be created.", pcepMsg);
+ } catch (RejectedExecutionException e) {
+ throw e;
+ }
+ }
+
+ @Override
+ public final boolean isConnected() {
+ return this.connected;
+ }
+
+ @Override
+ public String channelId() {
+ return channelId;
+ }
+
+ @Override
+ public final PccId getPccId() {
+ return this.pccId;
+ };
+
+ @Override
+ public final String getStringId() {
+ return this.pccId.toString();
+ }
+
+ @Override
+ public final void handleMessage(PcepMessage m) {
+ }
+
+ @Override
+ public boolean isOptical() {
+ return false;
+ }
+
+ @Override
+ public PcepFactory factory() {
+ return PcepFactories.getFactory(pcepVersion);
+ }
+
+ @Override
+ public void setLspDbSyncStatus(PcepSyncStatus syncStatus) {
+ this.lspDbSyncStatus = syncStatus;
+ }
+
+ @Override
+ public PcepSyncStatus lspDbSyncStatus() {
+ return lspDbSyncStatus;
+ }
+
+ @Override
+ public void setLabelDbSyncStatus(PcepSyncStatus syncStatus) {
+ this.labelDbSyncStatus = syncStatus;
+ }
+
+ @Override
+ public PcepSyncStatus labelDbSyncStatus() {
+ return labelDbSyncStatus;
+ }
+
+ @Override
+ public void setCapability(ClientCapability capability) {
+ this.capability = capability;
+ }
+
+ @Override
+ public ClientCapability capability() {
+ return capability;
+ }
+
+ @Override
+ public void addNode(PcepClient pc) {
+ }
+
+ @Override
+ public void deleteNode(PccId pccId) {
+ }
+
+ @Override
+ public void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag) {
+ lspDelegationInfo.put(lspKey, dFlag);
+ }
+
+ @Override
+ public Boolean delegationInfo(LspKey lspKey) {
+ return lspDelegationInfo.get(lspKey);
+ }
+
+ @Override
+ public void initializeSyncMsgList(PccId pccId) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public List<PcepStateReport> getSyncMsgList(PccId pccId) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void removeSyncMsgList(PccId pccId) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg) {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientControllerAdapter.java b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientControllerAdapter.java
new file mode 100644
index 0000000..74660b1
--- /dev/null
+++ b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepClientControllerAdapter.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.pcep.topology.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.onlab.packet.IpAddress;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepClient;
+import org.onosproject.pcep.controller.PcepClientController;
+import org.onosproject.pcep.controller.PcepClientListener;
+import org.onosproject.pcep.controller.PcepEventListener;
+import org.onosproject.pcep.controller.PcepNodeListener;
+import org.onosproject.pcep.controller.PcepPacketListener;
+import org.onosproject.pcep.controller.driver.PcepAgent;
+import org.onosproject.pcepio.protocol.PcepError;
+import org.onosproject.pcepio.protocol.PcepErrorInfo;
+import org.onosproject.pcepio.protocol.PcepErrorMsg;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepFactory;
+import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepVersion;
+
+import com.google.common.collect.Sets;
+
+import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_TYPE_19;
+import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_VALUE_5;
+
+/**
+ * Representation of PCEP client controller adapter.
+ */
+public class PcepClientControllerAdapter implements PcepClientController {
+
+ protected ConcurrentHashMap<PccId, PcepClient> connectedClients =
+ new ConcurrentHashMap<PccId, PcepClient>();
+
+ protected PcepClientAgent agent = new PcepClientAgent();
+ protected Set<PcepClientListener> pcepClientListener = new HashSet<>();
+
+ protected Set<PcepEventListener> pcepEventListener = Sets.newHashSet();
+ public Set<PcepNodeListener> pcepNodeListener = Sets.newHashSet();
+
+ @Activate
+ public void activate() {
+ }
+
+ @Deactivate
+ public void deactivate() {
+ }
+
+ @Override
+ public Collection<PcepClient> getClients() {
+ return connectedClients.values();
+ }
+
+ @Override
+ public PcepClient getClient(PccId pccId) {
+ if (null != connectedClients.get(pccId)) {
+ return connectedClients.get(pccId);
+ }
+ PcepClientAdapter pc = new PcepClientAdapter();
+ if (pccId.ipAddress().equals(IpAddress.valueOf(0xC010103))
+ || pccId.ipAddress().equals(IpAddress.valueOf(0xB6024E22))) {
+ pc.setCapability(new ClientCapability(true, false, false, false, false));
+ } else {
+ pc.setCapability(new ClientCapability(true, true, true, false, false));
+ }
+ pc.init(PccId.pccId(pccId.ipAddress()), PcepVersion.PCEP_1);
+ connectedClients.put(pccId, pc);
+ return pc;
+ }
+
+ @Override
+ public void addListener(PcepClientListener listener) {
+ if (!pcepClientListener.contains(listener)) {
+ this.pcepClientListener.add(listener);
+ }
+ }
+
+ @Override
+ public void addNodeListener(PcepNodeListener listener) {
+ pcepNodeListener.add(listener);
+ }
+
+ @Override
+ public void removeNodeListener(PcepNodeListener listener) {
+ pcepNodeListener.remove(listener);
+ }
+
+ @Override
+ public void removeListener(PcepClientListener listener) {
+ this.pcepClientListener.remove(listener);
+ }
+
+ @Override
+ public void addEventListener(PcepEventListener listener) {
+ pcepEventListener.add(listener);
+ }
+
+ @Override
+ public void removeEventListener(PcepEventListener listener) {
+ pcepEventListener.remove(listener);
+ }
+
+ @Override
+ public void writeMessage(PccId pccId, PcepMessage msg) {
+ this.getClient(pccId).sendMessage(msg);
+ }
+
+ @Override
+ public void processClientMessage(PccId pccId, PcepMessage msg) {
+
+ PcepClient pc = getClient(pccId);
+
+ switch (msg.getType()) {
+ case NONE:
+ break;
+ case OPEN:
+ break;
+ case KEEP_ALIVE:
+ //log.debug("Sending Keep Alive Message to {" + pccIpAddress.toString() + "}");
+ pc.sendMessage(Collections.singletonList(pc.factory().buildKeepaliveMsg().build()));
+ break;
+ case PATH_COMPUTATION_REQUEST:
+ break;
+ case PATH_COMPUTATION_REPLY:
+ break;
+ case NOTIFICATION:
+ break;
+ case ERROR:
+ break;
+ case CLOSE:
+ //log.debug("Sending Close Message to { }", pccIpAddress.toString());
+ pc.sendMessage(Collections.singletonList(pc.factory().buildCloseMsg().build()));
+ break;
+ case INITIATE:
+ if (!pc.capability().pcInstantiationCapability()) {
+ pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+ ERROR_TYPE_19, ERROR_VALUE_5)));
+ }
+ break;
+ case REPORT:
+ //Only update the listener if respective capability is supported else send PCEP-ERR msg
+ if (pc.capability().statefulPceCapability()) {
+ for (PcepEventListener l : pcepEventListener) {
+ l.handleMessage(pccId, msg);
+ }
+ } else {
+ // Send PCEP-ERROR message.
+ pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+ ERROR_TYPE_19, ERROR_VALUE_5)));
+ }
+ break;
+ case UPDATE:
+ if (!pc.capability().statefulPceCapability()) {
+ pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+ ERROR_TYPE_19, ERROR_VALUE_5)));
+ }
+ break;
+ case LABEL_UPDATE:
+ if (!pc.capability().pceccCapability()) {
+ pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+ ERROR_TYPE_19, ERROR_VALUE_5)));
+ }
+ break;
+ case MAX:
+ break;
+ case END:
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void closeConnectedClients() {
+ PcepClient pc;
+ for (PccId id : connectedClients.keySet()) {
+ pc = getClient(id);
+ pc.disconnectClient();
+ }
+ }
+
+ private PcepErrorMsg getErrMsg(PcepFactory factory, byte errorType, byte errorValue) {
+ LinkedList<PcepError> llPcepErr = new LinkedList<>();
+
+ LinkedList<PcepErrorObject> llerrObj = new LinkedList<>();
+ PcepErrorMsg errMsg;
+
+ PcepErrorObject errObj = factory.buildPcepErrorObject().setErrorValue(errorValue).setErrorType(errorType)
+ .build();
+
+ llerrObj.add(errObj);
+ PcepError pcepErr = factory.buildPcepError().setErrorObjList(llerrObj).build();
+
+ llPcepErr.add(pcepErr);
+
+ PcepErrorInfo errInfo = factory.buildPcepErrorInfo().setPcepErrorList(llPcepErr).build();
+
+ errMsg = factory.buildPcepErrorMsg().setPcepErrorInfo(errInfo).build();
+ return errMsg;
+ }
+
+ /**
+ * Implementation of an Pcep Agent which is responsible for
+ * keeping track of connected clients and the state in which
+ * they are.
+ */
+ public class PcepClientAgent implements PcepAgent {
+
+ @Override
+ public boolean addConnectedClient(PccId pccId, PcepClient pc) {
+
+ if (connectedClients.get(pccId) != null) {
+ return false;
+ } else {
+ connectedClients.put(pccId, pc);
+ for (PcepClientListener l : pcepClientListener) {
+ l.clientConnected(pccId);
+ }
+ return true;
+ }
+ }
+
+ @Override
+ public boolean validActivation(PccId pccId) {
+ if (connectedClients.get(pccId) == null) {
+ //log.error("Trying to activate client but is not in "
+ // + "connected switches: pccIp {}. Aborting ..", pccIpAddress.toString());
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public void removeConnectedClient(PccId pccId) {
+ connectedClients.remove(pccId);
+ for (PcepClientListener l : pcepClientListener) {
+ //log.warn("removal for {}", pccIpAddress.toString());
+ l.clientDisconnected(pccId);
+ }
+ }
+
+ @Override
+ public void processPcepMessage(PccId pccId, PcepMessage m) {
+ processClientMessage(pccId, m);
+ }
+
+ @Override
+ public void addNode(PcepClient pc) {
+ for (PcepNodeListener l : pcepNodeListener) {
+ l.addNode(pc);
+ }
+ }
+
+ @Override
+ public void deleteNode(PccId pccId) {
+ for (PcepNodeListener l : pcepNodeListener) {
+ l.deleteNode(pccId);
+ }
+ }
+
+ @Override
+ public boolean analyzeSyncMsgList(PccId pccId) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+ }
+
+ @Override
+ public void addPacketListener(PcepPacketListener listener) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void removePacketListener(PcepPacketListener listener) {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepControllerAdapter.java b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepControllerAdapter.java
new file mode 100644
index 0000000..6b8bda9
--- /dev/null
+++ b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepControllerAdapter.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.provider.pcep.topology.impl;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.pcep.api.PcepController;
+import org.onosproject.pcep.api.PcepDpid;
+import org.onosproject.pcep.api.PcepLinkListener;
+import org.onosproject.pcep.api.PcepSwitch;
+import org.onosproject.pcep.api.PcepSwitchListener;
+import org.onosproject.pcep.api.PcepTunnel;
+import org.onosproject.pcep.api.PcepTunnelListener;
+
+/**
+ * Implementation of PCEP controller.
+ */
+public class PcepControllerAdapter implements PcepController {
+
+ @Override
+ public Iterable<PcepSwitch> getSwitches() {
+ return null;
+ }
+
+ @Override
+ public PcepSwitch getSwitch(PcepDpid did) {
+ return null;
+ }
+
+ @Override
+ public void addListener(PcepSwitchListener listener) {
+
+ }
+
+ @Override
+ public void removeListener(PcepSwitchListener listener) {
+ }
+
+ @Override
+ public void addLinkListener(PcepLinkListener listener) {
+ }
+
+ @Override
+ public void removeLinkListener(PcepLinkListener listener) {
+ }
+
+ @Override
+ public void addTunnelListener(PcepTunnelListener listener) {
+ }
+
+ @Override
+ public void removeTunnelListener(PcepTunnelListener listener) {
+ }
+
+ @Override
+ public PcepTunnel applyTunnel(DeviceId srcDid, DeviceId dstDid, long srcPort, long dstPort, long bandwidth,
+ String name) {
+ return null;
+ }
+
+ @Override
+ public Boolean deleteTunnel(String id) {
+ return null;
+ }
+
+ @Override
+ public Boolean updateTunnelBandwidth(String id, long bandwidth) {
+ return null;
+ }
+
+ @Override
+ public void getTunnelStatistics(String pcepTunnelId) {
+
+ }
+}
diff --git a/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProviderTest.java b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProviderTest.java
new file mode 100644
index 0000000..65a4c02
--- /dev/null
+++ b/providers/pcep/topology/src/test/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProviderTest.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.onosproject.provider.pcep.topology.impl;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.net.Link.State.ACTIVE;
+import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.LABEL_STACK_CAPABILITY;
+import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.LSRID;
+import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.PCECC_CAPABILITY;
+import static org.onosproject.provider.pcep.topology.impl.PcepTopologyProvider.SR_CAPABILITY;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.ChassisId;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceProvider;
+import org.onosproject.net.device.DeviceProviderRegistry;
+import org.onosproject.net.device.DeviceProviderService;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.device.PortStatistics;
+import org.onosproject.net.link.LinkDescription;
+import org.onosproject.net.link.LinkProvider;
+import org.onosproject.net.link.LinkProviderRegistry;
+import org.onosproject.net.link.LinkProviderService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcep.controller.PcepClient;
+import org.onosproject.pcep.controller.PcepNodeListener;
+
+/**
+ * Test for PCEP topology provider.
+ */
+public class PcepTopologyProviderTest {
+ private static final String UNKNOWN = new String("unknown");
+ public static ProviderId providerId = new ProviderId("l3", "foo");
+ private final PcepClientControllerAdapter clientController = new PcepClientControllerAdapter();
+ private final PcepTopologyProvider provider = new PcepTopologyProvider();
+ private final MockDeviceRegistry nodeRegistry = new MockDeviceRegistry();
+ private final PcepControllerAdapter controller = new PcepControllerAdapter();
+ private final MockLinkRegistry linkRegistry = new MockLinkRegistry();
+ private final MockDeviceService deviceService = new MockDeviceService();
+ private Map<DeviceId, Device> deviceMap = new HashMap<>();
+
+ @Before
+ public void startUp() {
+ provider.pcepClientController = clientController;
+ provider.deviceProviderRegistry = nodeRegistry;
+ provider.linkProviderRegistry = linkRegistry;
+ provider.controller = controller;
+ provider.deviceService = deviceService;
+ provider.activate();
+ }
+
+ @After
+ public void tearDown() {
+ provider.deactivate();
+ provider.deviceProviderRegistry = null;
+ provider.pcepClientController = null;
+ provider.linkProviderRegistry = null;
+ provider.controller = null;
+ provider.deviceService = null;
+ }
+
+ /* Class implement device test registry */
+ private class MockLinkRegistry implements LinkProviderRegistry {
+ LinkProvider linkProvider;
+ Set<Link> links = new HashSet<>();
+
+ @Override
+ public LinkProviderService register(LinkProvider provider) {
+ this.linkProvider = provider;
+ return new MockProviderService();
+ }
+
+ @Override
+ public void unregister(LinkProvider provider) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public Set<ProviderId> getProviders() {
+ return null;
+ }
+
+ private class MockProviderService implements LinkProviderService {
+
+ @Override
+ public void linkDetected(LinkDescription linkDescription) {
+ links.add(DefaultLink.builder().src(linkDescription.src())
+ .dst(linkDescription.dst()).state(ACTIVE).type(linkDescription.type())
+ .providerId(ProviderId.NONE).build());
+ }
+
+ @Override
+ public void linkVanished(LinkDescription linkDescription) {
+ links.remove(DefaultLink.builder().src(linkDescription.src())
+ .dst(linkDescription.dst()).state(ACTIVE).type(linkDescription.type())
+ .providerId(ProviderId.NONE).build());
+ }
+
+ @Override
+ public void linksVanished(ConnectPoint connectPoint) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void linksVanished(DeviceId deviceId) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public LinkProvider provider() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ }
+ }
+
+ /* Class implement device test registry */
+ private class MockDeviceRegistry implements DeviceProviderRegistry {
+ DeviceProvider provider;
+
+ Set<DeviceId> connected = new HashSet<>();
+
+ @Override
+ public DeviceProviderService register(DeviceProvider provider) {
+ this.provider = provider;
+ return new MockProviderService();
+ }
+
+ @Override
+ public void unregister(DeviceProvider provider) {
+ }
+
+ @Override
+ public Set<ProviderId> getProviders() {
+ return null;
+ }
+
+ private class MockProviderService implements DeviceProviderService {
+
+ @Override
+ public DeviceProvider provider() {
+ return null;
+ }
+
+ @Override
+ public void deviceConnected(DeviceId deviceId, DeviceDescription deviceDescription) {
+ connected.add(deviceId);
+ Device device = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.ROUTER, UNKNOWN, UNKNOWN,
+ UNKNOWN, UNKNOWN, new ChassisId(), deviceDescription.annotations());
+ deviceMap.put(deviceId, device);
+ }
+
+ @Override
+ public void deviceDisconnected(DeviceId deviceId) {
+ connected.remove(deviceId);
+ deviceMap.remove(deviceId);
+ }
+
+ @Override
+ public void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void portStatusChanged(DeviceId deviceId, PortDescription portDescription) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
+ // TODO Auto-generated method stub
+ }
+ }
+ }
+
+ /* Mock test for device service */
+ private class MockDeviceService extends DeviceServiceAdapter {
+ @Override
+ public Device getDevice(DeviceId deviceId) {
+ return deviceMap.get(deviceId);
+ }
+ }
+
+ /**
+ * Adds the PCEP device and removes it.
+ */
+ @Test
+ public void testPcepTopologyProviderTestAddDevice1() {
+ PcepClient pc = clientController.getClient(PccId.pccId(IpAddress.valueOf("1.1.1.1")));
+ for (PcepNodeListener l : clientController.pcepNodeListener) {
+ pc.setCapability(new ClientCapability(true, true, false, true, true));
+ l.addNode(pc);
+ assertThat(nodeRegistry.connected.size(), is(1));
+ assertThat(deviceMap.keySet().iterator().next(), is(DeviceId.deviceId("l3:1.1.1.1")));
+ assertThat(deviceMap.values().iterator().next().annotations().value(LABEL_STACK_CAPABILITY), is("true"));
+ assertThat(deviceMap.values().iterator().next().annotations().value(LSRID), is("1.1.1.1"));
+ assertThat(deviceMap.values().iterator().next().annotations().value(PCECC_CAPABILITY), is("true"));
+ assertThat(deviceMap.values().iterator().next().annotations().value(SR_CAPABILITY), is("true"));
+
+ l.deleteNode(pc.getPccId());
+ assertThat(nodeRegistry.connected.size(), is(0));
+ }
+ }
+}
diff --git a/providers/pcep/tunnel/BUCK b/providers/pcep/tunnel/BUCK
index ce09ba2..465f5fd 100644
--- a/providers/pcep/tunnel/BUCK
+++ b/providers/pcep/tunnel/BUCK
@@ -6,6 +6,7 @@
'//incubator/api:onos-incubator-api',
'//protocols/pcep/pcepio:onos-protocols-pcep-pcepio',
'//protocols/pcep/api:onos-protocols-pcep-api',
+ '//protocols/pcep/ctl:onos-protocols-pcep-ctl',
]
TEST_DEPS = [
diff --git a/providers/pcep/tunnel/pom.xml b/providers/pcep/tunnel/pom.xml
index 2a72154..5241bb8 100644
--- a/providers/pcep/tunnel/pom.xml
+++ b/providers/pcep/tunnel/pom.xml
@@ -49,5 +49,10 @@
<version>${project.version} </version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-pcep-controller-impl</artifactId>
+ <version>${project.version} </version>
+ </dependency>
</dependencies>
</project>
diff --git a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
index cb1922a..c77187a 100644
--- a/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
+++ b/providers/pcep/tunnel/src/main/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProvider.java
@@ -36,6 +36,7 @@
import org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.Tunnel.State;
+import org.onosproject.incubator.net.tunnel.TunnelAdminService;
import org.onosproject.incubator.net.tunnel.TunnelDescription;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelId;
@@ -45,11 +46,14 @@
import org.onosproject.incubator.net.tunnel.TunnelProviderService;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.incubator.net.tunnel.TunnelStatistics;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultAnnotations.Builder;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
+import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.IpElementId;
@@ -57,6 +61,7 @@
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.device.DeviceService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcep.api.PcepController;
@@ -68,12 +73,14 @@
import org.onosproject.pcep.api.PcepTunnel.PathType;
import org.onosproject.pcep.api.PcepTunnelListener;
import org.onosproject.pcep.api.PcepTunnelStatistics;
+import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcep.controller.PcepClientListener;
import org.onosproject.pcep.controller.PcepEventListener;
-import org.onosproject.pcep.controller.PcepSyncStatus;
+import org.onosproject.pcep.controller.PcepLspSyncAction;
+import org.onosproject.pcep.controller.impl.PcepLspStatus;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
import org.onosproject.pcepio.protocol.PcepAttribute;
@@ -83,6 +90,7 @@
import org.onosproject.pcepio.protocol.PcepInitiateMsg;
import org.onosproject.pcepio.protocol.PcepLspObject;
import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepMetricObject;
import org.onosproject.pcepio.protocol.PcepMsgPath;
import org.onosproject.pcepio.protocol.PcepReportMsg;
import org.onosproject.pcepio.protocol.PcepSrpObject;
@@ -107,8 +115,10 @@
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
-import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
@@ -125,14 +135,18 @@
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LSP_SIG_TYPE;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCC_TUNNEL_ID;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PLSP_ID;
-import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCE_INIT;
+import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.DELEGATE;
+import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.COST_TYPE;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.CREATE;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.DELETE;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.LSP_STATE_RPT;
import static org.onosproject.provider.pcep.tunnel.impl.RequestType.UPDATE;
-import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
-import static org.onosproject.pcep.controller.PcepSyncStatus.SYNCED;
import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
+import static org.onosproject.pcep.controller.PcepLspSyncAction.REMOVE;
+import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_UPDATE;
+import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_DELETE;
+import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.IGP_METRIC;
+import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.TE_METRIC;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -148,6 +162,11 @@
private static final long MIN_BANDWIDTH = 64;
private static final String BANDWIDTH_UINT = "kbps";
static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
+ public static final long IDENTIFIER_SET = 0x100000000L;
+ public static final long SET = 0xFFFFFFFFL;
+ private static final int DELAY = 2;
+ private static final int WAIT_TIME = 5;
+ public static final String LSRID = "lsrId";
static final int POLL_INTERVAL = 10;
@Property(name = "tunnelStatsPollFrequency", intValue = POLL_INTERVAL,
@@ -171,6 +190,15 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ComponentConfigService cfgService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected TunnelAdminService tunnelAdminService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MastershipService mastershipService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
TunnelProviderService service;
HashMap<String, TunnelId> tunnelMap = new HashMap<String, TunnelId>();
@@ -182,10 +210,6 @@
protected PcepTunnelApiMapper pcepTunnelApiMapper = new PcepTunnelApiMapper();
private static final int DEFAULT_BANDWIDTH_VALUE = 10;
- private Map<IpAddress, Map<TunnelId, Tunnel>> preSyncLspDbMap = new HashMap<>();
- private Map<IpAddress, List<Tunnel>> syncCompleteDeleteList = new HashMap<>();
- private Map<IpAddress, List<Tunnel>> syncCompleteUpdateList = new HashMap<>();
-
/**
* Creates a Tunnel provider.
*/
@@ -263,7 +287,8 @@
}
//If stateful and PC Initiation capability is not supported by client not sending Initiate msg
- if (pc.capability().pcInstantiationCapability()) {
+ //Only master will initiate setup tunnel
+ if (pc.capability().pcInstantiationCapability() && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
pcepSetupTunnel(tunnel, path, pc);
}
}
@@ -300,7 +325,10 @@
return;
}
- if (pc.capability().pcInstantiationCapability()) {
+ //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
+ //Only master will initiate setup tunnel
+ if (pc.capability().pcInstantiationCapability()
+ && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
pcepSetupTunnel(tunnel, path, pc);
}
}
@@ -327,7 +355,9 @@
return;
}
- if (pc.capability().pcInstantiationCapability()) {
+ //Only master will release tunnel
+ if (pc.capability().pcInstantiationCapability()
+ && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
pcepReleaseTunnel(tunnel, pc);
}
}
@@ -358,7 +388,9 @@
return;
}
- if (pc.capability().pcInstantiationCapability()) {
+ //Only master will release tunnel
+ if (pc.capability().pcInstantiationCapability()
+ && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
pcepReleaseTunnel(tunnel, pc);
}
}
@@ -384,7 +416,12 @@
return;
}
- if (pc.capability().statefulPceCapability()) {
+ // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
+ // LSP].If annotation is null D flag is not set else it is set.
+ if (pc.capability().statefulPceCapability()
+ && pc.delegationInfo(
+ new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
+ .annotations().value(LOCAL_LSP_ID)))) != null) {
pcepUpdateTunnel(tunnel, path, pc);
}
}
@@ -416,7 +453,12 @@
return;
}
- if (pc.capability().statefulPceCapability()) {
+ // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
+ // LSP].If annotation is null D flag is not set else it is set.
+ if (pc.capability().statefulPceCapability()
+ && pc.delegationInfo(
+ new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
+ .annotations().value(LOCAL_LSP_ID)))) != null) {
pcepUpdateTunnel(tunnel, path, pc);
}
}
@@ -480,6 +522,43 @@
return tunnelId;
}
+ private void tunnelUpdated(Tunnel tunnel, Path path) {
+ handleTunnelUpdate(tunnel, path);
+ }
+
+ //Handles tunnel updated using tunnel admin service[specially to update annotations].
+ private void handleTunnelUpdate(Tunnel tunnel, Path path) {
+
+ if (tunnel.type() == MPLS) {
+ pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.tunnelId());
+
+ tunnelAdminService.updateTunnel(tunnel, path);
+
+ return;
+ }
+
+ Tunnel tunnelOld = tunnelQueryById(tunnel.tunnelId());
+ if (tunnelOld.type() != Tunnel.Type.VLAN) {
+ error("Illegal tunnel type. Only support VLAN tunnel update.");
+ return;
+ }
+
+ long bandwidth = Long
+ .parseLong(tunnel.annotations().value("bandwidth"));
+ if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
+ error("Update failed, invalid bandwidth.");
+ return;
+ }
+ String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
+
+ checkNotNull(pcepTunnelId, "Invalid tunnel id");
+ if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
+ error("Update failed,maybe invalid bandwidth.");
+ return;
+ }
+ tunnelAdminService.updateTunnel(tunnel, path);
+ }
+
@Override
public void tunnelRemoved(TunnelDescription tunnel) {
if (tunnel.type() == MPLS) {
@@ -681,7 +760,6 @@
path,
annotations);
return tunnel;
-
}
/**
@@ -1098,41 +1176,8 @@
log.debug("SRP ID in handle message " + srpId);
if (!(pcepTunnelApiMapper.checkFromTunnelRequestQueue(srpId))) {
-
- // Check the sync status
- if (lspObj.getSFlag()) {
- if (pcepClientController.getClient(pccId).lspDbSyncStatus() != IN_SYNC) {
- pcepClientController.getClient(pccId).setLspDbSyncStatus(IN_SYNC);
-
- // On starting LSP-DB sync, store LSP DB locally for this PCC.
- Map<TunnelId, Tunnel> preSyncLspDb = new HashMap<>();
- Collection<Tunnel> queriedTunnels = tunnelService.queryTunnel(MPLS);
-
- for (Tunnel tunnel : queriedTunnels) {
- if (((IpTunnelEndPoint) tunnel.src()).ip().equals(pccId.ipAddress())) {
- preSyncLspDb.put(tunnel.tunnelId(), tunnel);
- }
- }
-
- preSyncLspDbMap.put(pccId.ipAddress(), preSyncLspDb);
- syncCompleteDeleteList.put(pccId.ipAddress(), new LinkedList<>());
- syncCompleteUpdateList.put(pccId.ipAddress(), new LinkedList<>());
- }
- handleRptWithoutSrpId(stateRpt, pccId, IN_SYNC);
- continue;
-
- } else if (pcepClientController.getClient(pccId).lspDbSyncStatus() == IN_SYNC) {
- // If sync flag is not set in the msg, and the
- // previous state was "in sync" means this is
- // end of sync message. PCRpt for end of sync
- // does not carry any LSP report.
- pcepClientController.getClient(pccId).setLspDbSyncStatus(SYNCED);
- handleEndOfSyncAction(pccId);
- continue;
- }
-
- // For PCRpt without matching SRP id not during LSPDB sync.
- handleRptWithoutSrpId(stateRpt, pccId, SYNCED);
+ // For PCRpt without matching SRP id.
+ handleRptWithoutSrpId(stateRpt, pccId);
continue;
}
@@ -1226,27 +1271,30 @@
}
}
- private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId, PcepSyncStatus syncStatus) {
- ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
- PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
- checkNotNull(msgPath);
- PcepEroObject eroObj = msgPath.getEroObject();
- if (eroObj == null) {
- log.error("ERO object is null in report message.");
- return;
- }
- Path path = buildPathFromEroObj(eroObj, providerId);
+ private SparseAnnotations getAnnotations(PcepLspObject lspObj, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv,
+ float bandwidth, LspType lspType, String costType) {
- int bandwidth = 0;
- if (msgPath.getBandwidthObject() != null) {
- bandwidth = msgPath.getBandwidthObject().getBandwidth();
- }
+ Builder builder = DefaultAnnotations.builder();
/*
- * To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
- * from PCE.
+ * [RFC 5440] The absence of the METRIC object MUST be interpreted by the PCE as a path computation request
+ * for which no constraints need be applied to any of the metrics.
*/
- PcepSrpObject srpObj = stateRpt.getSrpObject();
+ if (costType != null) {
+ builder.set(COST_TYPE, costType);
+ }
+
+ SparseAnnotations annotations = builder
+ .set(BANDWIDTH, (new Float(bandwidth)).toString()).set(LSP_SIG_TYPE, lspType.name())
+ .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
+ .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
+ .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId()))
+ .set(DELEGATE, String.valueOf(lspObj.getDFlag()))
+ .build();
+ return annotations;
+ }
+
+ private LspType getLspType(PcepSrpObject srpObj) {
LspType lspType = WITH_SIGNALLING;
if (null != srpObj) {
@@ -1266,6 +1314,55 @@
}
}
}
+ return lspType;
+ }
+
+ private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId) {
+ ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
+ String costType = null;
+ PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
+ checkNotNull(msgPath);
+ PcepEroObject eroObj = msgPath.getEroObject();
+ if (eroObj == null) {
+ log.error("ERO object is null in report message.");
+ return;
+ }
+
+ PcepAttribute attributes = msgPath.getPcepAttribute();
+ int cost = 0;
+ if (attributes != null && attributes.getMetricObjectList() != null) {
+ ListIterator<PcepMetricObject> iterator = attributes.getMetricObjectList().listIterator();
+ PcepMetricObject metricObj = iterator.next();
+
+ while (metricObj != null) {
+ if (metricObj.getBType() == IGP_METRIC) {
+ costType = "COST";
+ } else if (metricObj.getBType() == TE_METRIC) {
+ costType = "TE_COST";
+ }
+
+ if (costType != null) {
+ cost = metricObj.getMetricVal();
+ log.debug("Path cost {}", cost);
+ break;
+ }
+ metricObj = iterator.next();
+ }
+ }
+
+ Path path = buildPathFromEroObj(eroObj, providerId, cost);
+
+ float bandwidth = 0;
+ if (msgPath.getBandwidthObject() != null) {
+ bandwidth = msgPath.getBandwidthObject().getBandwidth();
+ }
+
+ /*
+ * To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
+ * from PCE.
+ */
+ PcepSrpObject srpObj = stateRpt.getSrpObject();
+ LspType lspType = getLspType(srpObj);
PcepLspObject lspObj = stateRpt.getLspObject();
ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
@@ -1287,7 +1384,6 @@
break;
}
}
-
/*
* Draft says: The LSP-IDENTIFIERS TLV MUST be included in the LSP object in PCRpt messages for
* RSVP-signaled LSPs. For ONOS PCECC implementation, it is mandatory.
@@ -1303,6 +1399,14 @@
.ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
+ // Store delegation flag info and that LSP info because only delegated PCE sends update message
+ // Storing if D flag is set, if not dont store. while checking whether delegation if annotation for D flag
+ // not present then non-delegated , if present it is delegated.
+ if (lspObj.getDFlag()) {
+ pcepClientController.getClient(pccId).setLspAndDelegationInfo(
+ new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId()), lspObj.getDFlag());
+ }
+
Tunnel tunnel = null;
// Asynchronous status change message from PCC for LSP reported earlier.
for (Tunnel tunnelObj : tunnelQueryResult) {
@@ -1321,7 +1425,6 @@
}
continue;
}
-
if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId()) && (Integer
.valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
tunnel = tunnelObj;
@@ -1330,6 +1433,7 @@
}
DefaultTunnelDescription td;
+ SparseAnnotations annotations = null;
State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
if (tunnel == null) {
if (lspObj.getRFlag()) {
@@ -1340,91 +1444,96 @@
return;
}
- if (lspObj.getCFlag()) {
- /*
- * While in sync, if PCRpt is received for PCE init LSP and PCE doesn't have entry, mark to send
- * delete message on end of sync.
- */
- SparseAnnotations annotations = DefaultAnnotations.builder()
- .set(BANDWIDTH, (new Integer(bandwidth)).toString())
- .set(LSP_SIG_TYPE, lspType.name())
- .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
- .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
- .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId())).build();
+ DeviceId deviceId = getDevice(pccId);
+ if (deviceId == null) {
+ log.error("Ingress deviceId not found");
+ return;
+ }
+ annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
- // Gnenerate tunnel id for the temporary tunnel.
- String onosTunnelId = "PCC" + String.valueOf(ipv4LspIdenTlv.getTunnelId());
- Tunnel tunnelToBeDeleted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
- new DefaultGroupId(0), TunnelId.valueOf(onosTunnelId),
- TunnelName.tunnelName(String
- .valueOf(pathNameTlv.getValue())),
- path, annotations);
+ td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
+ 0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
+ annotations);
- /*
- * Need to send PCInitiate delete msg for a tunnel which does not exist at PCE. For that some dummy
- * data-structures need to be populated.
- */
- PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelToBeDeleted, path, RequestType.DELETE);
- pcepTunnelData.setPlspId(lspObj.getPlspId());
- pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
- pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
- pcepTunnelApiMapper.handleCreateTunnelRequestQueue(0, pcepTunnelData);
-
- /*
- * Add to the list of tunnels for which PCInit delete will be sent at the end of sync.
- */
- List<Tunnel> tunnelToBeDeletedList = syncCompleteDeleteList.get(pccId.ipAddress());
- tunnelToBeDeletedList.add(tunnelToBeDeleted);
- syncCompleteDeleteList.put(pccId.ipAddress(), tunnelToBeDeletedList);
+ // Do not support PCC initiated LSP after LSP DB sync is completed.
+ if (!lspObj.getSFlag() && !lspObj.getCFlag()) {
+ log.error("Received PCC initiated LSP while not in sync.");
return;
}
- SparseAnnotations annotations = DefaultAnnotations.builder()
- .set(BANDWIDTH, (new Integer(bandwidth)).toString())
- .set(LSP_SIG_TYPE, lspType.name())
- .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
- .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
- .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId())).build();
+ /*
+ * If ONOS instance is master for PCC then set delegated flag as annotation and add the tunnel to store.
+ * Because all LSPs need not be delegated, hence mastership for the PCC is confirmed whereas not the
+ * delegation set to all LSPs.If ONOS is not the master for that PCC then check if D flag is set, if yes
+ * wait for 2 seconds [while master has added the tunnel to the store] then update the tunnel. Tunnel is
+ * updated because in case of resilency only delegated LSPs are recomputed and only delegated PCE can
+ * send update message to that client.
+ *
+ * 1)Master can 1st get the Rpt message
+ * a)Master adds the tunnel into core.
+ * b)If a non-master for ingress gets Rpt message with D flag set[as delegation owner]
+ * after master, then runs timer then update the tunnel with D flag set.
+ * 2)Non-Master can 1st get the Rpt message
+ * a)Non-Master runs the timer check for the tunnel then updates the tunnel with D flag set
+ * b)Master would have got the message while the non-master running timer, hence master adds
+ * tunnel to core
+ *
+ * In general always master adds the tunnel to the core
+ * while delegated owner [master or non-master with D flag set] always updates the tunnel running timer
+ */
+ if (mastershipService.isLocalMaster(deviceId)) {
+ TunnelId tId = tunnelAdded(td, tunnelState);
+ Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
+ tunnelState, new DefaultGroupId(0), tId, TunnelName.tunnelName(String.valueOf(pathNameTlv
+ .getValue())), path, annotations);
- td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
- new DefaultGroupId(0), providerId,
- TunnelName.tunnelName(String.valueOf(pathNameTlv.getValue())), path,
- annotations);
-
- TunnelId tId = tunnelAdded(td, tunnelState);
- Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
- tunnelState, new DefaultGroupId(0), tId,
- TunnelName.tunnelName(String.valueOf(pathNameTlv.getValue())),
- path, annotations);
-
- PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
- pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
- pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
+ PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
+ pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
+ pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
+ } else if (!mastershipService.isLocalMaster(deviceId) && lspObj.getDFlag()) {
+ //Start timer then update the tunnel with D flag
+ tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
+ }
return;
}
- if ((syncStatus == IN_SYNC) && (lspObj.getCFlag()) && (tunnelState != tunnel.state())) {
- // Mark to send PCUpd msg with state known at PCE.
- List<Tunnel> tunnelToBeUpdateList = syncCompleteUpdateList.get(pccId.ipAddress());
- tunnelToBeUpdateList.add(tunnel);
- syncCompleteUpdateList.put(pccId.ipAddress(), tunnelToBeUpdateList);
- return;
+ //delegated owner will update can be a master or non-master
+ if (lspObj.getDFlag()) {
+ annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
+ td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
+ 0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
+ annotations);
+ tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
}
+ removeOrUpdatetunnel(tunnel, pccId, lspObj, providerId, tunnelState);
+ return;
+ }
- td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
- tunnel.type(), tunnel.groupId(), providerId,
- tunnel.tunnelName(), tunnel.path(),
- (SparseAnnotations) tunnel.annotations());
-
+ private void removeOrUpdatetunnel(Tunnel tunnel, PccId pccId, PcepLspObject lspObj, ProviderId providerId,
+ State tunnelState) {
+ DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
+ tunnel.type(), tunnel.groupId(), providerId, tunnel.tunnelName(), tunnel.path(),
+ (SparseAnnotations) tunnel.annotations());
if (lspObj.getRFlag()) {
tunnelRemoved(td);
} else {
- if (syncStatus == IN_SYNC) {
- markLspDbEntryAsLatest(pccId, tunnel.tunnelId());
- }
tunnelUpdated(td, tunnelState);
}
- return;
+ }
+
+ private void tunnelUpdateInDelegatedCase(PccId pccId, SparseAnnotations annotations,
+ DefaultTunnelDescription td, ProviderId providerId) {
+ //Wait for 2sec then query tunnel based on ingress PLSP-ID and local LSP-ID
+
+ /*
+ * If ONOS is not the master for that PCC then check if D flag is set, if yes wait [while
+ * master has added the tunnel to the store] then update the tunnel.
+ */
+ ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+
+ // Thread is started after 2 seconds first time later periodically after 2 seconds to update the tunnel
+ executor.scheduleAtFixedRate(new UpdateDelegation(td, providerId, annotations, pccId,
+ executor), DELAY, DELAY, TimeUnit.SECONDS);
}
/**
@@ -1432,9 +1541,10 @@
*
* @param eroObj ERO object
* @param providerId provider id
+ * @param cost cost of path
* @return path object
*/
- private Path buildPathFromEroObj(PcepEroObject eroObj, ProviderId providerId) {
+ private Path buildPathFromEroObj(PcepEroObject eroObj, ProviderId providerId, int cost) {
checkNotNull(eroObj);
List<Link> links = new ArrayList<Link>();
LinkedList<PcepValueType> llSubObj = eroObj.getSubObjects();
@@ -1474,7 +1584,8 @@
// the other sub objects are not required
}
}
- return new DefaultPath(providerId, links, 0, EMPTY);
+
+ return new DefaultPath(providerId, links, cost, EMPTY);
}
@Override
@@ -1493,44 +1604,14 @@
TunnelStatistics tunnelStatistics = buildTunnelStatistics(pcepTunnelStatistics);
tunnelStatisticsMap.put(id, tunnelStatistics);
}
- }
- @Override
- public Tunnel tunnelQueryById(TunnelId tunnelId) {
- return service.tunnelQueryById(tunnelId);
- }
+ @Override
+ public void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction) {
- /**
- * Removes the entry from temporary copy of LSPDB, signifying its status as upto date.
- *
- * @param pccId the key for temporary LSPDB
- * @param tunnelId the tunnel id for which information is updated.
- */
- private void markLspDbEntryAsLatest(PccId pccId, TunnelId tunnelId) {
- checkNotNull(pccId);
- checkNotNull(tunnelId);
-
- Map<TunnelId, Tunnel> preSyncLspDb = preSyncLspDbMap.get(pccId.ipAddress());
- checkNotNull(preSyncLspDb);
-
- preSyncLspDb.remove(tunnelId);
- preSyncLspDbMap.put(pccId.ipAddress(), preSyncLspDb);
- }
-
- /**
- * Sends PCInit, PCInit(R) or PCUpd messages for initiated LSPs at the end
- * of LSP DB sync based on actions decided while sync was in progress. Also
- * triggers label DB sync.
- *
- * @param pccId the key for temporary DBs storing required end of sync
- * actions.
- */
- private void handleEndOfSyncAction(PccId pccId) {
-
- Map<TunnelId, Tunnel> preSyncLspDb = preSyncLspDbMap.get(pccId.ipAddress());
- checkNotNull(preSyncLspDb);
-
- for (Tunnel tunnel : preSyncLspDb.values()) {
+ if (endOfSyncAction == SEND_UPDATE) {
+ updateTunnel(tunnel, tunnel.path());
+ return;
+ }
TunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(),
tunnel.src(), tunnel.dst(),
@@ -1541,41 +1622,133 @@
tunnel.path(),
(SparseAnnotations) tunnel.annotations());
- if ((tunnel.annotations().value(PCE_INIT) == null)
- || (tunnel.annotations().value(PCE_INIT).equals("false"))) {
- tunnelRemoved(td);
- } else {
+ if (endOfSyncAction == PcepLspSyncAction.UNSTABLE) {
+
// Send PCInit msg again after global reoptimization.
tunnelUpdated(td, UNSTABLE);
// To remove the old tunnel from store whose PLSPID is not
// recognized by ingress PCC.
tunnelRemoved(td);
+
+ } else if (endOfSyncAction == REMOVE) {
+ tunnelRemoved(td);
}
}
- List<Tunnel> tunnelsToBeDeletedList = syncCompleteDeleteList.get(pccId.ipAddress());
- checkNotNull(tunnelsToBeDeletedList);
- for (Tunnel tunnel: tunnelsToBeDeletedList) {
- releaseTunnel(tunnel);
+ @Override
+ public void handleEndOfSyncAction(PccId pccId, PcepMessage msg, PcepLspSyncAction endOfSyncAction) {
+ try {
+ if ((msg instanceof PcepInitiateMsg) && (endOfSyncAction == SEND_DELETE)) {
+ PcepClient pc = pcepClientController.getClient(pccId);
+ LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = ((PcepInitiateMsg) msg)
+ .getPcInitiatedLspRequestList();
+ PcInitiatedLspRequest pcInitMsg = llPcInitiatedLspRequestList.iterator().next();
+
+ if (pcInitMsg != null) {
+ PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(SrpIdGenerators.create())
+ .setRFlag(true).build();
+
+ PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest()
+ .setLspObject(pcInitMsg.getLspObject()).setSrpObject(srpobj).build();
+
+ llPcInitiatedLspRequestList.remove(pcInitMsg);
+ llPcInitiatedLspRequestList.add(releaseLspRequest);
+
+ PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
+ .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
+
+ pc.sendMessage(Collections.singletonList(pcInitiateMsg));
+ }
+ }
+ } catch (PcepParseException e) {
+ log.error("Exception occured while sending initiate delete message {}", e.getMessage());
+ }
+ }
+ }
+ @Override
+ public Tunnel tunnelQueryById(TunnelId tunnelId) {
+ return service.tunnelQueryById(tunnelId);
+ }
+
+
+ private DeviceId getDevice(PccId pccId) {
+ // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
+ IpAddress lsrId = pccId.ipAddress();
+ String lsrIdentifier = String.valueOf(lsrId);
+
+ // Find PCC deviceID from lsrId stored as annotations
+ Iterable<Device> devices = deviceService.getAvailableDevices();
+ for (Device dev : devices) {
+ if (dev.annotations().value(AnnotationKeys.TYPE).equals("L3")
+ && dev.annotations().value(LSRID).equals(lsrIdentifier)) {
+ return dev.id();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Updates the tunnel with updated tunnel annotation after a delay of two seconds and checks it till
+ * tunnel is found.
+ */
+ private class UpdateDelegation implements Runnable {
+ DefaultTunnelDescription td;
+ ProviderId providerId;
+ SparseAnnotations annotations;
+ PccId pccId;
+ ScheduledExecutorService executor;
+
+ /**
+ * Creates an instance of UpdateDelegation.
+ *
+ * @param td tunnel description
+ * @param providerId provider id
+ * @param annotations tunnel annotations
+ * @param pccId PCEP client id
+ * @param executor service of delegated owner
+ */
+ public UpdateDelegation(DefaultTunnelDescription td, ProviderId providerId, SparseAnnotations annotations,
+ PccId pccId, ScheduledExecutorService executor) {
+ this.td = td;
+ this.providerId = providerId;
+ this.annotations = annotations;
+ this.pccId = pccId;
+ this.executor = executor;
}
- List<Tunnel> tunnelsToBeUpdatedList = syncCompleteUpdateList.get(pccId.ipAddress());
- checkNotNull(tunnelsToBeUpdatedList);
- for (Tunnel tunnel: tunnelsToBeUpdatedList) {
- updateTunnel(tunnel, tunnel.path());
- }
+ //Temporary using annotations later will use projection/network config service
+ @Override
+ public void run() {
+ Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(td.src(), td.dst());
+ TunnelId tempTunnelId = null;
+ for (Tunnel t : tunnelQueryResult) {
+ if (t.annotations().value(LOCAL_LSP_ID) == null || t.annotations().value(PLSP_ID) == null) {
+ continue;
+ }
- /* On end of sync, empty all temporary data structures. */
- preSyncLspDbMap.remove(pccId.ipAddress());
- syncCompleteDeleteList.remove(pccId.ipAddress());
- syncCompleteUpdateList.remove(pccId.ipAddress());
+ if (t.annotations().value(LOCAL_LSP_ID).equals(td.annotations().value(LOCAL_LSP_ID))
+ && t.annotations().value(PLSP_ID).equals(td.annotations().value(PLSP_ID))
+ && ((IpTunnelEndPoint) t.src()).ip().equals(pccId.id())) {
+ tempTunnelId = t.tunnelId();
+ break;
+ }
+ }
- // TODO: If SR capable, send a notification to
- // PCE APP to start label DB sync.
- if (true) {
- pcepClientController.getClient(pccId).setLabelDbSyncStatus(IN_SYNC);
+ //If tunnel is found update the tunnel and shutdown the thread otherwise thread will be executing
+ //periodically
+ if (tempTunnelId != null) {
+ Tunnel tunnel = new DefaultTunnel(providerId, td.src(), td.dst(), MPLS, new DefaultGroupId(0),
+ tempTunnelId, td.tunnelName(), td.path(), annotations);
+ tunnelUpdated(tunnel, td.path());
+ executor.shutdown();
+ try {
+ executor.awaitTermination(WAIT_TIME, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ log.error("updating delegation failed");
+ }
+ }
}
}
}
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java
index daf315a..aafdfaa 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientAdapter.java
@@ -17,17 +17,22 @@
import static org.junit.Assert.assertNotNull;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.jboss.netty.channel.Channel;
import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepSyncStatus;
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepFactory;
import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepStateReport;
import org.onosproject.pcepio.protocol.PcepVersion;
/**
@@ -45,6 +50,8 @@
private PcepVersion pcepVersion;
private PcepSyncStatus lspDbSyncStatus;
private PcepSyncStatus labelDbSyncStatus;
+ private Map<LspKey, Boolean> lspDelegationInfo = new HashMap<>();
+ private Map<PccId, List<PcepStateReport>> sycRptCache = new HashMap<>();
/**
* Initialize instance with specified parameters.
@@ -139,4 +146,45 @@
public ClientCapability capability() {
return capability;
}
+
+ @Override
+ public void addNode(PcepClient pc) {
+ }
+
+ @Override
+ public void deleteNode(PccId pccId) {
+ }
+
+ @Override
+ public void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag) {
+ lspDelegationInfo.put(lspKey, dFlag);
+ }
+
+ @Override
+ public Boolean delegationInfo(LspKey lspKey) {
+ return lspDelegationInfo.get(lspKey);
+ }
+
+ @Override
+ public void initializeSyncMsgList(PccId pccId) {
+ List<PcepStateReport> rptMsgList = new LinkedList<>();
+ sycRptCache.put(pccId, rptMsgList);
+ }
+
+ @Override
+ public List<PcepStateReport> getSyncMsgList(PccId pccId) {
+ return sycRptCache.get(pccId);
+ }
+
+ @Override
+ public void removeSyncMsgList(PccId pccId) {
+ sycRptCache.remove(pccId);
+ }
+
+ @Override
+ public void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg) {
+ List<PcepStateReport> rptMsgList = sycRptCache.get(pccId);
+ rptMsgList.add(rptMsg);
+ sycRptCache.put(pccId, rptMsgList);
+ }
}
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
index 822d8b6..dd82aac 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
@@ -24,13 +24,13 @@
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Deactivate;
-import org.onlab.packet.IpAddress;
-import org.onosproject.pcep.controller.ClientCapability;
import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcep.controller.PcepClientListener;
import org.onosproject.pcep.controller.PcepEventListener;
+import org.onosproject.pcep.controller.PcepNodeListener;
+import org.onosproject.pcep.controller.PcepPacketListener;
import org.onosproject.pcep.controller.driver.PcepAgent;
import org.onosproject.pcepio.protocol.PcepError;
import org.onosproject.pcepio.protocol.PcepErrorInfo;
@@ -57,6 +57,8 @@
protected Set<PcepClientListener> pcepClientListener = new HashSet<>();
protected Set<PcepEventListener> pcepEventListener = Sets.newHashSet();
+ public Set<PcepNodeListener> pcepNodeListener = Sets.newHashSet();
+ protected Set<PcepPacketListener> pcepPacketListener = Sets.newHashSet();
@Activate
public void activate() {
@@ -73,16 +75,11 @@
@Override
public PcepClient getClient(PccId pccId) {
- if (null != connectedClients.get(pccId)) {
+ if (connectedClients.get(pccId) != null) {
return connectedClients.get(pccId);
}
PcepClientAdapter pc = new PcepClientAdapter();
- if (pccId.ipAddress().equals(IpAddress.valueOf(0xC010103))
- || pccId.ipAddress().equals(IpAddress.valueOf(0xB6024E22))) {
- pc.setCapability(new ClientCapability(true, false, false));
- } else {
- pc.setCapability(new ClientCapability(true, true, true));
- }
+
pc.init(PccId.pccId(pccId.ipAddress()), PcepVersion.PCEP_1);
connectedClients.put(pccId, pc);
return pc;
@@ -96,6 +93,16 @@
}
@Override
+ public void addNodeListener(PcepNodeListener listener) {
+ pcepNodeListener.add(listener);
+ }
+
+ @Override
+ public void removeNodeListener(PcepNodeListener listener) {
+ pcepNodeListener.remove(listener);
+ }
+
+ @Override
public void removeListener(PcepClientListener listener) {
this.pcepClientListener.remove(listener);
}
@@ -111,6 +118,16 @@
}
@Override
+ public void addPacketListener(PcepPacketListener listener) {
+ pcepPacketListener.add(listener);
+ }
+
+ @Override
+ public void removePacketListener(PcepPacketListener listener) {
+ pcepPacketListener.remove(listener);
+ }
+
+ @Override
public void writeMessage(PccId pccId, PcepMessage msg) {
this.getClient(pccId).sendMessage(msg);
}
@@ -254,5 +271,25 @@
public void processPcepMessage(PccId pccId, PcepMessage m) {
processClientMessage(pccId, m);
}
+
+ @Override
+ public void addNode(PcepClient pc) {
+ for (PcepNodeListener l : pcepNodeListener) {
+ l.addNode(pc);
+ }
+ }
+
+ @Override
+ public void deleteNode(PccId pccId) {
+ for (PcepNodeListener l : pcepNodeListener) {
+ l.deleteNode(pccId);
+ }
+ }
+
+ @Override
+ public boolean analyzeSyncMsgList(PccId pccId) {
+ // TODO Auto-generated method stub
+ return false;
+ }
}
}
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java
index ec9c1aa..22a683b 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepReleaseTunnelProviderTest.java
@@ -40,6 +40,7 @@
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelName;
+import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
@@ -49,7 +50,10 @@
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
/**
@@ -64,12 +68,16 @@
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final PcepTunnelApiMapper pcepTunnelAPIMapper = new PcepTunnelApiMapper();
private final TunnelServiceAdapter tunnelService = new TunnelServiceAdapter();
+ private final DeviceServiceAdapter deviceService = new DeviceServiceAdapter();
+ private final MastershipServiceAdapter mastershipService = new MastershipServiceAdapter();
@Before
public void setUp() throws IOException {
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
+ tunnelProvider.deviceService = deviceService;
+ tunnelProvider.mastershipService = mastershipService;
tunnelProvider.tunnelService = tunnelService;
tunnelProvider.pcepTunnelApiMapper = pcepTunnelAPIMapper;
tunnelProvider.cfgService = new ComponentConfigAdapter();
@@ -125,6 +133,8 @@
tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+ controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E20))).setCapability(
+ new ClientCapability(true, true, true, true, true));
tunnelProvider.releaseTunnel(tunnel);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -179,6 +189,8 @@
tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+ controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E22))).setCapability(
+ new ClientCapability(true, false, false, true, true));
tunnelProvider.releaseTunnel(tunnel);
assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
@@ -233,6 +245,8 @@
tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+ controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E20))).setCapability(
+ new ClientCapability(true, true, true, true, true));
tunnelProvider.releaseTunnel(tunnel);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -287,6 +301,8 @@
tunnelProvider.pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+ controller.getClient(PccId.pccId(IpAddress.valueOf(0xB6024E20))).setCapability(
+ new ClientCapability(true, true, true, true, true));
tunnelProvider.releaseTunnel(tunnel);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -298,5 +314,7 @@
tunnelProvider.controller = null;
tunnelProvider.pcepClientController = null;
tunnelProvider.tunnelProviderRegistry = null;
+ tunnelProvider.deviceService = null;
+ tunnelProvider.mastershipService = null;
}
}
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java
index d2c4d5e..078deb1 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepSetupTunnelProviderTest.java
@@ -40,6 +40,7 @@
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelName;
+import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
@@ -49,7 +50,10 @@
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
/**
* Test for PCEP setup tunnel.
@@ -62,12 +66,16 @@
private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final TunnelServiceAdapter tunnelService = new TunnelServiceAdapter();
+ private final DeviceServiceAdapter deviceService = new DeviceServiceAdapter();
+ private final MastershipServiceAdapter mastershipService = new MastershipServiceAdapter();
@Before
public void setUp() throws IOException {
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
+ tunnelProvider.deviceService = deviceService;
+ tunnelProvider.mastershipService = mastershipService;
tunnelProvider.cfgService = new ComponentConfigAdapter();
tunnelProvider.tunnelService = tunnelService;
tunnelProvider.activate();
@@ -111,6 +119,8 @@
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
path, annotations);
+ controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
+ new ClientCapability(true, true, true, true, true));
tunnelProvider.setupTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -154,6 +164,8 @@
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
path, annotations);
+ controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010103))).setCapability(
+ new ClientCapability(true, true, true, true, true));
tunnelProvider.setupTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
@@ -197,6 +209,8 @@
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
path, annotations);
+ controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
+ new ClientCapability(true, true, true, true, true));
tunnelProvider.setupTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -240,6 +254,8 @@
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
path, annotations);
+ controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
+ new ClientCapability(true, true, true, true, true));
tunnelProvider.setupTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
@@ -251,5 +267,7 @@
tunnelProvider.controller = null;
tunnelProvider.pcepClientController = null;
tunnelProvider.tunnelProviderRegistry = null;
+ tunnelProvider.deviceService = null;
+ tunnelProvider.mastershipService = null;
}
}
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java
index 2abab75..ce00b5e 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelAddedTest.java
@@ -24,27 +24,35 @@
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LSP_SIG_TYPE;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCC_TUNNEL_ID;
import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PLSP_ID;
+import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.DELEGATE;
import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
import static org.onosproject.pcep.controller.PcepSyncStatus.SYNCED;
-import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
+import static org.onosproject.net.Device.Type.ROUTER;
+import static org.onosproject.net.MastershipRole.MASTER;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.onlab.packet.ChassisId;
import org.onlab.packet.IpAddress;
import org.onosproject.cfg.ComponentConfigAdapter;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.tunnel.DefaultTunnel;
import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.incubator.net.tunnel.Tunnel.Type;
+import org.onosproject.incubator.net.tunnel.TunnelAdminService;
import org.onosproject.incubator.net.tunnel.TunnelDescription;
import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
import org.onosproject.incubator.net.tunnel.TunnelId;
@@ -52,16 +60,26 @@
import org.onosproject.incubator.net.tunnel.TunnelProvider;
import org.onosproject.incubator.net.tunnel.TunnelProviderService;
import org.onosproject.incubator.net.tunnel.Tunnel.State;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
+import org.onosproject.net.MastershipRole;
import org.onosproject.net.Path;
import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
import org.onosproject.pcepio.exceptions.PcepOutOfBoundMessageException;
import org.onosproject.pcepio.exceptions.PcepParseException;
import org.onosproject.pcepio.protocol.PcepFactories;
import org.onosproject.pcepio.protocol.PcepMessage;
import org.onosproject.pcepio.protocol.PcepMessageReader;
+import org.onosproject.pcepio.protocol.PcepVersion;
import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.LspKey;
import org.onosproject.pcep.controller.PccId;
import com.google.common.collect.ImmutableSet;
@@ -71,13 +89,73 @@
*/
public class PcepTunnelAddedTest {
- static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
+ public static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
+ public static final String UNKOWN = "UNKOWN";
PcepTunnelProvider tunnelProvider = new PcepTunnelProvider();
private final MockTunnelProviderRegistryAdapter registry = new MockTunnelProviderRegistryAdapter();
private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final PcepTunnelApiMapper pcepTunnelAPIMapper = new PcepTunnelApiMapper();
private final MockTunnelServiceAdapter tunnelService = new MockTunnelServiceAdapter();
+ public final MockDeviceService deviceService = new MockDeviceService();
+ private final MockMasterShipService masterShipService = new MockMasterShipService();
+ private final MockTunnelAdminService tunnelAdminService = new MockTunnelAdminService();
+
+ private class MockTunnelAdminService implements TunnelAdminService {
+
+ @Override
+ public void removeTunnel(TunnelId tunnelId) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, ProviderId producerName) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void removeTunnels(TunnelEndPoint src, TunnelEndPoint dst, Type type, ProviderId producerName) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void updateTunnel(Tunnel tunnel, Path path) {
+ if (tunnelService.tunnelIdAsKeyStore.containsKey(tunnel.tunnelId())) {
+ tunnelService.tunnelIdAsKeyStore.replace(tunnel.tunnelId(), tunnel);
+ }
+ }
+ }
+
+ private class MockMasterShipService extends MastershipServiceAdapter {
+ boolean set;
+
+ private void setMaster(boolean isMaster) {
+ this.set = isMaster;
+ }
+
+ @Override
+ public MastershipRole getLocalRole(DeviceId deviceId) {
+ return set ? MastershipRole.MASTER : MastershipRole.STANDBY;
+ }
+
+ @Override
+ public boolean isLocalMaster(DeviceId deviceId) {
+ return getLocalRole(deviceId) == MASTER;
+ }
+ }
+
+ private class MockDeviceService extends DeviceServiceAdapter {
+ List<Device> devices = new LinkedList<>();
+
+ private void addDevice(Device dev) {
+ devices.add(dev);
+ }
+
+ @Override
+ public Iterable<Device> getAvailableDevices() {
+ return devices;
+ }
+ }
private class MockTunnelProviderRegistryAdapter extends TunnelProviderRegistryAdapter {
public long tunnelIdCounter;
@@ -97,12 +175,34 @@
@Override
public TunnelId tunnelAdded(TunnelDescription tunnel) {
- return TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
+ TunnelId id = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
+ Tunnel storedTunnel = new DefaultTunnel(ProviderId.NONE,
+ tunnel.src(), tunnel.dst(),
+ tunnel.type(),
+ tunnel.groupId(),
+ id,
+ tunnel.tunnelName(),
+ tunnel.path(),
+ tunnel.resource(),
+ tunnel.annotations());
+ tunnelService.tunnelIdAsKeyStore.put(id, storedTunnel);
+ return id;
}
@Override
public TunnelId tunnelAdded(TunnelDescription tunnel, State state) {
- return TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
+ TunnelId id = TunnelId.valueOf(String.valueOf(++tunnelIdCounter));
+ Tunnel storedTunnel = new DefaultTunnel(ProviderId.NONE,
+ tunnel.src(), tunnel.dst(),
+ tunnel.type(),
+ tunnel.groupId(),
+ id,
+ tunnel.tunnelName(),
+ tunnel.path(),
+ tunnel.resource(),
+ tunnel.annotations());
+ tunnelService.tunnelIdAsKeyStore.put(id, storedTunnel);
+ return id;
}
@Override
@@ -168,9 +268,12 @@
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
+ tunnelProvider.deviceService = deviceService;
+ tunnelProvider.mastershipService = masterShipService;
tunnelProvider.pcepTunnelApiMapper = pcepTunnelAPIMapper;
tunnelProvider.cfgService = new ComponentConfigAdapter();
tunnelProvider.tunnelService = tunnelService;
+ tunnelProvider.tunnelAdminService = tunnelAdminService;
tunnelProvider.service = registry.register(tunnelProvider);
tunnelProvider.activate();
}
@@ -210,6 +313,19 @@
PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
PcepMessage message = reader.readFrom(buffer);
+
+ DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
+ newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
+ newBuilder.set(AnnotationKeys.TYPE, "L3");
+ Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
+ UNKOWN, UNKOWN, UNKOWN,
+ UNKOWN, new ChassisId(),
+ newBuilder.build());
+
+ deviceService.addDevice(device);
+ controller.getClient(PccId.pccId(IpAddress.valueOf("1.1.1.1"))).setCapability(
+ new ClientCapability(true, true, true, true, true));
+ masterShipService.setMaster(true);
controller.processClientMessage(PccId.pccId(IpAddress.valueOf("1.1.1.1")), message);
assertThat(registry.tunnelIdCounter, is((long) 1));
@@ -254,14 +370,20 @@
.set(LSP_SIG_TYPE, WITHOUT_SIGNALLING_AND_WITHOUT_SR.name())
.set(PCC_TUNNEL_ID, String.valueOf(1))
.set(PLSP_ID, String.valueOf(1))
- .set(LOCAL_LSP_ID, String.valueOf(1)).build();
+ .set(LOCAL_LSP_ID, String.valueOf(1))
+ .set(DELEGATE, String.valueOf("true"))
+ .build();
Tunnel tunnel = new DefaultTunnel(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, INIT, null, null,
TunnelName.tunnelName("T123"), null, annotations);
tunnelService.setupTunnel(null, null, tunnel, null);
PccId pccId = PccId.pccId(IpAddress.valueOf(0x4e1f0400));
- controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
+ PcepClientAdapter pc = new PcepClientAdapter();
+ pc.init(pccId, PcepVersion.PCEP_1);
+ masterShipService.setMaster(true);
+ controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+ controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
// Process update message.
@@ -281,6 +403,164 @@
0x00, 0x00, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
0x00, 0x00, 0x00, 0x02,
+ 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x1B, // LSP object
+ 0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x01, 0x00, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x05, 0x05, 0x05, 0x05,
+
+ 0x07, 0x10, 0x00, 0x14, //ERO object
+ 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+ 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+ 0x08, 0x10, 0x00, 0x34, //RRO object
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+ 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+ };
+
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(reportMsg);
+
+ PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
+ PcepMessage message = reader.readFrom(buffer);
+
+ DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
+ newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
+ newBuilder.set(AnnotationKeys.TYPE, "L3");
+ Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
+ UNKOWN, UNKOWN, UNKOWN,
+ UNKOWN, new ChassisId(),
+ newBuilder.build());
+
+ deviceService.addDevice(device);
+
+ PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
+ controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
+ controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
+ PcepClientAdapter pc = new PcepClientAdapter();
+ pc.init(pccId, PcepVersion.PCEP_1);
+ controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+ masterShipService.setMaster(true);
+ controller.processClientMessage(pccId, message);
+
+ assertThat(registry.tunnelIdCounter, is((long) 1));
+ }
+
+ /**
+ * Tests PCRpt msg with D flag set and delegated to non-master.
+ *
+ * @throws InterruptedException while waiting for delay
+ */
+ @Test
+ public void tunnelProviderAddedTest4() throws PcepParseException, PcepOutOfBoundMessageException,
+ InterruptedException {
+ byte[] reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+ 0x21, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, //SRP object
+ 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+ 0x00, 0x00, 0x00, 0x02,
+ 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x02, //LSP object
+ 0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, //symbolic path tlv
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x01, 0x00, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x05, 0x05, 0x05, 0x05,
+
+ 0x07, 0x10, 0x00, 0x14, //ERO object
+ 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+ 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+ 0x08, 0x10, 0x00, 0x34, //RRO object
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+ 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+ };
+
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(reportMsg);
+
+ PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
+ PcepMessage message = reader.readFrom(buffer);
+
+ //PCC 1.1.1.1, D=0, ONOS as master
+ masterShipService.setMaster(true);
+ DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
+ newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
+ newBuilder.set(AnnotationKeys.TYPE, "L3");
+ Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
+ UNKOWN, UNKOWN, UNKOWN,
+ UNKOWN, new ChassisId(),
+ newBuilder.build());
+
+ deviceService.addDevice(device);
+ controller.getClient(PccId.pccId(IpAddress.valueOf("1.1.1.1"))).setCapability(
+ new ClientCapability(true, true, true, true, true));
+ controller.processClientMessage(PccId.pccId(IpAddress.valueOf("1.1.1.1")), message);
+ assertThat(tunnelService.tunnelIdAsKeyStore.values().iterator().next().annotations().value(DELEGATE),
+ is("false"));
+
+ //PCC 1.1.1.1, D=1, non-master
+ masterShipService.setMaster(false);
+
+ reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+ 0x21, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, //SRP object
+ 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+ 0x00, 0x00, 0x00, 0x02,
+ 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x03, //LSP object
+ 0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, //symbolic path tlv
+ 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
+ 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x01, 0x00, 0x01,
+ 0x01, 0x01, 0x01, 0x01,
+ 0x05, 0x05, 0x05, 0x05,
+
+ 0x07, 0x10, 0x00, 0x14, //ERO object
+ 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
+ 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
+
+ 0x08, 0x10, 0x00, 0x34, //RRO object
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
+ 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
+ 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
+ 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
+ };
+
+ buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(reportMsg);
+
+ reader = PcepFactories.getGenericReader();
+ message = reader.readFrom(buffer);
+
+ controller.processClientMessage(PccId.pccId(IpAddress.valueOf("1.1.1.1")), message);
+ TimeUnit.MILLISECONDS.sleep(4000);
+ assertThat(registry.tunnelIdCounter, is((long) 1));
+ assertThat(tunnelService.tunnelIdAsKeyStore.values().iterator().next().annotations().value(DELEGATE),
+ is("true"));
+ }
+
+ /**
+ * Tests adding PCC Init LSP after LSP DB sync is over.
+ */
+ @Test
+ public void tunnelProviderAddedTest5() throws PcepParseException, PcepOutOfBoundMessageException {
+ byte[] reportMsg = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
+ 0x21, 0x10, 0x00, 0x14, //SRP object
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
+ 0x00, 0x00, 0x00, 0x02,
0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
0x00, 0x11, 0x00, 0x02, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
@@ -308,290 +588,27 @@
PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
PcepMessage message = reader.readFrom(buffer);
+ DefaultAnnotations.Builder newBuilder = DefaultAnnotations.builder();
+ newBuilder.set(PcepTunnelProvider.LSRID, "1.1.1.1");
+ newBuilder.set(AnnotationKeys.TYPE, "L3");
+ Device device = new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("1.1.1.1"), ROUTER,
+ UNKOWN, UNKOWN, UNKOWN,
+ UNKOWN, new ChassisId(),
+ newBuilder.build());
+
+ deviceService.addDevice(device);
+
PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
controller.getClient(pccId).setLspDbSyncStatus(SYNCED);
- controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
+ controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
+ PcepClientAdapter pc = new PcepClientAdapter();
+ pc.init(pccId, PcepVersion.PCEP_1);
+ controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+ masterShipService.setMaster(true);
controller.processClientMessage(pccId, message);
- assertThat(registry.tunnelIdCounter, is((long) 1));
- }
-
- /**
- * Tests LSPDB sync where PCC reports less LSPs than known by PCE and PCE deletes at the end of DB sync.
- */
- @Test
- public void testCaseLspDbSync1() throws PcepParseException, PcepOutOfBoundMessageException {
- /* Step 1 create 2 LSPs */
- byte[] reportMsg1 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
- 0x21, 0x10, 0x00, 0x14, //SRP object
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
- 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
- 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
- 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
- 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x01, 0x00, 0x01,
- 0x01, 0x01, 0x01, 0x01,
- 0x05, 0x05, 0x05, 0x05,
-
- 0x07, 0x10, 0x00, 0x14, //ERO object
- 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
- 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
- 0x08, 0x10, 0x00, 0x34, //RRO object
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
- 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
- };
-
- ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer();
- buffer1.writeBytes(reportMsg1);
-
- PcepMessageReader<PcepMessage> reader1 = PcepFactories.getGenericReader();
- PcepMessage message1 = reader1.readFrom(buffer1);
-
- PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
- controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
- controller.processClientMessage(pccId, message1);
-
- /* create 2nd LSP */
- byte[] reportMsg2 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
- 0x21, 0x10, 0x00, 0x14, //SRP object
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
- 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x20, 0x19, // LSP object
- 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
- 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
- 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x02, 0x00, 0x02,
- 0x01, 0x01, 0x01, 0x01,
- 0x05, 0x05, 0x05, 0x05,
-
- 0x07, 0x10, 0x00, 0x14, //ERO object
- 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
- 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
- 0x08, 0x10, 0x00, 0x34, //RRO object
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
- 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
- };
-
- ChannelBuffer buffer2 = ChannelBuffers.dynamicBuffer();
- buffer2.writeBytes(reportMsg2);
-
- PcepMessageReader<PcepMessage> reader2 = PcepFactories.getGenericReader();
- PcepMessage message2 = reader2.readFrom(buffer2);
-
- controller.processClientMessage(pccId, message2);
-
- /* Assert number of LSPs in DB to be 2. */
- assertThat(registry.tunnelIdCounter, is((long) 2));
-
- /* Step 2 send sync begin message and LSP 1. */
- byte[] reportMsg3 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
- 0x21, 0x10, 0x00, 0x14, //SRP object
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
- 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x1B, // LSP object
- 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
- 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
- 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x01, 0x00, 0x01,
- 0x01, 0x01, 0x01, 0x01,
- 0x05, 0x05, 0x05, 0x05,
-
- 0x07, 0x10, 0x00, 0x14, //ERO object
- 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
- 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
- 0x08, 0x10, 0x00, 0x34, //RRO object
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
- 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
- };
-
- ChannelBuffer buffer3 = ChannelBuffers.dynamicBuffer();
- buffer3.writeBytes(reportMsg3);
- PcepMessageReader<PcepMessage> reader3 = PcepFactories.getGenericReader();
- PcepMessage message3 = reader3.readFrom(buffer3);
- controller.processClientMessage(pccId, message3);
-
- assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(IN_SYNC));
-
- /* Step 3 send end of sync marker */
- byte[] reportMsg4 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x24,
- 0x20, 0x10, 0x00, 0x1C, // LSP object
- 0x00, 0x00, 0x10, 0x19,
- 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x07, 0x10, 0x00, 0x04, //ERO object
- };
-
- ChannelBuffer buffer4 = ChannelBuffers.dynamicBuffer();
- buffer4.writeBytes(reportMsg4);
- PcepMessageReader<PcepMessage> reader4 = PcepFactories.getGenericReader();
- PcepMessage message4 = reader4.readFrom(buffer4);
- controller.processClientMessage(pccId, message4);
-
- assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(SYNCED));
- }
-
- /**
- * Tests PCC PCRpt PCE initiated LSP which PCE doesn't know and hence should send PCInit delete msg.
- */
- @Test
- public void testCaseLspDbSync2() throws PcepParseException, PcepOutOfBoundMessageException {
- /* Step 1 create 2 LSPs */
- byte[] reportMsg1 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
- 0x21, 0x10, 0x00, 0x14, //SRP object
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
- 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, 0x19, // LSP object
- 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
- 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
- 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x01, 0x00, 0x01,
- 0x01, 0x01, 0x01, 0x01,
- 0x05, 0x05, 0x05, 0x05,
-
- 0x07, 0x10, 0x00, 0x14, //ERO object
- 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
- 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
- 0x08, 0x10, 0x00, 0x34, //RRO object
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
- 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
- };
-
- ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer();
- buffer1.writeBytes(reportMsg1);
-
- PcepMessageReader<PcepMessage> reader1 = PcepFactories.getGenericReader();
- PcepMessage message1 = reader1.readFrom(buffer1);
-
- PccId pccId = PccId.pccId(IpAddress.valueOf("1.1.1.1"));
- controller.getClient(pccId).setCapability(new ClientCapability(true, true, true));
- controller.processClientMessage(pccId, message1);
-
- /* create 2nd LSP */
- byte[] reportMsg2 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
- 0x21, 0x10, 0x00, 0x14, //SRP object
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
- 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x20, 0x19, // LSP object
- 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
- 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
- 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x02, 0x00, 0x02,
- 0x01, 0x01, 0x01, 0x01,
- 0x05, 0x05, 0x05, 0x05,
-
- 0x07, 0x10, 0x00, 0x14, //ERO object
- 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
- 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
- 0x08, 0x10, 0x00, 0x34, //RRO object
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
- 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
- };
-
- ChannelBuffer buffer2 = ChannelBuffers.dynamicBuffer();
- buffer2.writeBytes(reportMsg2);
-
- PcepMessageReader<PcepMessage> reader2 = PcepFactories.getGenericReader();
- PcepMessage message2 = reader2.readFrom(buffer2);
-
- controller.processClientMessage(pccId, message2);
-
- /* Assert number of LSPs in DB to be 2. */
- assertThat(registry.tunnelIdCounter, is((long) 2));
-
- /* Step 2 send sync begin message and LSP 1. */
- byte[] reportMsg3 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x84,
- 0x21, 0x10, 0x00, 0x14, //SRP object
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x1c, 0x00, 0x04, // PATH-SETUP-TYPE TLV
- 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x10, 0x00, 0x24, 0x00, 0x00, 0x10, (byte) 0x9B, // LSP object
- 0x00, 0x11, 0x00, 0x04, 0x54, 0x31, 0x00, 0x00, // symbolic path TLV
- 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
- 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x01, 0x00, 0x03,
- 0x01, 0x01, 0x01, 0x01,
- 0x05, 0x05, 0x05, 0x05,
-
- 0x07, 0x10, 0x00, 0x14, //ERO object
- 0x01, 0x08, (byte) 0x01, 0x01, 0x01, 0x01, 0x04, 0x00, // ERO IPv4 sub objects
- 0x01, 0x08, (byte) 0x05, 0x05, 0x05, 0x05, 0x04, 0x00,
-
- 0x08, 0x10, 0x00, 0x34, //RRO object
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x01, 0x04, 0x00, // RRO IPv4 sub objects
- 0x01, 0x08, 0x11, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x06, 0x06, 0x06, 0x06, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x02, 0x04, 0x00,
- 0x01, 0x08, 0x12, 0x01, 0x01, 0x01, 0x04, 0x00,
- 0x01, 0x08, 0x05, 0x05, 0x05, 0x05, 0x04, 0x00
- };
-
- ChannelBuffer buffer3 = ChannelBuffers.dynamicBuffer();
- buffer3.writeBytes(reportMsg3);
- PcepMessageReader<PcepMessage> reader3 = PcepFactories.getGenericReader();
- PcepMessage message3 = reader3.readFrom(buffer3);
- controller.processClientMessage(pccId, message3);
-
- assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(IN_SYNC));
-
- /* Step 3 send end of sync marker */
- byte[] reportMsg4 = new byte[] {0x20, 0x0a, 0x00, (byte) 0x24,
- 0x20, 0x10, 0x00, 0x1C, // LSP object
- 0x00, 0x00, 0x10, 0x19,
- 0x00, 0x12, 0x00, 0x10, // IPv4-LSP-IDENTIFIER-TLV
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x07, 0x10, 0x00, 0x04, //ERO object
- };
-
- ChannelBuffer buffer4 = ChannelBuffers.dynamicBuffer();
- buffer4.writeBytes(reportMsg4);
- PcepMessageReader<PcepMessage> reader4 = PcepFactories.getGenericReader();
- PcepMessage message4 = reader4.readFrom(buffer4);
- controller.processClientMessage(pccId, message4);
-
- assertThat(controller.getClient(pccId).lspDbSyncStatus(), is(SYNCED));
+ assertThat(registry.tunnelIdCounter, is((long) 0));
}
@After
@@ -604,6 +621,9 @@
tunnelProvider.pcepTunnelApiMapper = null;
tunnelProvider.cfgService = null;
tunnelProvider.tunnelService = null;
+ tunnelProvider.tunnelAdminService = null;
+ tunnelProvider.deviceService = null;
+ tunnelProvider.mastershipService = null;
tunnelProvider.service = null;
}
}
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java
index 2922537..e641c64 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepTunnelProviderTest.java
@@ -35,6 +35,7 @@
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelName;
+import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
@@ -44,7 +45,10 @@
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.PccId;
import org.onosproject.cfg.ComponentConfigAdapter;
public class PcepTunnelProviderTest {
@@ -55,6 +59,8 @@
private final PcepClientControllerAdapter controller = new PcepClientControllerAdapter();
private final PcepControllerAdapter ctl = new PcepControllerAdapter();
private final TunnelServiceAdapter tunnelService = new TunnelServiceAdapter();
+ private final DeviceServiceAdapter deviceService = new DeviceServiceAdapter();
+ private final MastershipServiceAdapter mastershipService = new MastershipServiceAdapter();
@Test
public void testCasePcepSetupTunnel() {
@@ -62,6 +68,8 @@
tunnelProvider.tunnelProviderRegistry = registry;
tunnelProvider.pcepClientController = controller;
tunnelProvider.controller = ctl;
+ tunnelProvider.deviceService = deviceService;
+ tunnelProvider.mastershipService = mastershipService;
tunnelProvider.cfgService = new ComponentConfigAdapter();
tunnelProvider.tunnelService = tunnelService;
tunnelProvider.activate();
@@ -99,6 +107,8 @@
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
new DefaultGroupId(0), TunnelId.valueOf("1"), TunnelName.tunnelName("T123"),
path, annotations);
+ controller.getClient(PccId.pccId(IpAddress.valueOf(0xC010101))).setCapability(
+ new ClientCapability(true, true, true, true, true));
tunnelProvider.setupTunnel(tunnel, path);
@@ -109,6 +119,8 @@
public void tearDown() throws IOException {
tunnelProvider.deactivate();
tunnelProvider.controller = null;
+ tunnelProvider.deviceService = null;
+ tunnelProvider.mastershipService = null;
tunnelProvider.pcepClientController = null;
tunnelProvider.tunnelProviderRegistry = null;
}
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java
index 2c9961f..4106dfb 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepUpdateTunnelProviderTest.java
@@ -47,6 +47,10 @@
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.controller.ClientCapability;
+import org.onosproject.pcep.controller.LspKey;
+import org.onosproject.pcep.controller.PccId;
+import org.onosproject.pcepio.protocol.PcepVersion;
import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITH_SIGNALLING;
@@ -99,7 +103,7 @@
ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
- ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+ ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
.type(Link.Type.DIRECT).build();
@@ -108,6 +112,8 @@
path = new DefaultPath(pid, links, 20, EMPTY);
Annotations annotations = DefaultAnnotations.builder()
+ .set(PcepAnnotationKeys.PLSP_ID, "1")
+ .set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
.set(LSP_SIG_TYPE, WITH_SIGNALLING.name())
.build();
@@ -124,6 +130,12 @@
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+ PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
+ PcepClientAdapter pc = new PcepClientAdapter();
+ pc.init(pccId, PcepVersion.PCEP_1);
+ controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+ controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
tunnelProvider.updateTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
}
@@ -137,7 +149,7 @@
Path path;
ProviderId pid = new ProviderId("pcep", PROVIDER_ID);
List<Link> links = new ArrayList<>();
- IpAddress srcIp = IpAddress.valueOf(0xC010103);
+ IpAddress srcIp = IpAddress.valueOf(0xD010101);
IpElementId srcElementId = IpElementId.ipElement(srcIp);
IpAddress dstIp = IpAddress.valueOf(0xD010102);
@@ -151,7 +163,7 @@
ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
- ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+ ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
.type(Link.Type.DIRECT).build();
@@ -161,6 +173,8 @@
Annotations annotations = DefaultAnnotations.builder()
.set(LSP_SIG_TYPE, WITH_SIGNALLING.name())
+ .set(PcepAnnotationKeys.PLSP_ID, "1")
+ .set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
.build();
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
@@ -176,6 +190,12 @@
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+ PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
+ PcepClientAdapter pc = new PcepClientAdapter();
+ pc.init(pccId, PcepVersion.PCEP_1);
+ controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+ controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
tunnelProvider.updateTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper.checkFromTunnelRequestQueue(1), is(false));
}
@@ -203,7 +223,7 @@
ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
- ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+ ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
.type(Link.Type.DIRECT).build();
@@ -213,6 +233,8 @@
Annotations annotations = DefaultAnnotations.builder()
.set(LSP_SIG_TYPE, SR_WITHOUT_SIGNALLING.name())
+ .set(PcepAnnotationKeys.PLSP_ID, "1")
+ .set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
.build();
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
@@ -228,6 +250,12 @@
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+ PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
+ PcepClientAdapter pc = new PcepClientAdapter();
+ pc.init(pccId, PcepVersion.PCEP_1);
+ controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+ controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
tunnelProvider.updateTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
}
@@ -255,7 +283,7 @@
ConnectPoint src = new ConnectPoint(srcElementId, PortNumber.portNumber(10023));
- ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10023));
+ ConnectPoint dst = new ConnectPoint(dstElementId, PortNumber.portNumber(10024));
Link link = DefaultLink.builder().providerId(pid).src(src).dst(dst)
.type(Link.Type.DIRECT).build();
@@ -265,6 +293,8 @@
Annotations annotations = DefaultAnnotations.builder()
.set(LSP_SIG_TYPE, WITHOUT_SIGNALLING_AND_WITHOUT_SR.name())
+ .set(PcepAnnotationKeys.PLSP_ID, "1")
+ .set(PcepAnnotationKeys.LOCAL_LSP_ID, "1")
.build();
tunnel = new DefaultTunnel(pid, ipTunnelEndPointSrc, ipTunnelEndPointDst, Tunnel.Type.MPLS,
@@ -280,6 +310,12 @@
tunnelProvider.pcepTunnelApiMapper.handleCreateTunnelRequestQueue(1, pcepTunnelData);
+ PccId pccId = PccId.pccId(IpAddress.valueOf(0xD010101));
+ PcepClientAdapter pc = new PcepClientAdapter();
+ pc.init(pccId, PcepVersion.PCEP_1);
+ controller.getClient(pccId).setLspAndDelegationInfo(new LspKey(1, (short) 1), true);
+ controller.getClient(pccId).setCapability(new ClientCapability(true, true, true, true, true));
+
tunnelProvider.updateTunnel(tunnel, path);
assertThat(tunnelProvider.pcepTunnelApiMapper, not(nullValue()));
}