2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.rib.impl.config;
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
12 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getAfiSafiWithDefault;
13 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getGlobalClusterIdentifier;
14 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.toTableTypes;
16 import com.google.common.util.concurrent.FluentFuture;
17 import com.google.common.util.concurrent.Futures;
18 import com.google.common.util.concurrent.ListenableFuture;
19 import java.util.Collection;
22 import java.util.stream.Collectors;
23 import org.checkerframework.checker.lock.qual.GuardedBy;
24 import org.opendaylight.mdsal.common.api.CommitInfo;
25 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
26 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
27 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
28 import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener;
29 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
30 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.BGPRibRoutingPolicyFactory;
31 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
32 import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
33 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
34 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
35 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
36 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
37 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
38 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
39 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
40 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRibState;
41 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRibStateProvider;
42 import org.opendaylight.protocol.bgp.rib.spi.state.BGPStateProviderRegistry;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config;
45 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.RibId;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.Rib;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.RibKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.BgpId;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.ClusterIdentifier;
58 import org.opendaylight.yangtools.concepts.Registration;
59 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
60 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
64 public final class RibImpl implements RIB, BGPRibStateProvider {
66 private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
68 private final RIBExtensionConsumerContext extensionProvider;
69 private final BGPDispatcher dispatcher;
70 private final CodecsRegistry codecsRegistry;
71 private final DOMDataBroker domBroker;
72 private final BGPRibRoutingPolicyFactory policyProvider;
73 private final BGPStateProviderRegistry stateProviderRegistry;
75 private RIBImpl ribImpl;
77 private Registration stateProviderRegistration;
79 private Collection<AfiSafi> afiSafi;
81 private AsNumber asNumber;
83 private Ipv4AddressNoZone routerId;
85 private ClusterIdentifier clusterId;
90 final RIBExtensionConsumerContext extensionProvider,
91 final BGPDispatcher dispatcher,
92 final BGPRibRoutingPolicyFactory policyProvider,
93 final CodecsRegistry codecsRegistry,
94 final BGPStateProviderRegistry stateProviderRegistry,
95 final DOMDataBroker domBroker) {
96 this.extensionProvider = requireNonNull(extensionProvider);
97 this.dispatcher = requireNonNull(dispatcher);
98 this.codecsRegistry = requireNonNull(codecsRegistry);
99 this.domBroker = requireNonNull(domBroker);
100 this.policyProvider = requireNonNull(policyProvider);
101 this.stateProviderRegistry = requireNonNull(stateProviderRegistry);
104 synchronized void start(final Global global, final String instanceName,
105 final BGPTableTypeRegistryConsumer tableTypeRegistry) {
106 checkState(ribImpl == null, "Previous instance %s was not closed.", this);
107 LOG.info("Starting BGP instance {}", instanceName);
108 ribId = new RibId(instanceName);
109 ribImpl = createRib(global, tableTypeRegistry);
110 stateProviderRegistration = stateProviderRegistry.register(this);
113 synchronized ListenableFuture<?> stop() {
114 if (ribImpl == null) {
115 LOG.info("RIB instance {} already closed, skipping", ribId);
116 return Futures.immediateVoidFuture();
119 LOG.info("Closing RIB instance {}", ribId);
120 if (stateProviderRegistration != null) {
121 LOG.info("Unregistering state provider for RIB instance {}", ribId);
122 stateProviderRegistration.close();
123 stateProviderRegistration = null;
126 final var future = ribImpl.closeServiceInstance();
131 synchronized boolean isGlobalEqual(final Global global) {
132 final Collection<AfiSafi> globalAfiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true).values();
133 final Config globalConfig = global.getConfig();
134 final AsNumber globalAs = globalConfig.getAs();
135 final Ipv4Address globalRouterId = global.getConfig().getRouterId();
136 final ClusterIdentifier globalClusterId = getGlobalClusterIdentifier(globalConfig);
137 return afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(afiSafi)
138 && globalAs.equals(asNumber)
139 && globalRouterId.getValue().equals(routerId.getValue())
140 && globalClusterId.getValue().equals(clusterId.getValue());
144 public synchronized KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
145 return ribImpl.getInstanceIdentifier();
149 public synchronized AsNumber getLocalAs() {
150 return ribImpl.getLocalAs();
154 public synchronized BgpId getBgpIdentifier() {
155 return ribImpl.getBgpIdentifier();
159 public synchronized Set<? extends BgpTableType> getLocalTables() {
160 return ribImpl.getLocalTables();
164 public synchronized BGPDispatcher getDispatcher() {
165 return ribImpl.getDispatcher();
169 public synchronized DOMTransactionChain createPeerDOMChain(final DOMTransactionChainListener listener) {
170 return ribImpl.createPeerDOMChain(listener);
174 public synchronized RIBExtensionConsumerContext getRibExtensions() {
175 return ribImpl.getRibExtensions();
179 public synchronized RIBSupportContextRegistry getRibSupportContext() {
180 return ribImpl.getRibSupportContext();
184 public synchronized YangInstanceIdentifier getYangRibId() {
185 return ribImpl.getYangRibId();
189 public synchronized CodecsRegistry getCodecsRegistry() {
190 return ribImpl.getCodecsRegistry();
194 public synchronized DOMDataTreeChangeService getService() {
195 return ribImpl.getService();
198 synchronized FluentFuture<? extends CommitInfo> closeServiceInstance() {
199 if (ribImpl != null) {
200 return ribImpl.closeServiceInstance();
202 return CommitInfo.emptyFluentFuture();
206 public synchronized Set<TablesKey> getLocalTablesKeys() {
207 return ribImpl.getLocalTablesKeys();
211 public synchronized boolean supportsTable(final TablesKey tableKey) {
212 return ribImpl.supportsTable(tableKey);
216 public synchronized BGPRibRoutingPolicy getRibPolicies() {
217 return ribImpl.getRibPolicies();
221 public synchronized BGPPeerTracker getPeerTracker() {
222 return ribImpl.getPeerTracker();
226 public synchronized String toString() {
227 return ribImpl != null ? ribImpl.toString() : "";
230 private synchronized RIBImpl createRib(
232 final BGPTableTypeRegistryConsumer tableTypeRegistry) {
233 afiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true).values();
234 final Config globalConfig = global.getConfig();
235 asNumber = globalConfig.getAs();
236 routerId = IetfInetUtil.ipv4AddressNoZoneFor(globalConfig.getRouterId());
237 clusterId = getGlobalClusterIdentifier(globalConfig);
238 final Map<TablesKey, PathSelectionMode> pathSelectionModes = OpenConfigMappingUtil
239 .toPathSelectionMode(afiSafi, tableTypeRegistry).entrySet()
241 .collect(Collectors.toMap(entry ->
242 new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
244 final BGPRibRoutingPolicy ribPolicy = policyProvider.buildBGPRibPolicy(asNumber.getValue().toJava(),
245 routerId, clusterId, RoutingPolicyUtil.getApplyPolicy(global.getApplyPolicy()));
257 toTableTypes(afiSafi, tableTypeRegistry),
262 public synchronized BGPRibState getRIBState() {
263 return ribImpl.getRIBState();
266 public synchronized void instantiateServiceInstance() {
267 if (ribImpl != null) {
268 ribImpl.instantiateServiceInstance();
273 public synchronized void refreshTable(final TablesKey tk, final PeerId peerId) {
274 ribImpl.refreshTable(tk, peerId);