use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.order.tlv.Order in project bgpcep by opendaylight.
the class AddPathAbstractRouteEntry method fillAdjRibsOut.
@SuppressWarnings("unchecked")
private void fillAdjRibsOut(final boolean isFirstBestPath, final Attributes attributes, final Route routeNonAddPath, final Route routeAddPath, final Identifier routeKeyAddNonPath, final Identifier routeKeyAddPath, final PeerId fromPeerId, final TablesKey localTK, final RouteEntryDependenciesContainer routeEntryDep, final WriteTransaction tx) {
/*
* We need to keep track of routers and populate adj-ribs-out, too. If we do not, we need to
* expose from which client a particular route was learned from in the local RIB, and have
* the listener perform filtering.
*
* We walk the policy set in order to minimize the amount of work we do for multiple peers:
* if we have two eBGP peers, for example, there is no reason why we should perform the translation
* multiple times.
*/
final RIBSupport ribSupport = routeEntryDep.getRibSupport();
for (final Peer toPeer : this.peerTracker.getPeers()) {
if (!filterRoutes(fromPeerId, toPeer, localTK)) {
continue;
}
final boolean destPeerSupAddPath = toPeer.supportsAddPathSupported(localTK);
if (toPeer.getPeerId().getValue().equals("bgp://127.0.0.5")) {
LOG.debug("Write route {} to peer AdjRibsOut {}", toPeer.getPeerId());
}
if (peersSupportsAddPathOrIsFirstBestPath(destPeerSupAddPath, isFirstBestPath)) {
Optional<Attributes> effAttrib = Optional.empty();
final Peer fromPeer = this.peerTracker.getPeer(fromPeerId);
if (fromPeer != null && attributes != null) {
final BGPRouteEntryExportParameters baseExp = new BGPRouteEntryExportParametersImpl(fromPeer, toPeer);
effAttrib = routeEntryDep.getRoutingPolicies().applyExportPolicies(baseExp, attributes);
}
Route newRoute = null;
InstanceIdentifier ribOutRoute = null;
if (destPeerSupAddPath) {
newRoute = routeAddPath;
ribOutRoute = ribSupport.createRouteIdentifier(toPeer.getRibOutIId(localTK), routeKeyAddPath);
} else if (!this.oldNonAddPathBestPathTheSame) {
ribOutRoute = ribSupport.createRouteIdentifier(toPeer.getRibOutIId(localTK), routeKeyAddNonPath);
newRoute = routeNonAddPath;
}
if (effAttrib.isPresent() && newRoute != null) {
LOG.debug("Write route {} to peer AdjRibsOut {}", newRoute, toPeer.getPeerId());
tx.put(LogicalDatastoreType.OPERATIONAL, ribOutRoute, newRoute);
tx.put(LogicalDatastoreType.OPERATIONAL, ribOutRoute.child(Attributes.class), effAttrib.get());
} else if (ribOutRoute != null) {
LOG.trace("Removing {} from transaction for peer {}", ribOutRoute, toPeer.getPeerId());
tx.delete(LogicalDatastoreType.OPERATIONAL, ribOutRoute);
}
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.order.tlv.Order in project controller by opendaylight.
the class CarProvider method registerCommitCohort.
@Override
public synchronized ListenableFuture<RpcResult<RegisterCommitCohortOutput>> registerCommitCohort(final RegisterCommitCohortInput input) {
if (commitCohortReg.get() != null) {
return RpcResultBuilder.success(new RegisterCommitCohortOutputBuilder().build()).buildFuture();
}
final DOMDataTreeCommitCohortRegistry commitCohortRegistry = domDataBroker.getExtensions().getInstance(DOMDataTreeCommitCohortRegistry.class);
if (commitCohortRegistry == null) {
// Shouldn't happen
return RpcResultBuilder.<RegisterCommitCohortOutput>failed().withError(ErrorType.APPLICATION, "DOMDataTreeCommitCohortRegistry not found").buildFuture();
}
// Note: it may look strange that we specify the CarEntry.QNAME twice in the path below. This must be done in
// order to register the commit cohort for CarEntry instances. In the underlying data tree, a yang list is
// represented as a MapNode with MapEntryNodes representing the child list entries. Therefore, in order to
// address a list entry, you must specify the path argument for the MapNode and the path argument for the
// MapEntryNode. In the path below, the first CarEntry.QNAME argument addresses the MapNode and, since we want
// to address all list entries, the second path argument is wild-carded by specifying just the CarEntry.QNAME.
final YangInstanceIdentifier carEntryPath = YangInstanceIdentifier.builder(YangInstanceIdentifier.of(Cars.QNAME)).node(CarEntry.QNAME).node(CarEntry.QNAME).build();
commitCohortReg.set(commitCohortRegistry.registerCommitCohort(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, carEntryPath), new CarEntryDataTreeCommitCohort()));
LOG_CAR_PROVIDER.info("Registered commit cohort");
return RpcResultBuilder.success(new RegisterCommitCohortOutputBuilder().build()).buildFuture();
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.order.tlv.Order in project bgpcep by opendaylight.
the class SimpleAttributeRegistry method parseAttributes.
@Override
public ParsedAttributes parseAttributes(final ByteBuf buffer, final PeerSpecificParserConstraint constraint) throws BGPDocumentedException, BGPParsingException {
final RevisedErrorHandling errorHandling = RevisedErrorHandling.from(constraint);
final Map<Integer, RawAttribute> attributes = new TreeMap<>();
BGPTreatAsWithdrawException withdrawCause = null;
while (buffer.isReadable()) {
try {
addAttribute(buffer, errorHandling, attributes);
} catch (BGPTreatAsWithdrawException e) {
LOG.info("Failed to completely parse attributes list.");
withdrawCause = e;
break;
}
}
/*
* TreeMap guarantees that we will be invoking the parser in the order
* of increasing attribute type.
*/
// We may have multiple attribute errors, each specifying a withdraw. We need to finish parsing the message
// all attributes before we can decide whether we can discard attributes, or whether we need to terminate
// the session.
final AttributesBuilder builder = new AttributesBuilder();
for (final Entry<Integer, RawAttribute> entry : attributes.entrySet()) {
LOG.debug("Parsing attribute type {}", entry.getKey());
final RawAttribute a = entry.getValue();
try {
a.parser.parseAttribute(a.buffer, builder, errorHandling, constraint);
} catch (BGPTreatAsWithdrawException e) {
LOG.info("Attribute {} indicated treat-as-withdraw", entry.getKey(), e);
if (withdrawCause == null) {
withdrawCause = e;
} else {
withdrawCause.addSuppressed(e);
}
}
}
builder.setUnrecognizedAttributes(BindingMap.ordered(this.unrecognizedAttributes));
return new ParsedAttributes(builder.build(), withdrawCause);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.order.tlv.Order 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;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.order.tlv.Order in project bgpcep by opendaylight.
the class BGPSessionImpl method handleMessage.
/**
* Handles incoming message based on their type.
*
* @param msg incoming message
*/
void handleMessage(final Notification msg) {
// synchronize on listener and then on this object to ensure correct order of locking
synchronized (this.listener) {
synchronized (this) {
if (this.state == State.IDLE) {
return;
}
try {
// Update last reception time
this.lastMessageReceivedAt = System.nanoTime();
if (msg instanceof Open) {
// Open messages should not be present here
terminate(new BGPDocumentedException(null, BGPError.FSM_ERROR));
} else if (msg instanceof Notify) {
final Notify notify = (Notify) msg;
// Notifications are handled internally
LOG.info("Session closed because Notification message received: {} / {}, data={}", notify.getErrorCode(), notify.getErrorSubcode(), notify.getData() != null ? ByteBufUtil.hexDump(notify.getData()) : null);
notifyTerminationReasonAndCloseWithoutMessage(notify.getErrorCode(), notify.getErrorSubcode());
} else if (msg instanceof Keepalive) {
// Keepalives are handled internally
LOG.trace("Received KeepAlive message.");
this.kaCounter++;
if (this.kaCounter >= 2) {
this.sync.kaReceived();
}
} else if (msg instanceof RouteRefresh) {
this.listener.onMessage(this, msg);
} else if (msg instanceof Update) {
this.listener.onMessage(this, msg);
this.sync.updReceived((Update) msg);
} else {
LOG.warn("Ignoring unhandled message: {}.", msg.getClass());
}
this.sessionState.messageReceived(msg);
} catch (final BGPDocumentedException e) {
terminate(e);
}
}
}
}
Aggregations