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.DOMDataBroker.DataTreeChangeExtension;
27 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
28 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
29 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.BGPRibRoutingPolicyFactory;
30 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
31 import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
32 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
33 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
34 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
35 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
36 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
37 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
38 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
39 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRibState;
40 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRibStateProvider;
41 import org.opendaylight.protocol.bgp.rib.spi.state.BGPStateProviderRegistry;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.RibId;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.Rib;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.RibKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.BgpId;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.ClusterIdentifier;
57 import org.opendaylight.yangtools.concepts.Registration;
58 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
59 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
63 public final class RibImpl implements RIB, BGPRibStateProvider {
65 private static final Logger LOG = LoggerFactory.getLogger(RibImpl.class);
67 private final RIBExtensionConsumerContext extensionProvider;
68 private final BGPDispatcher dispatcher;
69 private final CodecsRegistry codecsRegistry;
70 private final DOMDataBroker domBroker;
71 private final BGPRibRoutingPolicyFactory policyProvider;
72 private final BGPStateProviderRegistry stateProviderRegistry;
74 private RIBImpl ribImpl;
76 private Registration stateProviderRegistration;
78 private Collection<AfiSafi> afiSafi;
80 private AsNumber asNumber;
82 private Ipv4AddressNoZone routerId;
84 private ClusterIdentifier clusterId;
89 final RIBExtensionConsumerContext extensionProvider,
90 final BGPDispatcher dispatcher,
91 final BGPRibRoutingPolicyFactory policyProvider,
92 final CodecsRegistry codecsRegistry,
93 final BGPStateProviderRegistry stateProviderRegistry,
94 final DOMDataBroker domBroker) {
95 this.extensionProvider = requireNonNull(extensionProvider);
96 this.dispatcher = requireNonNull(dispatcher);
97 this.codecsRegistry = requireNonNull(codecsRegistry);
98 this.domBroker = requireNonNull(domBroker);
99 this.policyProvider = requireNonNull(policyProvider);
100 this.stateProviderRegistry = requireNonNull(stateProviderRegistry);
103 synchronized void start(final Global global, final String instanceName,
104 final BGPTableTypeRegistryConsumer tableTypeRegistry) {
105 checkState(ribImpl == null, "Previous instance %s was not closed.", this);
106 LOG.info("Starting BGP instance {}", instanceName);
107 ribId = new RibId(instanceName);
108 ribImpl = createRib(global, tableTypeRegistry);
109 stateProviderRegistration = stateProviderRegistry.register(this);
112 synchronized ListenableFuture<?> stop() {
113 if (ribImpl == null) {
114 LOG.info("RIB instance {} already closed, skipping", ribId);
115 return Futures.immediateVoidFuture();
118 LOG.info("Closing RIB instance {}", ribId);
119 if (stateProviderRegistration != null) {
120 LOG.info("Unregistering state provider for RIB instance {}", ribId);
121 stateProviderRegistration.close();
122 stateProviderRegistration = null;
125 final var future = ribImpl.closeServiceInstance();
130 synchronized boolean isGlobalEqual(final Global global) {
131 final Collection<AfiSafi> globalAfiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true).values();
132 final Config globalConfig = global.getConfig();
133 final AsNumber globalAs = globalConfig.getAs();
134 final Ipv4Address globalRouterId = global.getConfig().getRouterId();
135 final ClusterIdentifier globalClusterId = getGlobalClusterIdentifier(globalConfig);
136 return afiSafi.containsAll(globalAfiSafi) && globalAfiSafi.containsAll(afiSafi)
137 && globalAs.equals(asNumber)
138 && globalRouterId.getValue().equals(routerId.getValue())
139 && globalClusterId.getValue().equals(clusterId.getValue());
143 public synchronized KeyedInstanceIdentifier<Rib, RibKey> getInstanceIdentifier() {
144 return ribImpl.getInstanceIdentifier();
148 public synchronized AsNumber getLocalAs() {
149 return ribImpl.getLocalAs();
153 public synchronized BgpId getBgpIdentifier() {
154 return ribImpl.getBgpIdentifier();
158 public synchronized Set<? extends BgpTableType> getLocalTables() {
159 return ribImpl.getLocalTables();
163 public synchronized BGPDispatcher getDispatcher() {
164 return ribImpl.getDispatcher();
168 public synchronized DOMTransactionChain createPeerDOMChain() {
169 return ribImpl.createPeerDOMChain();
173 public synchronized RIBExtensionConsumerContext getRibExtensions() {
174 return ribImpl.getRibExtensions();
178 public synchronized RIBSupportContextRegistry getRibSupportContext() {
179 return ribImpl.getRibSupportContext();
183 public synchronized YangInstanceIdentifier getYangRibId() {
184 return ribImpl.getYangRibId();
188 public synchronized CodecsRegistry getCodecsRegistry() {
189 return ribImpl.getCodecsRegistry();
193 public synchronized DataTreeChangeExtension getService() {
194 return ribImpl.getService();
197 synchronized FluentFuture<? extends CommitInfo> closeServiceInstance() {
198 if (ribImpl != null) {
199 return ribImpl.closeServiceInstance();
201 return CommitInfo.emptyFluentFuture();
205 public synchronized Set<TablesKey> getLocalTablesKeys() {
206 return ribImpl.getLocalTablesKeys();
210 public synchronized boolean supportsTable(final TablesKey tableKey) {
211 return ribImpl.supportsTable(tableKey);
215 public synchronized BGPRibRoutingPolicy getRibPolicies() {
216 return ribImpl.getRibPolicies();
220 public synchronized BGPPeerTracker getPeerTracker() {
221 return ribImpl.getPeerTracker();
225 public synchronized String toString() {
226 return ribImpl != null ? ribImpl.toString() : "";
229 private synchronized RIBImpl createRib(
231 final BGPTableTypeRegistryConsumer tableTypeRegistry) {
232 afiSafi = getAfiSafiWithDefault(global.getAfiSafis(), true).values();
233 final Config globalConfig = global.getConfig();
234 asNumber = globalConfig.getAs();
235 routerId = IetfInetUtil.ipv4AddressNoZoneFor(globalConfig.getRouterId());
236 clusterId = getGlobalClusterIdentifier(globalConfig);
237 final Map<TablesKey, PathSelectionMode> pathSelectionModes = OpenConfigMappingUtil
238 .toPathSelectionMode(afiSafi, tableTypeRegistry).entrySet()
240 .collect(Collectors.toMap(entry ->
241 new TablesKey(entry.getKey().getAfi(), entry.getKey().getSafi()), Map.Entry::getValue));
243 final BGPRibRoutingPolicy ribPolicy = policyProvider.buildBGPRibPolicy(asNumber.getValue().toJava(),
244 routerId, clusterId, RoutingPolicyUtil.getApplyPolicy(global.getApplyPolicy()));
256 toTableTypes(afiSafi, tableTypeRegistry),
261 public synchronized BGPRibState getRIBState() {
262 return ribImpl.getRIBState();
265 public synchronized void instantiateServiceInstance() {
266 if (ribImpl != null) {
267 ribImpl.instantiateServiceInstance();
272 public synchronized void refreshTable(final TablesKey tk, final PeerId peerId) {
273 ribImpl.refreshTable(tk, peerId);