Fix Path Computation Crashes 91/91091/4
authorOlivier Dugeon <olivier.dugeon@orange.com>
Fri, 10 Jul 2020 12:28:57 +0000 (14:28 +0200)
committerRobert Varga <nite@hq.sk>
Fri, 17 Jul 2020 12:10:19 +0000 (12:10 +0000)
If Path Computation is called with unknown graph, PCEP session crashes
due to path computation creation error. This patch checks that path
computation is valid and reply with PcErr message for PcReq or PcError
for RPC call.

JIRA: BGPCEP-911
Change-Id: I5fa6919db058c97ada4b69077630101d6f02c4f7
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PathComputationImpl.java
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PceServerFactory.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListener.java

index af094ec35d7b3f552f52218fe7b1faf8939c734f..349db4efce5dc91eb5af3d744b457ebc337fb20a 100644 (file)
@@ -178,7 +178,7 @@ public class PathComputationImpl implements PathComputation {
         }
 
         ConnectedVertex vertex = tedGraph.getConnectedVertex(address);
-        LOG.debug("Compute path from Source {}", vertex.toString());
+        LOG.debug("Compute path from Source {}", vertex != null ? vertex : "Unknown");
         return (vertex != null) ? vertex.getVertex().key() : null;
     }
 
@@ -196,7 +196,7 @@ public class PathComputationImpl implements PathComputation {
         }
 
         ConnectedVertex vertex = tedGraph.getConnectedVertex(address);
-        LOG.debug("Compute path to Destination {}", vertex.toString());
+        LOG.debug("Compute path to Destination {}", vertex != null ? vertex : "Unknown");
         return (vertex != null) ? vertex.getVertex().key() : null;
     }
 
index 813a6a4abe3d18ce7417e9951e9e5825c06a5096..9da8f189ae99f28bced33062f871f12be8dfd977 100644 (file)
@@ -43,17 +43,17 @@ public class PceServerFactory implements PceServerProvider {
     }
 
     @Override
-    public PathComputationImpl getPathComputation() {
-        /* Leave a change to get a valid Graph */
-        if (tedGraph == null) {
-            setTedGraph();
+    public @Nullable PathComputationImpl getPathComputation() {
+        /* Check that we have a valid graph */
+        if (getTedGraph() == null) {
+            return null;
         }
         return new PathComputationImpl(tedGraph, algoProvider);
     }
 
     @Override
     public @Nullable ConnectedGraph getTedGraph() {
-        /* Leave a change to get a valid Graph in case of late fulfillment */
+        /* Leave a chance to get a valid Graph in case of late fulfillment */
         if (tedGraph == null) {
             setTedGraph();
         }
index b05190decc8d295ee6af6741d799bdf6a62d9989..1c401e4f4b3a148e91ef0ba8d8d8eab64c77c8ca 100644 (file)
@@ -28,6 +28,7 @@ import java.util.Optional;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.bgpcep.pcep.server.PathComputation;
 import org.opendaylight.bgpcep.pcep.server.PceServerProvider;
 import org.opendaylight.protocol.pcep.PCEPSession;
@@ -69,13 +70,23 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.iet
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.srp.object.SrpBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.stateful.capability.tlv.Stateful;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.symbolic.path.name.tlv.SymbolicPathNameBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcerr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcerrBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcreq;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.PcerrMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.RequestId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.EroBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.object.open.Tlvs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.path.setup.type.tlv.PathSetupType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcep.error.object.ErrorObjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.PcerrMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.ErrorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.RequestCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.request._case.RequestBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.request._case.request.RpsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.PcreqMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.rp.object.RpBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.AddLspArgs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.EnsureLspOperationalInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.LspId;
@@ -376,6 +387,12 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
         /* Get a Path Computation to compute the Path from the Request */
         PathComputation pathComputation = this.pceServerProvider.getPathComputation();
         Message rep = null;
+        /* Reply with Error Message if no valid Path Computation is available */
+        if (pathComputation == null) {
+            rep = createErrorMsg(PCEPErrors.RESOURCE_LIMIT_EXCEEDED, Uint32.ZERO);
+            sendMessage(rep, new SrpIdNumber(Uint32.ZERO), null);
+            return false;
+        }
         for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq
                 .message.Requests req : message.getRequests()) {
             LOG.debug("Process request {}", req);
@@ -762,6 +779,9 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
 
                 /* Get a Path Computation to compute the Path from the Arguments */
                 PathComputation pathComputation = pceServerProvider.getPathComputation();
+                if (pathComputation == null) {
+                    return OperationResults.createUnsent(PCEPErrors.ERO_MISSING).future();
+                }
                 rb.setEro(pathComputation.computeEro(args.getEndpointsObj(), args.getBandwidth(), args.getClassType(),
                         args.getMetrics(), segmentRouting));
             }
@@ -850,4 +870,28 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
             return redelegate(reportedLsp, srp, lspBuilder.build(), this.input);
         }
     }
+
+    private static Pcerr createErrorMsg(@NonNull final PCEPErrors pcepErrors, final Uint32 reqID) {
+        return new PcerrBuilder()
+                .setPcerrMessage(new PcerrMessageBuilder()
+                    .setErrorType(new RequestCaseBuilder()
+                        .setRequest(new RequestBuilder()
+                            .setRps(Collections.singletonList(new RpsBuilder()
+                                .setRp(new RpBuilder()
+                                    .setProcessingRule(false)
+                                    .setIgnore(false)
+                                    .setRequestId(new RequestId(reqID))
+                                    .build())
+                                .build()))
+                            .build())
+                        .build())
+                    .setErrors(Collections.singletonList(new ErrorsBuilder()
+                        .setErrorObject(new ErrorObjectBuilder()
+                            .setType(pcepErrors.getErrorType())
+                            .setValue(pcepErrors.getErrorValue())
+                            .build())
+                        .build()))
+                    .build())
+                .build();
+    }
 }