use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes in project bgpcep by opendaylight.
the class SimpleAttributeRegistry method parseAttributes.
@Override
public Attributes parseAttributes(final ByteBuf buffer, final PeerSpecificParserConstraint constraint) throws BGPDocumentedException, BGPParsingException {
final Map<Integer, RawAttribute> attributes = new TreeMap<>();
while (buffer.isReadable()) {
addAttribute(buffer, attributes);
}
/*
* TreeMap guarantees that we will be invoking the parser in the order
* of increasing attribute type.
*/
final AttributesBuilder builder = new AttributesBuilder();
for (final Entry<Integer, RawAttribute> e : attributes.entrySet()) {
LOG.debug("Parsing attribute type {}", e.getKey());
final RawAttribute a = e.getValue();
a.parser.parseAttribute(a.buffer, builder, constraint);
}
builder.setUnrecognizedAttributes(this.unrecognizedAttributes);
return builder.build();
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes 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.bgp.message.rev171207.path.attributes.Attributes in project bgpcep by opendaylight.
the class AddPathAbstractRouteEntry method selectBest.
private void selectBest(final RouteKey key, final AddPathSelector selector) {
final int offset = this.offsets.offsetOf(key);
final Attributes attributes = this.offsets.getValue(this.values, offset);
final long pathId = this.offsets.getValue(this.pathsId, offset);
LOG.trace("Processing router key {} attributes {}", key, attributes);
selector.processPath(attributes, key, offset, pathId);
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes 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) {
/*
* 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.
*/
if (this.bestState.getLocalPref() == null && state.getLocalPref() != null) {
return true;
}
if (this.bestState.getLocalPref() != null && state.getLocalPref() == null) {
return false;
}
if (state.getLocalPref() != null && state.getLocalPref() > this.bestState.getLocalPref()) {
return false;
}
if (state.getLocalPref() != null && state.getLocalPref() < this.bestState.getLocalPref()) {
return true;
}
// 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.equals(newAs)) {
// 6. prefer the path with the lowest multi-exit discriminator (MED)
if (this.bestState.getMultiExitDisc() != null || state.getMultiExitDisc() != null) {
final Long bmed = this.bestState.getMultiExitDisc();
final Long nmed = state.getMultiExitDisc();
return nmed > bmed;
}
} 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.bgp.message.rev171207.path.attributes.Attributes in project bgpcep by opendaylight.
the class TestUtil method createAttributes.
private static Attributes createAttributes() {
final List<AsNumber> asSequences = Lists.newArrayList(new AsNumber(72L), new AsNumber(82L), new AsNumber(92L));
final List<Segments> segments = Lists.newArrayList();
final SegmentsBuilder segmentsBuild = new SegmentsBuilder();
segmentsBuild.setAsSequence(asSequences).build();
final AttributesBuilder attribBuilder = new AttributesBuilder().setAggregator(new AggregatorBuilder().setAsNumber(new AsNumber(72L)).setNetworkAddress(new Ipv4Address(IPV4_ADDRESS_20)).build()).setAigp(new AigpBuilder().setAigpTlv(new AigpTlvBuilder().setMetric(new AccumulatedIgpMetric(BigInteger.ONE)).build()).build()).setAsPath(new AsPathBuilder().setSegments(segments).build()).setAtomicAggregate(new AtomicAggregateBuilder().build()).setClusterId(new ClusterIdBuilder().setCluster(Lists.newArrayList(new ClusterIdentifier(IPV4_ADDRESS_30), new ClusterIdentifier(IPV4_ADDRESS_40))).build()).setCNextHop(new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(IPV4_ADDRESS_100).build()).build()).setCommunities(createCommunities()).setLocalPref(new LocalPrefBuilder().setPref(2L).build()).setMultiExitDisc(new MultiExitDiscBuilder().setMed(123L).build()).setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build()).setOriginatorId(new OriginatorIdBuilder().setOriginator(IPV4_ADDRESS_12).build()).setUnrecognizedAttributes(new ArrayList<>());
return attribBuilder.build();
}
Aggregations