Search in sources :

Example 1 with Algorithm

use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.Algorithm in project bgpcep by opendaylight.

the class AbstractPathComputation method pruneEdge.

/**
 * Check if Edge need to be prune regarding all constraints including
 * address family.
 *
 * @return True if Edge must be prune, False if Edge must be keep
 */
protected boolean pruneEdge(final ConnectedEdge edge, final CspfPath path) {
    /* Check that Constraints are initialized */
    if (constraints == null) {
        LOG.warn("Constraints not set");
        return true;
    }
    /* Edge could point to an unknown Vertex e.g. with inter-domain link */
    if (edge.getDestination() == null || edge.getDestination().getVertex() == null) {
        LOG.debug("No Destination");
        return true;
    }
    /* Check that Edge have attributes */
    EdgeAttributes attributes = edge.getEdge() != null ? edge.getEdge().getEdgeAttributes() : null;
    if (attributes == null) {
        LOG.debug("No attributes");
        return true;
    }
    /* Check that Edge belongs to the requested address family */
    switch(constraints.getAddressFamily()) {
        case Ipv4:
            if (attributes.getRemoteAddress() == null || attributes.getRemoteAddress().getIpv4Address() == null) {
                LOG.debug("No Ipv4 address");
                return true;
            }
            break;
        case Ipv6:
            if (attributes.getRemoteAddress() == null || attributes.getRemoteAddress().getIpv6Address() == null) {
                LOG.debug("No Ipv6 address");
                return true;
            }
            break;
        case SrIpv4:
            if (getIpv4NodeSid(edge.getDestination()) == null) {
                LOG.debug("No Node-SID for IPv4");
                return true;
            }
            if (attributes.getAdjSid() == null) {
                LOG.debug("No Adjacency-SID");
                return true;
            }
            break;
        case SrIpv6:
            if (getIpv6NodeSid(edge.getDestination()) == null) {
                LOG.debug("No Node-SID for IPv6");
                return true;
            }
            if (attributes.getAdjSid() == null) {
                LOG.debug("No SR Adjacency-SID");
                return true;
            }
            break;
        default:
            return true;
    }
    /* Skip checking other Constraints for simple SPF algorithm */
    if (this instanceof ShortestPathFirst) {
        LOG.trace("Edge {} is valid for Simple Path Computation", edge);
        return false;
    }
    /*
         * If specified, check that total TE Metric up to this edge respects the
         * initial constraints
         */
    if (constraints.getTeMetric() != null) {
        if (attributes.getTeMetric() == null) {
            return true;
        } else {
            int totalCost = attributes.getTeMetric().intValue() + path.getCost();
            if (totalCost > constraints.getTeMetric().intValue()) {
                LOG.debug("TeMetric {} exceed constraint {}", totalCost, constraints.getTeMetric().intValue());
                return true;
            }
        }
    }
    /*
         * If specified, check that total Delay up to this edge respects the
         * initial constraints
         */
    if (constraints.getDelay() != null) {
        if (attributes.getDelay() == null) {
            return true;
        } else {
            int totalDelay = attributes.getDelay().getValue().intValue() + path.getDelay();
            if (totalDelay > constraints.getDelay().getValue().intValue()) {
                LOG.debug("Delay {} exceed constraint {}", totalDelay, constraints.getDelay().getValue().intValue());
                return true;
            }
        }
    }
    /* Check that Edge respect Loss constraint */
    if (constraints.getLoss() != null) {
        if (attributes.getLoss() == null || attributes.getLoss().getValue().intValue() > constraints.getLoss().getValue().intValue()) {
            return true;
        }
    }
    /* Check that Edge meet Bandwidth constraint */
    int cos = 0;
    if (constraints.getClassType() != null) {
        cos = constraints.getClassType().intValue();
    }
    if (constraints.getBandwidth() != null) {
        if (attributes.getMaxLinkBandwidth() == null || attributes.getMaxResvLinkBandwidth() == null || attributes.getUnreservedBandwidth() == null || attributes.getUnreservedBandwidth().get(cos) == null) {
            return true;
        } else {
            Long bandwidth = constraints.getBandwidth().getValue().longValue();
            Long unrsv = 0L;
            for (UnreservedBandwidth unResBw : attributes.getUnreservedBandwidth()) {
                if (unResBw.getClassType().intValue() == cos) {
                    unrsv = unResBw.getBandwidth().getValue().longValue();
                    break;
                }
            }
            if (unrsv < bandwidth || attributes.getMaxLinkBandwidth().getValue().longValue() < bandwidth || attributes.getMaxResvLinkBandwidth().getValue().longValue() < bandwidth) {
                LOG.debug("Bandwidth constraint is not met");
                return true;
            }
        }
    }
    /* Check that Edge belongs to admin group */
    if (constraints.getAdminGroup() != null && !constraints.getAdminGroup().equals(attributes.getAdminGroup())) {
        LOG.debug("Not in the requested admin-group");
        return true;
    }
    /*
         * OK. All is fine. We can consider this Edge valid, so not to be prune
         */
    LOG.trace("Edge {} is valid for Constrained Path Computation", edge);
    return false;
}
Also used : UnreservedBandwidth(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidth) EdgeAttributes(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.EdgeAttributes)

Example 2 with Algorithm

use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.Algorithm in project bgpcep by opendaylight.

the class ConstrainedShortestPathFirst method computeP2pPath.

@Override
public ConstrainedPath computeP2pPath(final VertexKey src, final VertexKey dst, final PathConstraints cts) {
    LOG.info("Start CSPF Path Computation from {} to {} with constraints {}", src, dst, cts);
    /* Initialize algorithm */
    this.constraints = cts;
    ConstrainedPathBuilder cpathBuilder = initializePathComputation(src, dst);
    if (cpathBuilder.getStatus() == ComputationStatus.Failed) {
        return cpathBuilder.build();
    }
    cpathBuilder.setBandwidth(cts.getBandwidth()).setClassType(cts.getClassType());
    visitedVertices.clear();
    /* Process all Connected Vertex until priority queue becomes empty. Connected Vertices are added into the
         * priority queue when processing the next Connected Vertex: see relaxMC() method */
    int currentCost = Integer.MAX_VALUE;
    while (priorityQueue.size() != 0) {
        CspfPath currentPath = priorityQueue.poll();
        visitedVertices.put(currentPath.getVertexKey(), currentPath);
        LOG.debug("Got path to Vertex {} from Priority Queue", currentPath.getVertex());
        List<ConnectedEdge> edges = currentPath.getVertex().getOutputConnectedEdges();
        for (ConnectedEdge edge : edges) {
            /* Skip Connected Edges that must be prune i.e. Edges that not satisfy the given constraints,
                 * in particular the Bandwidth, TE Metric and Delay. */
            if (pruneEdge(edge, currentPath)) {
                LOG.trace("  Prune Edge {}", edge);
                continue;
            }
            if (relaxMultiConstraints(edge, currentPath) && pathDestination.getCost() < currentCost) {
                currentCost = pathDestination.getCost();
                cpathBuilder.setPathDescription(getPathDescription(pathDestination.getPath())).setMetric(Uint32.valueOf(pathDestination.getCost())).setStatus(ComputationStatus.Active);
                LOG.debug("  Found a valid path up to destination {}", cpathBuilder.getPathDescription());
            }
        }
    }
    /* The priority queue is empty => all the possible (vertex, path) elements have been explored
         * The "ConstrainedPathBuilder" object contains the optimal path if it exists
         * Otherwise an empty path with status failed is returned
         */
    if (cpathBuilder.getStatus() == ComputationStatus.InProgress || cpathBuilder.getPathDescription().size() == 0) {
        cpathBuilder.setStatus(ComputationStatus.Failed);
    } else {
        cpathBuilder.setStatus(ComputationStatus.Completed);
    }
    return cpathBuilder.build();
}
Also used : ConstrainedPathBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ConstrainedPathBuilder) ConnectedEdge(org.opendaylight.graph.ConnectedEdge)

Example 3 with Algorithm

use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.Algorithm in project bgpcep by opendaylight.

the class PathComputationServer method getConstrainedPath.

@Override
public ListenableFuture<RpcResult<GetConstrainedPathOutput>> getConstrainedPath(final GetConstrainedPathInput input) {
    final GetConstrainedPathOutputBuilder output = new GetConstrainedPathOutputBuilder();
    LOG.info("Got Path Computation Service request");
    /* First, get graph */
    final ConnectedGraph cgraph = graphProvider.getConnectedGraph(input.getGraphName());
    if (cgraph == null) {
        output.setStatus(ComputationStatus.Failed);
        return RpcResultBuilder.<GetConstrainedPathOutput>failed().withError(RpcError.ErrorType.RPC, "Unknown Graph Name").buildFuture();
    }
    /* get a new Path Computation Algorithm according to Input choice */
    PathComputationAlgorithm algo = getPathComputationAlgorithm(cgraph, input.getAlgorithm());
    if (algo == null) {
        output.setStatus(ComputationStatus.Failed);
        return RpcResultBuilder.<GetConstrainedPathOutput>failed().withError(RpcError.ErrorType.RPC, "Unknown Path Computation Algorithm").buildFuture();
    }
    /*
         * Request Path Computation for given source, destination and
         * constraints
         */
    final VertexKey source = new VertexKey(input.getSource());
    final VertexKey destination = new VertexKey(input.getDestination());
    LOG.info("Call Path Computation {} algorithm for path from {} to {} with contraints {}", input.getAlgorithm().getName(), source, destination, input.getConstraints());
    final ConstrainedPath cpath = algo.computeP2pPath(source, destination, input.getConstraints());
    /* Send back the Computed Path */
    output.setPathDescription(cpath.getPathDescription()).setStatus(cpath.getStatus()).setComputedMetric(cpath.getMetric()).setComputedTeMetric(cpath.getTeMetric()).setComputedDelay(cpath.getDelay());
    return RpcResultBuilder.success(output.build()).buildFuture();
}
Also used : GetConstrainedPathOutput(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.GetConstrainedPathOutput) ConnectedGraph(org.opendaylight.graph.ConnectedGraph) ConstrainedPath(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ConstrainedPath) GetConstrainedPathOutputBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.GetConstrainedPathOutputBuilder) VertexKey(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey) PathComputationAlgorithm(org.opendaylight.algo.PathComputationAlgorithm)

Example 4 with Algorithm

use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.Algorithm in project bgpcep by opendaylight.

the class SrNodeAttributesParser method parseSrAlgorithms.

public static SrAlgorithm parseSrAlgorithms(final ByteBuf buffer) {
    final SrAlgorithmBuilder builder = new SrAlgorithmBuilder();
    final List<Algorithm> algs = new ArrayList<>();
    while (buffer.isReadable()) {
        algs.add(Algorithm.forValue(buffer.readUnsignedByte()));
    }
    builder.setAlgorithms(algs);
    return builder.build();
}
Also used : ArrayList(java.util.ArrayList) SrAlgorithmBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.state.SrAlgorithmBuilder) Algorithm(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.Algorithm) SrAlgorithm(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.state.SrAlgorithm)

Example 5 with Algorithm

use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.Algorithm in project bgpcep by opendaylight.

the class AbstractBestPathSelector method isExistingPathBetter.

/**
 * Chooses best route according to BGP best path selection.
 *
 * @param state attributes of the new route
 * @return true if the existing path is better, false if the new path is better
 */
protected boolean isExistingPathBetter(@NonNull final BestPathState state) {
    // 0. draft-uttaro-idr-bgp-persistence-04 defines "depreferenced" paths
    final boolean stateDepref = state.isDepreferenced();
    if (this.bestState.isDepreferenced() != stateDepref) {
        return stateDepref;
    }
    // 1. prefer path with accessible nexthop
    // - we assume that all nexthops are accessible
    /*
         * 2. prefer path with higher LOCAL_PREF
         *
         * FIXME: for eBGP cases (when the LOCAL_PREF is missing), we should assign a policy-based preference
         *        before we ever get here.
         */
    final Uint32 bestLocal = this.bestState.getLocalPref();
    final Uint32 stateLocal = state.getLocalPref();
    if (stateLocal != null) {
        if (bestLocal == null) {
            return true;
        }
        final int cmp = stateLocal.compareTo(bestLocal);
        if (cmp != 0) {
            return cmp < 0;
        }
    } else if (bestLocal != null) {
        return false;
    }
    // 4. prefer the path with the shortest AS_PATH.
    if (this.bestState.getAsPathLength() != state.getAsPathLength()) {
        return this.bestState.getAsPathLength() < state.getAsPathLength();
    }
    // - IGP is lower than Exterior Gateway Protocol (EGP), and EGP is lower than INCOMPLETE
    if (!this.bestState.getOrigin().equals(state.getOrigin())) {
        final BgpOrigin bo = this.bestState.getOrigin();
        final BgpOrigin no = state.getOrigin();
        // This trick relies on the order in which the values are declared in the model.
        return no.ordinal() > bo.ordinal();
    }
    // FIXME: we should be able to cache the best AS
    final long bestAs = this.bestState.getPeerAs();
    final long newAs = state.getPeerAs();
    /*
         * Checks 6 and 7 are mutually-exclusive, as MEDs are comparable
         * only when the routes originated from the same AS. On the other
         * hand, when they are from the same AS, they are in the same iBGP/eBGP
         * relationship.
         *
         */
    if (bestAs == newAs) {
        // 6. prefer the path with the lowest multi-exit discriminator (MED)
        final Boolean cmp = firstLower(this.bestState.getMultiExitDisc(), state.getMultiExitDisc());
        if (cmp != null) {
            return cmp;
        }
    } else {
        /*
             * 7. prefer eBGP over iBGP paths
             *
             * EBGP is peering between two different AS, whereas IBGP is between same AS (Autonomous System),
             * so we just compare the AS numbers to our AS.
             *
             * FIXME: we should know this information from the peer directly.
             */
        if (this.ourAs != bestAs && this.ourAs == newAs) {
            return true;
        }
    }
    /*
         * 10. Prefer the route that comes from the BGP router with the lowest router ID.
         *
         * This is normally guaranteed by the iteration order of our caller, which runs selection
         * in the order of increasing router ID, but RFC-4456 Route Reflection throws a wrench into that.
         *
         * With RFC-5004, this gets a bit easier, because it completely eliminates step f) and later :-)
         *
         * RFC-5004 states that this algorithm should end here and select existing path over new path in the
         * best path selection process. Benefits are listed in the RFC: @see http://tools.ietf.org/html/rfc500
         * - This algorithm SHOULD NOT be applied when either path is from a BGP Confederation peer.
         *  - not applicable, we don't deal with confederation peers
         * - The algorithm SHOULD NOT be applied when both paths are from peers with an identical BGP identifier
         *   (i.e., there exist parallel BGP sessions between two BGP speakers).
         *  - not applicable, BUG-2631 prevents parallel sessions to be created.
         */
    return true;
}
Also used : Uint32(org.opendaylight.yangtools.yang.common.Uint32) BgpOrigin(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.BgpOrigin)

Aggregations

PathComputationAlgorithm (org.opendaylight.algo.PathComputationAlgorithm)3 VertexKey (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey)3 ConstrainedPath (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ConstrainedPath)3 ConnectedEdge (org.opendaylight.graph.ConnectedEdge)2 Eid (org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid)2 AlgorithmType (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.AlgorithmType)2 ConstrainedPathBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ConstrainedPathBuilder)2 PathConstraints (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.PathConstraints)2 Uint32 (org.opendaylight.yangtools.yang.common.Uint32)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConnectedGraph (org.opendaylight.graph.ConnectedGraph)1 IRowVisitor (org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor)1 MappingData (org.opendaylight.lispflowmapping.lisp.type.MappingData)1 MappingAuthkey (org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey)1 SrAlgorithm (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.state.SrAlgorithm)1 SrAlgorithmBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.state.SrAlgorithmBuilder)1 Algorithm (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.Algorithm)1 BgpOrigin (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.BgpOrigin)1