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
9 package org.opendaylight.protocol.bgp.rib.impl.config;
11 import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil.INSTANCE;
13 import com.google.common.collect.ImmutableList;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.List;
19 import java.util.Optional;
21 import java.util.stream.Collectors;
22 import javax.annotation.Nonnull;
23 import javax.annotation.Nullable;
24 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
25 import org.opendaylight.protocol.bgp.mode.impl.add.all.paths.AllPathSelection;
26 import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
27 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
28 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
29 import org.opendaylight.protocol.concepts.KeyMapping;
30 import org.opendaylight.protocol.util.Ipv4Util;
31 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.BgpCommonAfiSafiList;
32 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
33 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
34 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborAddPathsConfig;
35 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborGroup;
36 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborTransportConfig;
37 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflector;
38 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Timers;
39 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Transport;
40 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.Config;
41 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborKey;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroup;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
45 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
46 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
47 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.PeerType;
48 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.BgpTableType;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.SendReceive;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.mp.capabilities.add.path.capability.AddressFamilies;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.mp.capabilities.add.path.capability.AddressFamiliesBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180321.GlobalAddPathsConfig;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180321.GlobalConfigAugmentation;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180321.NeighborAddPathsConfig;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180321.NeighborClusterIdConfig;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180321.NeighborPeerGroupConfig;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180321.NeighborTransportConfig;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180321.PeerGroupTransportConfig;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180321.RouteReflectorClusterIdConfig;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
67 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
69 public final class OpenConfigMappingUtil {
71 static final String APPLICATION_PEER_GROUP_NAME = "application-peers";
72 static final int HOLDTIMER = 90;
73 private static final AfiSafi IPV4_AFISAFI = new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build();
74 private static final List<AfiSafi> DEFAULT_AFISAFI = ImmutableList.of(IPV4_AFISAFI);
75 private static final int CONNECT_RETRY = 30;
76 private static final PortNumber PORT = new PortNumber(179);
78 private OpenConfigMappingUtil() {
79 throw new UnsupportedOperationException();
82 public static String getRibInstanceName(final InstanceIdentifier<?> rootIdentifier) {
83 return rootIdentifier.firstKeyOf(Protocol.class).getName();
87 private static Integer getHoldTimer(final Timers timers) {
91 final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers
92 .Config config = timers.getConfig();
93 if (config != null && config.getHoldTime() != null) {
94 return config.getHoldTime().intValue();
100 private static AsNumber getRemotePeerAs(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
101 .rev151009.bgp.neighbor.group.Config config) {
102 if (config != null) {
103 final AsNumber peerAs = config.getPeerAs();
104 if (peerAs != null) {
112 private static Boolean isActive(final Transport transport) {
113 if (transport != null) {
114 final Config config = transport.getConfig();
115 if (config != null && config.isPassiveMode() != null) {
116 return !config.isPassiveMode();
123 private static Integer getRetryTimer(final Timers timers) {
124 if (timers == null) {
127 final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers
128 .Config config = timers.getConfig();
129 if (config != null && config.getConnectRetry() != null) {
130 return config.getConnectRetry().intValue();
135 public static KeyMapping getNeighborKey(final Neighbor neighbor) {
136 if (neighbor.getConfig() != null) {
137 final String authPassword = neighbor.getConfig().getAuthPassword();
138 if (authPassword != null) {
139 return KeyMapping.getKeyMapping(INSTANCE.inetAddressFor(neighbor.getNeighborAddress()), authPassword);
145 public static InstanceIdentifier<Neighbor> getNeighborInstanceIdentifier(
146 final InstanceIdentifier<Bgp> rootIdentifier,
147 final NeighborKey neighborKey) {
148 return rootIdentifier.child(Neighbors.class).child(Neighbor.class, neighborKey);
151 public static String getNeighborInstanceName(final InstanceIdentifier<?> rootIdentifier) {
152 return Ipv4Util.toStringIP(rootIdentifier.firstKeyOf(Neighbor.class).getNeighborAddress());
156 private static PortNumber getPort(@Nullable final Transport transport) {
157 if (transport != null) {
158 final Config config = transport.getConfig();
159 if (config != null) {
160 final NeighborTransportConfig peerTc = config.getAugmentation(NeighborTransportConfig.class);
161 if (peerTc != null) {
162 return peerTc.getRemotePort();
164 final PeerGroupTransportConfig peerGroupTc = config.getAugmentation(PeerGroupTransportConfig.class);
165 if (peerGroupTc != null) {
166 return peerGroupTc.getRemotePort();
173 //make sure IPv4 Unicast (RFC 4271) when required
174 public static List<AfiSafi> getAfiSafiWithDefault(
175 final BgpCommonAfiSafiList afiSAfis, final boolean setDeafultIPv4) {
176 if (afiSAfis == null || afiSAfis.getAfiSafi() == null) {
177 return setDeafultIPv4 ? DEFAULT_AFISAFI : Collections.emptyList();
179 final List<AfiSafi> afiSafi = afiSAfis.getAfiSafi();
180 if (setDeafultIPv4) {
181 final boolean anyMatch = afiSafi.stream()
182 .anyMatch(input -> input.getAfiSafiName().equals(IPV4UNICAST.class));
184 afiSafi.add(IPV4_AFISAFI);
190 public static ClusterIdentifier getGlobalClusterIdentifier(final org.opendaylight.yang.gen.v1.http.openconfig.net
191 .yang.bgp.rev151009.bgp.global.base.Config globalConfig) {
192 final RouteReflectorClusterIdConfig configAug
193 = globalConfig.getAugmentation(GlobalConfigAugmentation.class);
194 if (configAug != null && configAug.getRouteReflectorClusterId() != null) {
195 return new ClusterIdentifier(configAug.getRouteReflectorClusterId().getIpv4Address());
197 return new ClusterIdentifier(globalConfig.getRouterId());
201 public static ClusterIdentifier getNeighborClusterIdentifier(@Nullable final org.opendaylight.yang.gen.v1.http
202 .openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Config config) {
203 if (config != null) {
204 final RouteReflectorClusterIdConfig configAug = config.getAugmentation(NeighborClusterIdConfig.class);
205 if (configAug != null && configAug.getRouteReflectorClusterId() != null) {
206 return new ClusterIdentifier(configAug.getRouteReflectorClusterId().getIpv4Address());
212 public static Map<BgpTableType, PathSelectionMode> toPathSelectionMode(final List<AfiSafi> afiSafis,
213 final BGPTableTypeRegistryConsumer tableTypeRegistry, final BGPPeerTracker peerTracker) {
214 final Map<BgpTableType, PathSelectionMode> pathSelectionModes = new HashMap<>();
215 for (final AfiSafi afiSafi : afiSafis) {
216 final BgpNeighborAddPathsConfig afiSafi2 = afiSafi.getAugmentation(GlobalAddPathsConfig.class);
217 if (afiSafi2 != null) {
218 final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
219 if (bgpTableType.isPresent()) {
220 final Short sendMax = afiSafi2.getSendMax();
221 final PathSelectionMode selectionMode;
223 selectionMode = new AddPathBestNPathSelection(sendMax.longValue(), peerTracker);
225 selectionMode = new AllPathSelection(peerTracker);
227 pathSelectionModes.put(bgpTableType.get(), selectionMode);
231 return pathSelectionModes;
234 public static boolean isApplicationPeer(final Neighbor neighbor) {
235 final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group
236 .Config config = neighbor.getConfig();
237 if (config != null) {
238 final NeighborPeerGroupConfig config1 = config.getAugmentation(NeighborPeerGroupConfig.class);
239 if (config1 != null) {
240 final String peerGroup = config1.getPeerGroup();
241 return peerGroup != null && peerGroup.equals(APPLICATION_PEER_GROUP_NAME);
247 public static List<AddressFamilies> toAddPathCapability(final List<AfiSafi> afiSafis,
248 final BGPTableTypeRegistryConsumer tableTypeRegistry) {
249 final List<AddressFamilies> addPathCapability = new ArrayList<>();
250 for (final AfiSafi afiSafi : afiSafis) {
251 final BgpNeighborAddPathsConfig afiSafi1 = afiSafi.getAugmentation(NeighborAddPathsConfig.class);
252 final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
253 if (afiSafi1 != null && bgpTableType.isPresent()) {
254 final AddressFamiliesBuilder builder = new AddressFamiliesBuilder(bgpTableType.get());
255 builder.setSendReceive(toSendReceiveMode(afiSafi1));
256 addPathCapability.add(builder.build());
259 return addPathCapability;
262 private static SendReceive toSendReceiveMode(final BgpNeighborAddPathsConfig addPath) {
263 if (addPath.isReceive() && addPath.getSendMax() != null) {
264 return SendReceive.Both;
266 if (addPath.getSendMax() != null) {
267 return SendReceive.Send;
269 return SendReceive.Receive;
272 public static PeerRole toPeerRole(final BgpNeighborGroup neighbor) {
273 if (isRrClient(neighbor)) {
274 return PeerRole.RrClient;
277 if (neighbor.getConfig() != null) {
278 final PeerType peerType = neighbor.getConfig().getPeerType();
279 if (peerType == PeerType.EXTERNAL) {
280 return PeerRole.Ebgp;
281 } else if (peerType == PeerType.INTERNAL) {
282 return PeerRole.Ibgp;
288 private static boolean isRrClient(final BgpNeighborGroup neighbor) {
289 final RouteReflector routeReflector = neighbor.getRouteReflector();
290 if (routeReflector != null && routeReflector.getConfig() != null) {
291 return routeReflector.getConfig().isRouteReflectorClient();
296 public static List<BgpTableType> toTableTypes(final List<AfiSafi> afiSafis,
297 final BGPTableTypeRegistryConsumer tableTypeRegistry) {
298 return afiSafis.stream()
299 .map(afiSafi -> tableTypeRegistry.getTableType(afiSafi.getAfiSafiName()))
300 .filter(Optional::isPresent)
302 .collect(Collectors.toList());
305 public static Set<TablesKey> toTableKey(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer
307 return afiSafis.stream()
308 .map(afiSafi -> tableTypeRegistry.getTableKey(afiSafi.getAfiSafiName()))
309 .filter(Optional::isPresent)
311 .collect(Collectors.toSet());
315 public static boolean isActive(final Neighbor neighbor, final PeerGroup peerGroup) {
316 Boolean activeConnection = null;
317 if (peerGroup != null) {
318 activeConnection = isActive(peerGroup.getTransport());
321 if (activeConnection == null) {
322 activeConnection = isActive(neighbor.getTransport());
324 if (activeConnection == null) {
327 return activeConnection;
331 public static PeerRole toPeerRole(final Neighbor neighbor, final PeerGroup peerGroup) {
332 PeerRole role = null;
333 if (peerGroup != null) {
334 role = toPeerRole(peerGroup);
338 role = toPeerRole(neighbor);
342 return PeerRole.Ibgp;
347 public static int getHoldTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
349 if (peerGroup != null) {
350 hold = getHoldTimer(peerGroup.getTimers());
354 hold = getHoldTimer(neighbor.getTimers());
365 public static AsNumber getRemotePeerAs(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009
366 .bgp.neighbor.group.Config config, final PeerGroup peerGroup, final AsNumber localAs) {
367 AsNumber neighborAs = null;
368 if (peerGroup != null) {
369 neighborAs = getRemotePeerAs(peerGroup.getConfig());
372 if (neighborAs == null) {
373 neighborAs = getRemotePeerAs(config);
376 if (neighborAs == null) {
383 public static AsNumber getLocalPeerAs(@Nullable final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
384 .rev151009.bgp.neighbor.group.Config config, @Nonnull final AsNumber globalAs) {
385 if (config != null) {
386 final AsNumber peerAs = config.getLocalAs();
387 if (peerAs != null) {
394 public static int getRetryTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
395 Integer retryTimer = null;
396 if (peerGroup != null) {
397 retryTimer = getRetryTimer(peerGroup.getTimers());
400 if (retryTimer == null) {
401 retryTimer = getRetryTimer(neighbor.getTimers());
404 if (retryTimer == null) {
405 return CONNECT_RETRY;
412 public static PortNumber getPort(final Neighbor neighbor, final PeerGroup peerGroup) {
413 PortNumber port = null;
414 if (peerGroup != null) {
415 port = getPort(peerGroup.getTransport());
419 port = getPort(neighbor.getTransport());
430 public static IpAddress getLocalAddress(@Nullable final Transport transport) {
431 if (transport != null && transport.getConfig() != null) {
432 final BgpNeighborTransportConfig.LocalAddress localAddress = transport.getConfig().getLocalAddress();
433 if (localAddress != null ) {
434 return localAddress.getIpAddress();