uses initiated-capability-tlv;
}
- augment "/nt:network-topology/nt:topology/nt:node/topo:path-computation-client/topo:reported-lsp/stateful:lsp" {
+ augment "/nt:network-topology/nt:topology/nt:node/topo:path-computation-client/topo:reported-lsp/topo:path/stateful:lsp" {
reference "http://tools.ietf.org/html/draft-ietf-pce-pce-initiated-lsp-00#section-5.3.1";
leaf create {
type boolean;
ext:augment-identifier tlvs-3;
}
- augment "/nt:network-topology/nt:topology/nt:node/topo:path-computation-client/topo:reported-lsp" {
+ augment "/nt:network-topology/nt:topology/nt:node/topo:path-computation-client/topo:reported-lsp/topo:path" {
uses lsp-object;
}
import network-topology { prefix nt; revision-date 2013-10-21; }
import odl-network-topology { prefix ont; revision-date 2014-01-13; }
import pcep-types { prefix pcep; revision-date 2013-10-05; }
+ import rsvp { prefix rsvp; revision-date 2013-08-20; }
organization "Cisco Systems, Inc.";
contact "Robert Varga <rovarga@cisco.com>";
}
key name;
- container path {
+ list path {
+ leaf lsp-id {
+ type rsvp:lsp-id;
+ mandatory true;
+ }
+ key lsp-id;
+
uses pcep:path-definition;
}
-
uses lsp-metadata;
}
}
import io.netty.util.concurrent.FutureListener;
import java.net.InetAddress;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.MessageHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.ProtocolVersion;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.LspId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.Node1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.Node1Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLsp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLspBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLspKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.reported.lsp.Path;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
}
protected final synchronized void updateLsp(final DataModificationTransaction trans, final L id, final String lspName,
- final ReportedLspBuilder rlb, final boolean solicited) {
+ final ReportedLspBuilder rlb, final boolean solicited, final boolean remove) {
final String name;
if (lspName == null) {
LOG.debug("Saved LSP {} with name {}", id, name);
this.lsps.put(id, name);
+ // just one path should be reported
+ Preconditions.checkState(rlb.getPath().size() == 1);
+ LspId reportedLspId = rlb.getPath().get(0).getLspId();
+ // check previous report for existing paths
+ ReportedLsp previous = this.lspData.get(name);
+ // if no previous report about the lsp exist, just proceed
+ if (previous != null) {
+ List<Path> updatedPaths = new ArrayList<>(previous.getPath());
+ LOG.debug("Found previous paths {} to this lsp name {}", updatedPaths, name);
+ for (Path path : previous.getPath()) {
+ //we found reported path in previous reports
+ if (path.getLspId().getValue() == 0 || path.getLspId().equals(reportedLspId)) {
+ LOG.debug("Match on lsp-id {}", path.getLspId().getValue() );
+ // path that was reported previously and does have the same lsp-id, path will be updated
+ final boolean r = updatedPaths.remove(path);
+ LOG.trace("Request removed? {}", r);
+ }
+ }
+ // if the path does not exist in previous report, add it to path list, it's a new ERO
+ // only one path will be added
+ //lspId is 0 means confirmation message that shouldn't be added (because we have no means of deleting it later)
+ LOG.trace("Adding new path {} to {}", rlb.getPath(), updatedPaths);
+ updatedPaths.addAll(rlb.getPath());
+ if (remove) {
+ if (reportedLspId.getValue() == 0) {
+ // if lsp-id also 0, remove all paths
+ LOG.debug("Removing all paths.");
+ updatedPaths.clear();
+ } else {
+ // path is marked to be removed
+ LOG.debug("Removing path {} from {}", rlb.getPath(), updatedPaths);
+ final boolean r = updatedPaths.removeAll(rlb.getPath());
+ LOG.trace("Request removed? {}", r);
+ }
+ }
+ // if all paths or the last path were deleted, delete whole tunnel
+ if (updatedPaths.isEmpty()) {
+ LOG.debug("All paths were removed, removing LSP with {}.", id);
+ removeLsp(trans, id);
+ return;
+ }
+ LOG.debug("Setting new paths {} to lsp {}", updatedPaths, name);
+ rlb.setPath(updatedPaths);
+ }
Preconditions.checkState(name != null);
rlb.setKey(new ReportedLspKey(name));
rlb.setName(name);
if (r.getPath() != null) {
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.reported.lsp.PathBuilder pb = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.reported.lsp.PathBuilder();
pb.fieldsFrom(r.getPath());
- rlb.setPath(pb.build());
+ rlb.setPath(Collections.singletonList(pb.build()));
}
boolean solicited = false;
}
if (!lsp.isRemove()) {
- updateLsp(trans, id, name, rlb, solicited);
+ updateLsp(trans, id, name, rlb, solicited, false);
LOG.debug("LSP {} updated", lsp);
} else {
removeLsp(trans, id);
import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import java.net.InetAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Arguments2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Arguments3;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.OperationalStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Path1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Path1Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.PcrptMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.PcupdBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.PlspId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.ReportedLsp1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.ReportedLsp1Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.SrpIdNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.StatefulTlv1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.StatefulTlv1Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PcerrMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.Tlvs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.LspId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspArgs;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.EnsureLspOperationalInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
}
final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.PcrptMessage rpt = ((PcrptMessage) message).getPcrptMessage();
- for (final Reports r : rpt.getReports()) {
- final Lsp lsp = r.getLsp();
+ for (final Reports report : rpt.getReports()) {
+ final Lsp lsp = report.getLsp();
+ final PlspId plspid = lsp.getPlspId();
- if (!lsp.isSync() && (lsp.getPlspId() == null || lsp.getPlspId().getValue() == 0)) {
+ if (!lsp.isSync() && (lsp.getPlspId() == null || plspid.getValue() == 0)) {
stateSynchronizationAchieved(trans);
continue;
}
final ReportedLspBuilder rlb = new ReportedLspBuilder();
- rlb.addAugmentation(ReportedLsp1.class, new ReportedLsp1Builder(r).build());
- if (r.getPath() != null) {
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.reported.lsp.PathBuilder pb = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.reported.lsp.PathBuilder();
- pb.fieldsFrom(r.getPath());
- rlb.setPath(pb.build());
- }
+
boolean solicited = false;
- final Srp srp = r.getSrp();
+ final Srp srp = report.getSrp();
if (srp != null) {
final SrpIdNumber id = srp.getOperationId();
if (id.getValue() != 0) {
// up...
break;
}
- }
- }
- final PlspId id = lsp.getPlspId();
- if (!lsp.isRemove()) {
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.lsp.Tlvs tlvs = r.getLsp().getTlvs();
- final String name;
- if (tlvs != null && tlvs.getSymbolicPathName() != null) {
- name = Charsets.UTF_8.decode(ByteBuffer.wrap(tlvs.getSymbolicPathName().getPathName().getValue())).toString();
- } else {
- name = null;
}
-
- updateLsp(trans, id, name, rlb, solicited);
- LOG.debug("LSP {} updated", lsp);
+ }
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.lsp.Tlvs tlvs = report.getLsp().getTlvs();
+ final String name;
+ if (tlvs != null && tlvs.getSymbolicPathName() != null) {
+ name = Charsets.UTF_8.decode(ByteBuffer.wrap(tlvs.getSymbolicPathName().getPathName().getValue())).toString();
} else {
- removeLsp(trans, id);
- LOG.debug("LSP {} removed", lsp);
+ name = null;
}
+ LspId lspid = null;
+ if (tlvs != null && tlvs.getLspIdentifiers() != null) {
+ lspid = tlvs.getLspIdentifiers().getLspId();
+ }
+ if (report.getPath() != null) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.reported.lsp.PathBuilder pb = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.reported.lsp.PathBuilder();
+ pb.fieldsFrom(report.getPath());
+ pb.addAugmentation(Path1.class, new Path1Builder().setLsp(report.getLsp()).build());
+ pb.setLspId(lspid);
+ rlb.setPath(Lists.newArrayList(pb.build()));
+ }
+ updateLsp(trans, plspid, name, rlb, solicited, lsp.isRemove());
+ LOG.debug("LSP {} updated", lsp);
}
-
return false;
}
@Override
public synchronized ListenableFuture<OperationResult> removeLsp(final RemoveLspArgs input) {
Preconditions.checkArgument(input != null && input.getName() != null & input.getNode() != null, "Mandatory XML tags are missing.");
+ LOG.trace("RemoveLspArgs {}", input);
// Make sure the LSP exists, we need it for PLSP-ID
final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName()).build();
final ReportedLsp rep = readOperationalData(lsp);
LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
return OperationResults.UNSENT.future();
}
-
- final ReportedLsp1 ra = rep.getAugmentation(ReportedLsp1.class);
+ // it doesn't matter how many lsps there are in the path list, we only need delegate & plspid that is the same in eeach path
+ final Path1 ra = rep.getPath().get(0).getAugmentation(Path1.class);
Preconditions.checkState(ra != null, "Reported LSP reported null from data-store.");
Lsp reportedLsp = ra.getLsp();
Preconditions.checkState(reportedLsp != null, "Reported LSP does not contain LSP object.");
@Override
public synchronized ListenableFuture<OperationResult> updateLsp(final UpdateLspArgs input) {
Preconditions.checkArgument(input != null && input.getName() != null & input.getNode() != null && input.getArguments() != null, "Mandatory XML tags are missing.");
+ LOG.trace("UpdateLspArgs {}", input);
// Make sure the LSP exists
final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName()).build();
final ReportedLsp rep = readOperationalData(lsp);
LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
return OperationResults.UNSENT.future();
}
- final ReportedLsp1 ra = rep.getAugmentation(ReportedLsp1.class);
+ // it doesn't matter how many lsps there are in the path list, we only need plspid that is the same in each path
+ final Path1 ra = rep.getPath().get(0).getAugmentation(Path1.class);
Preconditions.checkState(ra != null, "Reported LSP reported null from data-store.");
Lsp reportedLsp = ra.getLsp();
Preconditions.checkState(reportedLsp != null, "Reported LSP does not contain LSP object.");
LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
return OperationResults.UNSENT.future();
}
-
- final ReportedLsp1 ra = rep.getAugmentation(ReportedLsp1.class);
- if (ra == null) {
- LOG.warn("Node {} LSP {} does not contain data", input.getNode(), input.getName());
- return OperationResults.UNSENT.future();
+ boolean operational = false;
+ // check if at least one of the paths has the same status as requested
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.reported.lsp.Path p : rep.getPath()) {
+ Path1 p1 = p.getAugmentation(Path1.class);
+ if (p1 == null) {
+ LOG.warn("Node {} LSP {} does not contain data", input.getNode(), input.getName());
+ return OperationResults.UNSENT.future();
+ }
+ Lsp l = p1.getLsp();
+ if (l.getOperational().equals(op)) {
+ operational = true;
+ }
}
-
- if (ra.getLsp().getOperational().equals(op)) {
+ if (operational) {
return OperationResults.SUCCESS.future();
} else {
return OperationResults.UNSENT.future();
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.PcrptMessageBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.Reports;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.ReportsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.reports.PathBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.symbolic.path.name.tlv.SymbolicPathNameBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.EroBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.TlvsBuilder;
final DefaultPCEPSessionNegotiator neg = new DefaultPCEPSessionNegotiator(new HashedWheelTimer(), mock(Promise.class), this.clientListener, this.manager.getSessionListener(), (short) 1, 5, this.localPrefs);
this.session = neg.createSession(new HashedWheelTimer(), this.clientListener, this.localPrefs, this.localPrefs);
- final List<Reports> reports = Lists.newArrayList(new ReportsBuilder().setLsp(
+ final List<Reports> reports = Lists.newArrayList(new ReportsBuilder().setPath(new PathBuilder().setEro(new EroBuilder().build()).build()).setLsp(
new LspBuilder().setPlspId(new PlspId(5L)).setSync(false).setRemove(false).setTlvs(
new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.lsp.TlvsBuilder().setSymbolicPathName(
new SymbolicPathNameBuilder().setPathName(new SymbolicPathName(new byte[] { 22, 34 })).build()).build()).build()).build());
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.AdministrativeStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.ReportedLsp1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Path1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.identifiers.tlv.lsp.identifiers.AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv4Case;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv6Case;
private void create(final DataModificationTransaction trans, final InstanceIdentifier<ReportedLsp> i, final ReportedLsp value) {
final InstanceIdentifier<Node> ni = i.firstIdentifierOf(Node.class);
- final ReportedLsp1 rl = value.getAugmentation(ReportedLsp1.class);
+
+ final Path1 rl = value.getPath().get(0).getAugmentation(Path1.class);
final AddressFamily af = rl.getLsp().getTlvs().getLspIdentifiers().getAddressFamily();
throw new IllegalArgumentException("Unsupported address family: " + af.getImplementedInterface());
}
- final Link1Builder lab = new Link1Builder(value.getPath().getLspa());
- lab.setBandwidth(value.getPath().getBandwidth().getBandwidth());
- lab.setClassType(value.getPath().getClassType().getClassType());
+ final Link1Builder lab = new Link1Builder(value.getPath().get(0).getLspa());
+ lab.setBandwidth(value.getPath().get(0).getBandwidth().getBandwidth());
+ lab.setClassType(value.getPath().get(0).getClassType().getClassType());
lab.setSymbolicPathName(value.getName());
final InstanceIdentifier<TerminationPoint> dst = getIpTerminationPoint(trans, dstIp, null, Boolean.FALSE);