* multiple times.
*/
for (final PeerRole role : PeerRole.values()) {
- if (PeerRole.Internal.equals(role)) {
- continue;
- }
final PeerExportGroup peerGroup = peerPT.getPeerGroup(role);
if (peerGroup != null) {
final ContainerNode effectiveAttributes = peerGroup.effectiveAttributes(routePeerId, attributes);
* multiple times.
*/
for (final PeerRole role : PeerRole.values()) {
- if (PeerRole.Internal.equals(role)) {
- continue;
- }
final PeerExportGroup peerGroup = peerPT.getPeerGroup(role);
if (peerGroup != null) {
final ContainerNode effAttrib = peerGroup.effectiveAttributes(routePeerId, attributes);
}
}
+ typedef simple-routing-policy {
+ type enumeration {
+ enum announce-none { description "Don't announce routes to this peer"; }
+ enum learn-none { description "Don't learn routes from this peer"; }
+ }
+ }
+
grouping route {
uses bgp-msg:path-attributes;
}
type peer-role;
mandatory true;
}
+ leaf simple-routing-policy {
+ type simple-routing-policy;
+ }
list supported-tables {
key "afi safi";
uses bgp-mp:bgp-add-path-table-type;
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.bgp.rib.rev130925.ApplicationRib;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
final RIB r = getTargetRibDependency();
final IpAddress bgpPeerId = new IpAddress(getBgpPeerId());
- final BGPPeer bgpClientPeer = new BGPPeer(bgpPeerId.getIpv4Address().getValue(), r, PeerRole.Internal, null);
+ final BGPPeer bgpClientPeer = new BGPPeer(bgpPeerId.getIpv4Address().getValue(), r, PeerRole.Internal, SimpleRoutingPolicy.AnnounceNone, null);
final BGPSessionPreferences prefs = new BGPSessionPreferences(r.getLocalAs(), 0, r.getBgpIdentifier(),
r.getLocalAs(), Collections.emptyList());
final BGPPeer bgpClientPeer;
final IpAddress host = getNormalizedHost();
if (getPeerRole() != null) {
- bgpClientPeer = new BGPPeer(peerName(host), r, getPeerRole(), getRpcRegistryDependency());
+ bgpClientPeer = new BGPPeer(peerName(host), r, getPeerRole(), getSimpleRoutingPolicy(), getRpcRegistryDependency());
} else {
- bgpClientPeer = new BGPPeer(peerName(host), r, PeerRole.Ibgp, getRpcRegistryDependency());
+ bgpClientPeer = new BGPPeer(peerName(host), r, PeerRole.Ibgp, getSimpleRoutingPolicy(), getRpcRegistryDependency());
}
bgpClientPeer.registerRootRuntimeBean(getRootRuntimeBeanRegistratorWrapper());
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.protocol.bgp.rib.impl;
-
-import com.google.common.base.Optional;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.SupportedTables;
-import org.opendaylight.yangtools.yang.binding.BindingMapping;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Maintains the mapping of PeerId -> Role. Subclasses get notified of changes and can do their
- * own thing.
- */
-abstract class AbstractPeerRoleTracker {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractPeerRoleTracker.class);
-
- public void onDataTreeChanged(final DataTreeCandidateNode change, final YangInstanceIdentifier peerPath) {
- // Check for removal
- final Optional<NormalizedNode<?, ?>> maybePeerRole = change.getDataAfter();
- LOG.debug("Data Changed for Peer role {} path {}, dataBefore {}, dataAfter {}", change.getIdentifier(),
- peerPath , change.getDataBefore(), maybePeerRole);
-
- final PeerRole role;
- if (maybePeerRole.isPresent()) {
- final LeafNode<?> peerRoleLeaf = (LeafNode<?>) maybePeerRole.get();
- // We could go for a codec, but this is simpler and faster
- role = PeerRole.valueOf(BindingMapping.getClassName((String) peerRoleLeaf.getValue()));
- } else {
- role = null;
- }
- peerRoleChanged(peerPath, role);
- }
-
- static final NodeIdentifier PEER_ROLE_NID = new NodeIdentifier(QName.create(Peer.QNAME, "peer-role").intern());
- static final NodeIdentifier PEER_TABLES = new NodeIdentifier(SupportedTables.QNAME);
-
- protected AbstractPeerRoleTracker() {
- }
-
- /**
- * Invoked whenever a peer role changes.
- *
- * @param peerPath Peer's path
- * @param role Peer's new role, null indicates the peer has disappeared.
- */
- protected abstract void peerRoleChanged(@Nonnull YangInstanceIdentifier peerPath, @Nullable PeerRole role);
-}
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContext;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils;
+import org.opendaylight.protocol.bgp.rib.spi.PeerRoleUtil;
import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.SendReceive;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamilies;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.AdjRibIn;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.AdjRibOut;
private static final NodeIdentifier PEER_TABLES = new NodeIdentifier(SupportedTables.QNAME);
private static final NodeIdentifier TABLES = new NodeIdentifier(Tables.QNAME);
private static final QName SEND_RECEIVE = QName.create(SupportedTables.QNAME, "send-receive").intern();
+ static final NodeIdentifier SIMPLE_ROUTING_POLICY_NID = new NodeIdentifier(QName.create(Peer.QNAME, "simple-routing-policy").intern());
// FIXME: is there a utility method to construct this?
private static final ContainerNode EMPTY_ADJRIBIN = Builders.containerBuilder().withNodeIdentifier(ADJRIBIN).addChild(ImmutableNodes.mapNodeBuilder(Tables.QNAME).build()).build();
private final YangInstanceIdentifier peerPath;
private final YangInstanceIdentifier ribPath;
private final DOMTransactionChain chain;
- private final PeerId peerId;
- private final String role;
+ private final PeerRole role;
+ private final Optional<SimpleRoutingPolicy> simpleRoutingPolicy;
- private AdjRibInWriter(final YangInstanceIdentifier ribPath, final DOMTransactionChain chain, final PeerId peerId, final String role, final YangInstanceIdentifier peerPath, final Map<TablesKey, TableContext> tables) {
+ private AdjRibInWriter(final YangInstanceIdentifier ribPath, final DOMTransactionChain chain, final PeerRole role,
+ final Optional<SimpleRoutingPolicy> simpleRoutingPolicy, final YangInstanceIdentifier peerPath, final Map<TablesKey, TableContext> tables) {
this.ribPath = Preconditions.checkNotNull(ribPath);
this.chain = Preconditions.checkNotNull(chain);
this.tables = Preconditions.checkNotNull(tables);
this.role = Preconditions.checkNotNull(role);
+ this.simpleRoutingPolicy = simpleRoutingPolicy;
this.peerPath = peerPath;
- this.peerId = peerId;
- }
-
- // We could use a codec, but this should be fine, too
- private static String roleString(final PeerRole role) {
- switch (role) {
- case Ebgp:
- return "ebgp";
- case Ibgp:
- return "ibgp";
- case RrClient:
- return "rr-client";
- case Internal:
- return "internal";
- default:
- throw new IllegalArgumentException("Unhandled role " + role);
- }
}
/**
* Create a new writer using a transaction chain.
*
* @param role peer's role
- * @param chain transaction chain
- * @return A fresh writer instance
+ * @param simpleRoutingPolicy simple Routing Policy {@link SimpleRoutingPolicy}
+ *@param chain transaction chain @return A fresh writer instance
*/
- static AdjRibInWriter create(@Nonnull final YangInstanceIdentifier ribId, @Nonnull final PeerRole role, @Nonnull final DOMTransactionChain chain) {
- return new AdjRibInWriter(ribId, chain, null, roleString(role), null, Collections.<TablesKey, TableContext>emptyMap());
+ static AdjRibInWriter create(@Nonnull final YangInstanceIdentifier ribId, @Nonnull final PeerRole role, final Optional<SimpleRoutingPolicy> simpleRoutingPolicy,
+ @Nonnull final DOMTransactionChain chain) {
+ return new AdjRibInWriter(ribId, chain, role, simpleRoutingPolicy, null, Collections.emptyMap());
}
/**
* @return New writer
*/
AdjRibInWriter transform(final PeerId newPeerId, final RIBSupportContextRegistry registry, final Set<TablesKey> tableTypes,
- final List<AddressFamilies> addPathTablesType, final boolean isAppPeer) {
+ final List<AddressFamilies> addPathTablesType) {
final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
final YangInstanceIdentifier newPeerPath;
- newPeerPath = createEmptyPeerStructure(newPeerId, isAppPeer, tx);
- final ImmutableMap<TablesKey, TableContext> tb = createNewTableInstances(newPeerPath, isAppPeer, registry, tableTypes, addPathTablesType, tx);
+ newPeerPath = createEmptyPeerStructure(newPeerId, tx);
+ final ImmutableMap<TablesKey, TableContext> tb = createNewTableInstances(newPeerPath, registry, tableTypes, addPathTablesType, tx);
tx.submit();
- return new AdjRibInWriter(this.ribPath, this.chain, newPeerId, this.role, newPeerPath, tb);
+ return new AdjRibInWriter(this.ribPath, this.chain, this.role, this.simpleRoutingPolicy, newPeerPath, tb);
}
/**
* Create new table instances, potentially creating their empty entries
* @param newPeerPath
- * @param isAppPeer
* @param registry
* @param tableTypes
* @param addPathTablesType
* @param tx
* @return
*/
- private ImmutableMap<TablesKey, TableContext> createNewTableInstances(final YangInstanceIdentifier newPeerPath, final boolean isAppPeer,
+ private ImmutableMap<TablesKey, TableContext> createNewTableInstances(final YangInstanceIdentifier newPeerPath,
final RIBSupportContextRegistry registry, final Set<TablesKey> tableTypes, final List<AddressFamilies> addPathTablesType,
final DOMDataWriteTransaction tx) {
LOG.warn("No support for table type {}, skipping it", tableKey);
continue;
}
- installAdjRibsOutTables(isAppPeer, newPeerPath, rs, instanceIdentifierKey, tableKey, addPathTableMaps.get(tableKey), tx);
+ installAdjRibsOutTables(newPeerPath, rs, instanceIdentifierKey, tableKey, addPathTableMaps.get(tableKey), tx);
installAdjRibInTables(newPeerPath, tableKey, rs, instanceIdentifierKey, tx, tb);
}
return tb.build();
tb.put(tableKey, ctx);
}
- private void installAdjRibsOutTables(final boolean isAppPeer, final YangInstanceIdentifier newPeerPath, final RIBSupportContext rs,
+ private void installAdjRibsOutTables(final YangInstanceIdentifier newPeerPath, final RIBSupportContext rs,
final NodeIdentifierWithPredicates instanceIdentifierKey, final TablesKey tableKey, final SendReceive sendReceive,
final DOMDataWriteTransaction tx) {
- if (!isAppPeer) {
+ if (!isAnnounceNone(this.simpleRoutingPolicy)) {
final NodeIdentifierWithPredicates supTablesKey = RibSupportUtils.toYangKey(SupportedTables.QNAME, tableKey);
final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> tt = Builders.mapEntryBuilder().withNodeIdentifier(supTablesKey);
for (final Entry<QName, Object> e : supTablesKey.getKeyValues().entrySet()) {
}
}
- private YangInstanceIdentifier createEmptyPeerStructure(final PeerId newPeerId, final boolean isAppPeer, final DOMDataWriteTransaction tx) {
+ private YangInstanceIdentifier createEmptyPeerStructure(final PeerId newPeerId, final DOMDataWriteTransaction tx) {
final NodeIdentifierWithPredicates peerKey = IdentifierUtils.domPeerId(newPeerId);
final YangInstanceIdentifier newPeerPath = this.ribPath.node(Peer.QNAME).node(peerKey);
- tx.put(LogicalDatastoreType.OPERATIONAL, newPeerPath, peerSkeleton(peerKey, newPeerId.getValue(), isAppPeer));
+ tx.put(LogicalDatastoreType.OPERATIONAL, newPeerPath, peerSkeleton(peerKey, newPeerId.getValue()));
LOG.debug("New peer {} structure installed.", newPeerPath);
return newPeerPath;
}
@VisibleForTesting
- MapEntryNode peerSkeleton(final NodeIdentifierWithPredicates peerKey, final String peerId, final boolean isAppPeer) {
+ MapEntryNode peerSkeleton(final NodeIdentifierWithPredicates peerKey, final String peerId) {
final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> pb = Builders.mapEntryBuilder();
pb.withNodeIdentifier(peerKey);
pb.withChild(ImmutableNodes.leafNode(PEER_ID, peerId));
- pb.withChild(ImmutableNodes.leafNode(PEER_ROLE, this.role));
+ pb.withChild(ImmutableNodes.leafNode(PEER_ROLE, PeerRoleUtil.roleForString(this.role)));
+ if (this.simpleRoutingPolicy.isPresent() && this.role != PeerRole.Internal) {
+ pb.withChild(ImmutableNodes.leafNode(SIMPLE_ROUTING_POLICY_NID, simpleRoutingPolicyString(this.simpleRoutingPolicy.get())));
+ }
pb.withChild(ImmutableMapNodeBuilder.create().withNodeIdentifier(PEER_TABLES).build());
pb.withChild(EMPTY_ADJRIBIN);
- pb.withChild(EMPTY_EFFRIBIN);
- if (!isAppPeer) {
+ if(!isLearnNone(this.simpleRoutingPolicy)) {
+ pb.withChild(EMPTY_EFFRIBIN);
+ }
+ if (!isAnnounceNone(this.simpleRoutingPolicy)) {
pb.withChild(EMPTY_ADJRIBOUT);
}
return pb.build();
void markTableUptodate(final TablesKey tableTypes) {
final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
-
final TableContext ctx = this.tables.get(tableTypes);
tx.merge(LogicalDatastoreType.OPERATIONAL, ctx.getTableId().node(Attributes.QNAME).node(ATTRIBUTES_UPTODATE_TRUE.getNodeType()), ATTRIBUTES_UPTODATE_TRUE);
-
tx.submit();
}
tx.submit();
}
+ static boolean isAnnounceNone(final java.util.Optional<SimpleRoutingPolicy> peerStatus) {
+ return peerStatus.isPresent() && peerStatus.get() == SimpleRoutingPolicy.AnnounceNone;
+ }
+
+ static boolean isLearnNone(final java.util.Optional<SimpleRoutingPolicy> peerStatus) {
+ return peerStatus.isPresent() && peerStatus.get() == SimpleRoutingPolicy.LearnNone;
+ }
+
+ private static String simpleRoutingPolicyString(final SimpleRoutingPolicy simpleRoutingPolicy) {
+ switch (simpleRoutingPolicy) {
+ case AnnounceNone:
+ return "announce-none";
+ case LearnNone:
+ return "learn-none";
+ default:
+ throw new IllegalArgumentException("Unhandled Simple Routing Policy " + simpleRoutingPolicy);
+ }
+ }
}
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Optional;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.ApplicationRibId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.AdjRibIn;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
this.effectiveRibInWriter = EffectiveRibInWriter.create(targetRib.getService(), targetRib.createPeerChain(this), peerIId,
targetRib.getImportPolicyPeerTracker(), targetRib.getRibSupportContext(), PeerRole.Internal);
this.writerChain = targetRib.createPeerChain(this);
- this.writer = AdjRibInWriter.create(targetRib.getYangRibId(), PeerRole.Internal, this.writerChain);
+ this.writer = AdjRibInWriter.create(targetRib.getYangRibId(), PeerRole.Internal, Optional.of(SimpleRoutingPolicy.AnnounceNone), this.writerChain);
this.writer = this.writer.transform(RouterIds.createPeerId(ipAddress), targetRib.getRibSupportContext(), targetRib.getLocalTablesKeys(),
- Collections.emptyList(), true);
+ Collections.emptyList());
this.moduleTracker = moduleTracker;
if (moduleTracker != null) {
moduleTracker.onInstanceCreate();
*/
package org.opendaylight.protocol.bgp.rib.impl;
+import static org.opendaylight.protocol.bgp.rib.impl.AdjRibInWriter.isAnnounceNone;
+import static org.opendaylight.protocol.bgp.rib.impl.AdjRibInWriter.isLearnNone;
+
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.controller.config.yang.bgp.rib.impl.BGPPeerRuntimeMXBean;
import org.opendaylight.controller.config.yang.bgp.rib.impl.BGPPeerRuntimeRegistration;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.RouteRefresh;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamilies;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev160322.PeerContext;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.PeerKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
private final RpcProviderRegistry rpcRegistry;
private RoutedRpcRegistration<BgpPeerRpcService> rpcRegistration;
private final PeerRole peerRole;
+ private final Optional<SimpleRoutingPolicy> simpleRoutingPolicy;
- public BGPPeer(final String name, final RIB rib, final PeerRole role, final RpcProviderRegistry rpcRegistry) {
+ public BGPPeer(final String name, final RIB rib, final PeerRole role, final SimpleRoutingPolicy peerStatus, final RpcProviderRegistry rpcRegistry) {
this.peerRole = role;
+ this.simpleRoutingPolicy = Optional.ofNullable(peerStatus);
this.rib = Preconditions.checkNotNull(rib);
this.name = name;
this.chain = rib.createPeerChain(this);
- this.ribWriter = AdjRibInWriter.create(rib.getYangRibId(), role, this.chain);
+ this.ribWriter = AdjRibInWriter.create(rib.getYangRibId(), this.peerRole, this.simpleRoutingPolicy, this.chain);
this.rpcRegistry = rpcRegistry;
}
+ public BGPPeer(final String name, final RIB rib, final PeerRole role, final RpcProviderRegistry rpcRegistry) {
+ this(name, rib, role, null, rpcRegistry);
+ }
+
@Override
public synchronized void close() {
releaseConnection();
this.rawIdentifier = InetAddresses.forString(session.getBgpId().getValue()).getAddress();
final PeerId peerId = RouterIds.createPeerId(session.getBgpId());
- final YangInstanceIdentifier peerIId = this.rib.getYangRibId().node(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer.QNAME).node(IdentifierUtils.domPeerId(peerId));
- createAdjRibOutListener(peerId);
- this.effRibInWriter = EffectiveRibInWriter.create(this.rib.getService(), this.rib.createPeerChain(this), peerIId, ((RIBImpl)this.rib).getImportPolicyPeerTracker(),
- this.rib.getRibSupportContext(), this.peerRole);
- this.ribWriter = this.ribWriter.transform(peerId, this.rib.getRibSupportContext(), this.tables, addPathTablesType, false);
+
+ this.tables.addAll(this.session.getAdvertisedTableTypes().stream().map(t -> new TablesKey(t.getAfi(), t.getSafi())).collect(Collectors.toList()));
+ final boolean announceNone = isAnnounceNone(this.simpleRoutingPolicy);
+ if(!announceNone) {
+ createAdjRibOutListener(peerId);
+ }
+ addBgp4Support(peerId, announceNone);
+
+ if(!isLearnNone(this.simpleRoutingPolicy)) {
+ final YangInstanceIdentifier peerIId = this.rib.getYangRibId().node(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer.QNAME).node(IdentifierUtils.domPeerId(peerId));
+ this.effRibInWriter = EffectiveRibInWriter.create(this.rib.getService(), this.rib.createPeerChain(this), peerIId, ((RIBImpl) this.rib).getImportPolicyPeerTracker(),
+ this.rib.getRibSupportContext(), this.peerRole);
+ }
+ this.ribWriter = this.ribWriter.transform(peerId, this.rib.getRibSupportContext(), this.tables, addPathTablesType);
this.sessionEstablishedCounter++;
if (this.registrator != null) {
this.runtimeReg = this.registrator.register(this);
}
private void createAdjRibOutListener(final PeerId peerId) {
- for (final BgpTableType t : this.session.getAdvertisedTableTypes()) {
- final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
- if (this.tables.add(key)) {
- createAdjRibOutListener(peerId, key, true);
- }
- }
-
- addBgp4Support(peerId);
+ this.tables.forEach(key->createAdjRibOutListener(peerId, key, true));
}
//try to add a support for old-school BGP-4, if peer did not advertise IPv4-Unicast MP capability
- private void addBgp4Support(final PeerId peerId) {
+ private void addBgp4Support(final PeerId peerId, final boolean announceNone) {
final TablesKey key = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
- if (this.tables.add(key)) {
+ this.tables.add(key);
+ if (!announceNone) {
createAdjRibOutListener(peerId, key, false);
}
}
LOG.error("Transaction chain failed.", cause);
this.chain.close();
this.chain = this.rib.createPeerChain(this);
- this.ribWriter = AdjRibInWriter.create(this.rib.getYangRibId(), this.peerRole, this.chain);
+ this.ribWriter = AdjRibInWriter.create(this.rib.getYangRibId(), this.peerRole, this.simpleRoutingPolicy, this.chain);
releaseConnection();
}
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils;
import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-final class ExportPolicyPeerTrackerImpl extends AbstractPeerRoleTracker implements ExportPolicyPeerTracker {
+final class ExportPolicyPeerTrackerImpl implements ExportPolicyPeerTracker {
private static final Logger LOG = LoggerFactory.getLogger(ExportPolicyPeerTrackerImpl.class);
private static final Function<YangInstanceIdentifier, Entry<PeerId, YangInstanceIdentifier>> GENERATE_PEER_ID = new Function<YangInstanceIdentifier, Entry<PeerId, YangInstanceIdentifier>>() {
@Override
}
};
private static final QName SEND_RECEIVE = QName.create(SupportedTables.QNAME, "send-receive").intern();
- private static final NodeIdentifier SEND_RECEIVE_NID = new YangInstanceIdentifier.NodeIdentifier(SEND_RECEIVE);
+ private static final NodeIdentifier SEND_RECEIVE_NID = new NodeIdentifier(SEND_RECEIVE);
private final Map<YangInstanceIdentifier, PeerRole> peerRoles = new HashMap<>();
private final Set<PeerId> peerTables = Sets.newHashSet();
private final PolicyDatabase policyDatabase;
}
@Override
- protected void peerRoleChanged(final YangInstanceIdentifier peerPath, final PeerRole role) {
+ public void peerRoleChanged(@Nonnull final YangInstanceIdentifier peerPath, @Nullable final PeerRole role) {
/*
* This is a sledgehammer approach to the problem: modify the role map first,
* then construct the group map from scratch.
/**
* Tracks import policy corresponding to a particular peer.
*/
-final class ImportPolicyPeerTracker extends AbstractPeerRoleTracker {
+final class ImportPolicyPeerTracker {
private static final Logger LOG = LoggerFactory.getLogger(ImportPolicyPeerTracker.class);
private final Map<PeerId, AbstractImportPolicy> policies = new ConcurrentHashMap<>();
this.policyDatabase = Preconditions.checkNotNull(policyDatabase);
}
- @Override
+ /**
+ * Invoked whenever a peer role changes.
+ *
+ * @param peerPath Peer's path
+ * @param role Peer's new role, null indicates the peer has disappeared.
+ */
protected void peerRoleChanged(final YangInstanceIdentifier peerPath, final PeerRole role) {
final PeerId peer = IdentifierUtils.peerId((NodeIdentifierWithPredicates) peerPath.getLastPathArgument());
*/
package org.opendaylight.protocol.bgp.rib.impl;
+import static org.opendaylight.protocol.bgp.rib.impl.AdjRibInWriter.SIMPLE_ROUTING_POLICY_NID;
+import static org.opendaylight.protocol.bgp.rib.spi.PeerRoleUtil.PEER_ROLE_NID;
+
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedInteger;
import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils;
import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
+import org.opendaylight.protocol.bgp.rib.spi.PeerRoleUtil;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.EffectiveRibIn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.SupportedTables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
private static final LeafNode<Boolean> ATTRIBUTES_UPTODATE_TRUE = ImmutableNodes.leafNode(QName.create(Attributes.QNAME, "uptodate"), Boolean.TRUE);
private static final NodeIdentifier EFFRIBIN_NID = new NodeIdentifier(EffectiveRibIn.QNAME);
private static final NodeIdentifier TABLES_NID = new NodeIdentifier(Tables.QNAME);
+ private static final NodeIdentifier PEER_TABLES = new NodeIdentifier(SupportedTables.QNAME);
private final Map<PathArgument, RouteEntry> routeEntries = new HashMap<>();
private final YangInstanceIdentifier locRibTarget;
}
private void filterOutChangesToSupportedTables(final PeerId peerIdOfNewPeer, final DataTreeCandidateNode rootNode) {
- final DataTreeCandidateNode tablesChange = rootNode.getModifiedChild(AbstractPeerRoleTracker.PEER_TABLES);
+ final DataTreeCandidateNode tablesChange = rootNode.getModifiedChild(PEER_TABLES);
if (tablesChange != null) {
this.peerPolicyTracker.onTablesChanged(peerIdOfNewPeer, tablesChange);
}
}
private void filterOutPeerRole(final PeerId peerId, final DataTreeCandidateNode rootNode, final YangInstanceIdentifier rootPath) {
- final DataTreeCandidateNode roleChange = rootNode.getModifiedChild(AbstractPeerRoleTracker.PEER_ROLE_NID);
+ final DataTreeCandidateNode roleChange = rootNode.getModifiedChild(PEER_ROLE_NID);
if (roleChange != null) {
- if (!rootNode.getModificationType().equals(ModificationType.DELETE)) {
+ if (rootNode.getModificationType() != ModificationType.DELETE) {
this.cacheDisconnectedPeers.reconnected(peerId);
}
- this.peerPolicyTracker.onDataTreeChanged(roleChange, IdentifierUtils.peerPath(rootPath));
+
+ // Check for removal
+ final Optional<NormalizedNode<?, ?>> maybePeerRole = roleChange.getDataAfter();
+ final YangInstanceIdentifier peerPath = IdentifierUtils.peerPath(rootPath);
+ LOG.debug("Data Changed for Peer role {} path {}, dataBefore {}, dataAfter {}", roleChange.getIdentifier(),
+ peerPath , roleChange.getDataBefore(), maybePeerRole);
+ final PeerRole role = PeerRoleUtil.roleForChange(maybePeerRole);
+ SimpleRoutingPolicy srp = getSimpleRoutingPolicy(rootNode);
+ if(PeerRole.Internal == role || SimpleRoutingPolicy.AnnounceNone == srp) {
+ return;
+ }
+ this.peerPolicyTracker.peerRoleChanged(peerPath, role);
+ }
+ }
+
+ private SimpleRoutingPolicy getSimpleRoutingPolicy(final DataTreeCandidateNode rootNode) {
+ final DataTreeCandidateNode statusChange = rootNode.getModifiedChild(SIMPLE_ROUTING_POLICY_NID);
+ if (statusChange != null) {
+ final Optional<NormalizedNode<?, ?>> maybePeerStatus = statusChange.getDataAfter();
+ if (maybePeerStatus.isPresent()) {
+ return SimpleRoutingPolicy.valueOf(BindingMapping.getClassName((String) (maybePeerStatus.get()).getValue()));
+ }
}
+ return null;
}
private void updateNodes(final DataTreeCandidateNode table, final PeerId peerId, final DOMDataWriteTransaction tx,
default ibgp;
}
+ leaf simple-routing-policy {
+ type rib:simple-routing-policy;
+ }
+
leaf initiate-connection {
description "If true, connection will be initiated right away from current device.
If not, the peer will only be registered to peer registry and available for incomming bgp connections.";
package org.opendaylight.protocol.bgp.rib.impl;
import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.never;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.CheckedFuture;
import java.util.Collections;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Rib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.AdjRibIn;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.SupportedTables;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- this.writer = AdjRibInWriter.create(YangInstanceIdentifier.of(Rib.QNAME), PeerRole.Ebgp, this.chain);
- assertNotNull(this.writer);
Mockito.doReturn("MockedTrans").when(this.tx).toString();
Mockito.doReturn(this.tx).when(this.chain).newWriteOnlyTransaction();
Mockito.doReturn(Mockito.mock(CheckedFuture.class)).when(this.tx).submit();
- }
-
- @Test
- public void testTransform() {
- final YangInstanceIdentifier peerPath = YangInstanceIdentifier.builder().node(Rib.QNAME).node(Peer.QNAME).nodeWithKey(Peer.QNAME, AdjRibInWriter.PEER_ID_QNAME, this.peerIp).build();
Mockito.doNothing().when(this.tx).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.any(YangInstanceIdentifier.class), Mockito.any(NormalizedNode.class));
Mockito.doNothing().when(this.tx).merge(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.any(YangInstanceIdentifier.class), Mockito.any(NormalizedNode.class));
Mockito.doReturn(this.context).when(this.registry).getRIBSupportContext(Mockito.any(TablesKey.class));
Mockito.doNothing().when(this.context).createEmptyTableStructure(Mockito.eq(this.tx), Mockito.any(YangInstanceIdentifier.class));
+ }
- this.writer.transform(new PeerId(this.peerIp), this.registry, this.tableTypes, this.addPathTablesType, false);
-
- // verify peer skeleton was inserted correctly
- Mockito.verify(this.tx).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(peerPath), Mockito.eq(this.writer.peerSkeleton(IdentifierUtils.peerKey(peerPath), this.peerIp, false)));
+ @Test
+ public void testTransform() {
+ this.writer = AdjRibInWriter.create(YangInstanceIdentifier.of(Rib.QNAME), PeerRole.Ebgp, Optional.empty(), this.chain);
+ assertNotNull(this.writer);
+ final YangInstanceIdentifier peerPath = YangInstanceIdentifier.builder().node(Rib.QNAME).node(Peer.QNAME).nodeWithKey(Peer.QNAME,
+ AdjRibInWriter.PEER_ID_QNAME, this.peerIp).build();
+ this.writer.transform(new PeerId(this.peerIp), this.registry, this.tableTypes, this.addPathTablesType);
+ verifyPeerSkeletonInsertedCorrectly(peerPath);
// verify supported tables were inserted for ipv4
Mockito.verify(this.tx).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(peerPath.node(SupportedTables.QNAME).node(RibSupportUtils.toYangKey(SupportedTables.QNAME, k4))), Mockito.any(NormalizedNode.class));
- // verify uptodate set to false
- final YangInstanceIdentifier path = peerPath.node(AdjRibIn.QNAME).node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(k4)).node(Attributes.QNAME).node(AdjRibInWriter.ATTRIBUTES_UPTODATE_FALSE.getNodeType());
+ verifyUptodateSetToFalse(peerPath);
+ }
+
+ private void verifyUptodateSetToFalse(final YangInstanceIdentifier peerPath) {
+ final YangInstanceIdentifier path = peerPath.node(AdjRibIn.QNAME).node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(k4))
+ .node(Attributes.QNAME).node(AdjRibInWriter.ATTRIBUTES_UPTODATE_FALSE.getNodeType());
Mockito.verify(this.tx).merge(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(path), Mockito.eq(AdjRibInWriter.ATTRIBUTES_UPTODATE_FALSE));
}
+
+ private void verifyPeerSkeletonInsertedCorrectly(final YangInstanceIdentifier peerPath) {
+ Mockito.verify(this.tx).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(peerPath),
+ Mockito.eq(this.writer.peerSkeleton(IdentifierUtils.peerKey(peerPath), this.peerIp)));
+ }
+
+ @Test
+ public void testAnnounceNoneTransform() {
+ this.writer = AdjRibInWriter.create(YangInstanceIdentifier.of(Rib.QNAME), PeerRole.Ebgp, Optional.of(SimpleRoutingPolicy.AnnounceNone), this.chain);
+ assertNotNull(this.writer);
+ final YangInstanceIdentifier peerPath = YangInstanceIdentifier.builder().node(Rib.QNAME).node(Peer.QNAME).nodeWithKey(Peer.QNAME,
+ AdjRibInWriter.PEER_ID_QNAME, this.peerIp).build();
+ this.writer.transform(new PeerId(this.peerIp), this.registry, this.tableTypes, this.addPathTablesType);
+ verifyPeerSkeletonInsertedCorrectly(peerPath);
+ // verify supported tables were not inserted for ipv4, AnnounceNone
+ Mockito.verify(this.tx, never()).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(peerPath.node(SupportedTables.QNAME).node(RibSupportUtils.toYangKey(SupportedTables.QNAME, k4))), Mockito.any(NormalizedNode.class));
+ verifyUptodateSetToFalse(peerPath);
+
+ }
}
\ No newline at end of file
*/
package org.opendaylight.protocol.bgp.rib.impl;
+import static org.opendaylight.protocol.bgp.rib.spi.PeerRoleUtil.PEER_ROLE_NID;
+
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.CheckedFuture;
Mockito.doReturn(Lists.newArrayList(table)).when(tableChange).getChildNodes();
Mockito.doReturn("table change").when(tableChange).toString();
Mockito.doReturn(tableChange).when(node).getModifiedChild(YangInstanceIdentifier.of(SupportedTables.QNAME).getLastPathArgument());
- Mockito.doReturn(null).when(node).getModifiedChild(AbstractPeerRoleTracker.PEER_ROLE_NID);
+ Mockito.doReturn(null).when(node).getModifiedChild(PEER_ROLE_NID);
Mockito.doReturn(null).when(node).getModifiedChild(YangInstanceIdentifier.of(EffectiveRibIn.QNAME).getLastPathArgument());
Mockito.doReturn(node).when(candidate).getRootNode();
Mockito.doReturn(ModificationType.SUBTREE_MODIFIED).when(node).getModificationType();
package org.opendaylight.protocol.bgp.rib.spi;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
*/
PeerRole getRole(YangInstanceIdentifier peerId);
- /**
- * @param change data change
- * @param peerPath YII of peer
- */
- void onDataTreeChanged(DataTreeCandidateNode change, YangInstanceIdentifier peerPath);
-
/**
* Check whether Peer supports Add Path
* @param peerId
* @return true if add-path is supported
*/
boolean isAddPathSupportedByPeer(PeerId peerId);
+
+ /**
+ * Invoked whenever a peer role changes.
+ *
+ * @param peerPath Peer's path
+ * @param role Peer's new role, null indicates the peer has disappeared.
+ */
+ void peerRoleChanged(@Nonnull YangInstanceIdentifier peerPath, @Nullable PeerRole role);
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.rib.spi;
+
+import com.google.common.base.Optional;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+final public class PeerRoleUtil {
+ public static final NodeIdentifier PEER_ROLE_NID = new NodeIdentifier(QName.create(Peer.QNAME, "peer-role").intern());
+
+ private PeerRoleUtil() {
+ throw new UnsupportedOperationException();
+ }
+
+ public static PeerRole roleForChange(final Optional<NormalizedNode<?, ?>> maybePeerRole) {
+ if (maybePeerRole.isPresent()) {
+ final LeafNode<?> peerRoleLeaf = (LeafNode<?>) maybePeerRole.get();
+ return PeerRole.valueOf(BindingMapping.getClassName((String) peerRoleLeaf.getValue()));
+ }
+ return null;
+ }
+
+ public static String roleForString(final PeerRole role) {
+ switch (role) {
+ case Ebgp:
+ return "ebgp";
+ case Ibgp:
+ return "ibgp";
+ case RrClient:
+ return "rr-client";
+ case Internal:
+ return "internal";
+ default:
+ throw new IllegalArgumentException("Unhandled role " + role);
+ }
+ }
+}