010c6025e2551fb5d9fd8503dffa8daefca0a6d1
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / config / OpenConfigMappingUtil.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.protocol.bgp.rib.impl.config;
10
11 import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil.INSTANCE;
12
13 import com.google.common.collect.ImmutableList;
14 import com.google.common.primitives.Shorts;
15 import java.math.BigDecimal;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Optional;
22 import java.util.Set;
23 import java.util.function.BiFunction;
24 import java.util.stream.Collectors;
25 import javax.annotation.Nonnull;
26 import javax.annotation.Nullable;
27 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
28 import org.opendaylight.protocol.bgp.mode.impl.add.all.paths.AllPathSelection;
29 import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
30 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
31 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
32 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
33 import org.opendaylight.protocol.concepts.KeyMapping;
34 import org.opendaylight.protocol.util.Ipv4Util;
35 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.BgpCommonAfiSafiList;
36 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
37 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
38 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborAddPathsConfig;
39 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborGroup;
40 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.AfiSafisBuilder;
41 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.ConfigBuilder;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflector;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflectorBuilder;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Timers;
45 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TimersBuilder;
46 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Transport;
47 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TransportBuilder;
48 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.Config;
49 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
50 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborBuilder;
51 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborKey;
52 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroup;
53 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
54 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
55 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.GlobalBuilder;
56 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
57 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
58 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.CommunityType;
59 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
60 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.PeerType;
61 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.RrClusterIdType;
62 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
64 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.BgpTableType;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.SendReceive;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.mp.capabilities.add.path.capability.AddressFamilies;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.mp.capabilities.add.path.capability.AddressFamiliesBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi2;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config1;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config2;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config2Builder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.GlobalConfigAugmentation;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.GlobalConfigAugmentationBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.ApplicationRibId;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.RibId;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.rfc2385.cfg.rev160324.Rfc2385Key;
85 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
86
87 public final class OpenConfigMappingUtil {
88
89     static final String APPLICATION_PEER_GROUP_NAME = "application-peers";
90     private static final AfiSafi IPV4_AFISAFI = new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build();
91     private static final List<AfiSafi> DEFAULT_AFISAFI = ImmutableList.of(IPV4_AFISAFI);
92     static final int HOLDTIMER = 90;
93     private static final int CONNECT_RETRY = 30;
94     private static final PortNumber PORT = new PortNumber(179);
95     private static final BigDecimal DEFAULT_KEEP_ALIVE = BigDecimal.valueOf(30);
96     private static final BigDecimal DEFAULT_MINIMUM_ADV_INTERVAL = BigDecimal.valueOf(30);
97
98     private OpenConfigMappingUtil() {
99         throw new UnsupportedOperationException();
100     }
101
102     public static String getRibInstanceName(final InstanceIdentifier<?> rootIdentifier) {
103         return rootIdentifier.firstKeyOf(Protocol.class).getName();
104     }
105
106     @Nullable
107     private static Integer getHoldTimer(final Timers timers) {
108         if (timers == null) {
109             return null;
110         }
111         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers
112                 .Config config = timers.getConfig();
113         if (config != null && config.getHoldTime() != null) {
114             return config.getHoldTime().intValue();
115         }
116         return null;
117     }
118
119     @Nullable
120     private static AsNumber getPeerAs(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
121             .rev151009.bgp.neighbor.group.Config config) {
122         if (config != null) {
123             final AsNumber peerAs = config.getPeerAs();
124             if (peerAs != null) {
125                 return peerAs;
126             }
127         }
128         return null;
129     }
130
131     @Nullable
132     private static Boolean isActive(final Transport transport) {
133         if (transport != null) {
134             final Config config = transport.getConfig();
135             if (config != null && config.isPassiveMode() != null) {
136                 return !config.isPassiveMode();
137             }
138         }
139         return null;
140     }
141
142     @Nullable
143     private static Integer getRetryTimer(final Timers timers) {
144         if (timers == null) {
145             return null;
146         }
147         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers
148                 .Config config = timers.getConfig();
149         if (config != null && config.getConnectRetry() != null) {
150             return config.getConnectRetry().intValue();
151         }
152         return null;
153     }
154
155     public static KeyMapping getNeighborKey(final Neighbor neighbor) {
156         if (neighbor.getConfig() != null) {
157             final String authPassword = neighbor.getConfig().getAuthPassword();
158             if (authPassword != null) {
159                 return KeyMapping.getKeyMapping(INSTANCE.inetAddressFor(neighbor.getNeighborAddress()), authPassword);
160             }
161         }
162         return null;
163     }
164
165     public static InstanceIdentifier<Neighbor> getNeighborInstanceIdentifier(
166             final InstanceIdentifier<Bgp> rootIdentifier,
167         final NeighborKey neighborKey) {
168         return rootIdentifier.child(Neighbors.class).child(Neighbor.class, neighborKey);
169     }
170
171     public static String getNeighborInstanceName(final InstanceIdentifier<?> rootIdentifier) {
172         return Ipv4Util.toStringIP(rootIdentifier.firstKeyOf(Neighbor.class).getNeighborAddress());
173     }
174
175     @Nullable
176     private static PortNumber getPort(@Nonnull final BgpNeighborGroup neighbor) {
177         if (neighbor.getTransport() != null) {
178             final Config config = neighbor.getTransport().getConfig();
179             if (config != null && config.getAugmentation(Config1.class) != null) {
180                 final PortNumber remotePort = config.getAugmentation(Config1.class).getRemotePort();
181                 if (remotePort != null) {
182                     return remotePort;
183                 }
184             }
185         }
186         return null;
187     }
188
189     //make sure IPv4 Unicast (RFC 4271) when required
190     public static List<AfiSafi> getAfiSafiWithDefault(
191             final BgpCommonAfiSafiList afiSAfis, final boolean setDeafultIPv4) {
192         if (afiSAfis == null || afiSAfis.getAfiSafi() == null) {
193             return setDeafultIPv4 ? DEFAULT_AFISAFI : Collections.emptyList();
194         }
195         final List<AfiSafi> afiSafi = afiSAfis.getAfiSafi();
196         if (setDeafultIPv4) {
197             final boolean anyMatch = afiSafi.stream().anyMatch(input -> input.getAfiSafiName().equals(IPV4UNICAST.class));
198             if (!anyMatch) {
199                 afiSafi.add(IPV4_AFISAFI);
200             }
201         }
202         return afiSafi;
203     }
204
205     public static ClusterIdentifier getClusterIdentifier(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.Config globalConfig) {
206         final GlobalConfigAugmentation globalConfigAugmentation = globalConfig.getAugmentation(GlobalConfigAugmentation.class);
207         if (globalConfigAugmentation != null && globalConfigAugmentation.getRouteReflectorClusterId() != null) {
208             return new ClusterIdentifier(globalConfigAugmentation.getRouteReflectorClusterId().getIpv4Address());
209         }
210         return new ClusterIdentifier(globalConfig.getRouterId());
211     }
212
213     public static Map<BgpTableType, PathSelectionMode> toPathSelectionMode(final List<AfiSafi> afiSafis,
214             final BGPTableTypeRegistryConsumer tableTypeRegistry, final BGPPeerTracker peerTracker) {
215         final Map<BgpTableType, PathSelectionMode> pathSelectionModes = new HashMap<>();
216         for (final AfiSafi afiSafi : afiSafis) {
217             final BgpNeighborAddPathsConfig afiSafi2 = afiSafi.getAugmentation(AfiSafi2.class);
218             if (afiSafi2 != null) {
219                 final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
220                 if (bgpTableType.isPresent()) {
221                     final Short sendMax = afiSafi2.getSendMax();
222                     final PathSelectionMode selectionMode;
223                     if (sendMax > 1) {
224                         selectionMode = new AddPathBestNPathSelection(sendMax.longValue(), peerTracker);
225                     } else {
226                         selectionMode = new AllPathSelection(peerTracker);
227                     }
228                     pathSelectionModes.put(bgpTableType.get(), selectionMode);
229                 }
230             }
231         }
232         return pathSelectionModes;
233     }
234
235     public static boolean isApplicationPeer(final Neighbor neighbor) {
236         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Config config = neighbor.getConfig();
237         if (config != null) {
238             final Config2 config1 = config.getAugmentation(Config2.class);
239             if (config1 != null) {
240                 final String peerGroup = config1.getPeerGroup();
241                 return peerGroup != null && peerGroup.equals(APPLICATION_PEER_GROUP_NAME);
242             }
243         }
244         return false;
245     }
246
247     public static List<AddressFamilies> toAddPathCapability(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
248         final List<AddressFamilies> addPathCapability = new ArrayList<>();
249         for (final AfiSafi afiSafi : afiSafis) {
250             final BgpNeighborAddPathsConfig afiSafi1 = afiSafi.getAugmentation(AfiSafi1.class);
251             final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
252             if (afiSafi1 != null && bgpTableType.isPresent()) {
253                 final AddressFamiliesBuilder builder = new AddressFamiliesBuilder(bgpTableType.get());
254                 builder.setSendReceive(toSendReceiveMode(afiSafi1));
255                 addPathCapability.add(builder.build());
256             }
257         }
258         return addPathCapability;
259     }
260
261     private static SendReceive toSendReceiveMode(final BgpNeighborAddPathsConfig addPath) {
262         if (addPath.isReceive() && addPath.getSendMax() != null) {
263             return SendReceive.Both;
264         }
265         if (addPath.getSendMax() != null) {
266             return SendReceive.Send;
267         }
268         return SendReceive.Receive;
269     }
270
271     public static Global fromRib(final BgpId bgpId, final ClusterIdentifier clusterIdentifier, final RibId ribId,
272         final AsNumber localAs, final List<BgpTableType> localTables,
273         final Map<TablesKey, PathSelectionMode> pathSelectionStrategies, final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
274         return toGlobalConfiguration(bgpId, clusterIdentifier, localAs, localTables, pathSelectionStrategies, bgpTableTypeRegistryConsumer);
275     }
276
277     private static Global toGlobalConfiguration(final BgpId bgpId, final ClusterIdentifier clusterIdentifier,
278         final AsNumber localAs, final List<BgpTableType> localTables,
279         final Map<TablesKey, PathSelectionMode> pathSelectionStrategies, final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
280         final ConfigBuilder configBuilder = new ConfigBuilder();
281         configBuilder.setAs(localAs);
282         configBuilder.setRouterId(bgpId);
283         if (clusterIdentifier != null) {
284             configBuilder.addAugmentation(GlobalConfigAugmentation.class,
285                 new GlobalConfigAugmentationBuilder().setRouteReflectorClusterId(new RrClusterIdType(clusterIdentifier)).build());
286         }
287         return new GlobalBuilder().setAfiSafis(new AfiSafisBuilder().setAfiSafi(toAfiSafis(localTables,
288             (afiSafi, tableType) -> toGlobalAfiSafiAddPath(afiSafi, tableType, pathSelectionStrategies), bgpTableTypeRegistryConsumer)).build())
289             .setConfig(configBuilder.build()).build();
290     }
291
292     public static Neighbor fromBgpPeer(final List<AddressFamilies> addPathCapabilities,
293         final List<BgpTableType> advertisedTables, final Integer holdTimer, final IpAddress ipAddress,
294         final Boolean isActive, final Rfc2385Key password, final PortNumber portNumber, final Integer retryTimer,
295         final AsNumber remoteAs, final PeerRole peerRole, final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
296         final NeighborBuilder neighborBuilder = new NeighborBuilder();
297         neighborBuilder.setNeighborAddress(ipAddress);
298         neighborBuilder.setKey(new NeighborKey(ipAddress));
299         neighborBuilder.setAfiSafis(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafisBuilder().setAfiSafi(toAfiSafis(advertisedTables,
300             (afiSafi, tableType) -> toNeighborAfiSafiAddPath(afiSafi, tableType, addPathCapabilities), bgpTableTypeRegistryConsumer)).build());
301         neighborBuilder.setTransport(new TransportBuilder().setConfig(
302             new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.ConfigBuilder()
303                 .setPassiveMode(!isActive)
304                 .setMtuDiscovery(Boolean.FALSE)
305                 .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config1.class,
306                     new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.Config1Builder()
307                         .setRemotePort(portNumber).build())
308                 .build()).build());
309         neighborBuilder.setConfig(
310             new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ConfigBuilder()
311                 .setAuthPassword(password != null ? password.getValue() : null)
312                 .setPeerAs(remoteAs)
313                 .setPeerType(toPeerType(peerRole))
314                 .setSendCommunity(CommunityType.NONE)
315                 .setRouteFlapDamping(Boolean.FALSE)
316                 .build());
317         neighborBuilder.setTimers(new TimersBuilder().setConfig(
318             new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.ConfigBuilder()
319                 .setHoldTime(BigDecimal.valueOf(holdTimer))
320                 .setConnectRetry(BigDecimal.valueOf(retryTimer))
321                 .setKeepaliveInterval(DEFAULT_KEEP_ALIVE)
322                 .setMinimumAdvertisementInterval(DEFAULT_MINIMUM_ADV_INTERVAL)
323                 .build()).build());
324         neighborBuilder.setRouteReflector(new RouteReflectorBuilder().setConfig(
325             new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.route.reflector.ConfigBuilder()
326                 .setRouteReflectorClient(peerRole == PeerRole.RrClient).build()).build());
327         return neighborBuilder.build();
328     }
329
330
331     public static Neighbor fromApplicationPeer(final ApplicationRibId applicationRibId, final BgpId bgpId) {
332         final NeighborBuilder neighborBuilder = new NeighborBuilder();
333         neighborBuilder.setNeighborAddress(new IpAddress(new Ipv4Address(bgpId.getValue())));
334         neighborBuilder.setKey(new NeighborKey(neighborBuilder.getNeighborAddress()));
335         neighborBuilder.setConfig(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ConfigBuilder()
336             .setDescription(applicationRibId.getValue())
337             .addAugmentation(Config2.class, new Config2Builder().setPeerGroup(APPLICATION_PEER_GROUP_NAME).build())
338             .build());
339
340         return neighborBuilder.build();
341     }
342
343     public static PeerRole toPeerRole(final BgpNeighborGroup neighbor) {
344         if (isRrClient(neighbor)) {
345             return PeerRole.RrClient;
346         }
347
348         if (neighbor.getConfig() != null) {
349             final PeerType peerType = neighbor.getConfig().getPeerType();
350             if (peerType == PeerType.EXTERNAL) {
351                 return PeerRole.Ebgp;
352             } else if(peerType == PeerType.INTERNAL) {
353                 return PeerRole.Ibgp;
354             }
355         }
356         return null;
357     }
358
359     static PeerType toPeerType(final PeerRole peerRole) {
360         switch (peerRole) {
361         case Ibgp:
362         case RrClient:
363             return PeerType.INTERNAL;
364         case Ebgp:
365             return PeerType.EXTERNAL;
366         case Internal:
367             break;
368         default:
369             break;
370         }
371         return null;
372     }
373
374     private static boolean isRrClient(final BgpNeighborGroup neighbor) {
375         final RouteReflector routeReflector = neighbor.getRouteReflector();
376         if (routeReflector != null && routeReflector.getConfig() != null) {
377             return routeReflector.getConfig().isRouteReflectorClient();
378         }
379         return false;
380     }
381
382     static List<AfiSafi> toAfiSafis(final List<BgpTableType> advertizedTables, final BiFunction<AfiSafi, BgpTableType, AfiSafi> function,
383         final BGPTableTypeRegistryConsumer bgpTableTypeRegistryConsumer) {
384         final List<AfiSafi> afiSafis = new ArrayList<>(advertizedTables.size());
385         for (final BgpTableType tableType : advertizedTables) {
386             final Optional<AfiSafi> afiSafiMaybe = toAfiSafi(new BgpTableTypeImpl(tableType.getAfi(), tableType.getSafi()), bgpTableTypeRegistryConsumer);
387             if (afiSafiMaybe.isPresent()) {
388                 final AfiSafi afiSafi = function.apply(afiSafiMaybe.get(), tableType);
389                 afiSafis.add(afiSafi);
390             }
391         }
392         return afiSafis;
393     }
394
395     static AfiSafi toGlobalAfiSafiAddPath(final AfiSafi afiSafi, final BgpTableType tableType,
396         final Map<TablesKey, PathSelectionMode> multiPathTables) {
397         final PathSelectionMode pathSelection = multiPathTables.get(new TablesKey(tableType.getAfi(), tableType.getSafi()));
398         if (pathSelection == null) {
399             return afiSafi;
400         }
401         final long maxPaths;
402         if (pathSelection instanceof AddPathBestNPathSelection) {
403             maxPaths = ((AddPathBestNPathSelection) pathSelection).getNBestPaths();
404         } else {
405             maxPaths = 0L;
406         }
407         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi2 addPath = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi2Builder()
408             .setReceive(true)
409             .setSendMax(Shorts.checkedCast(maxPaths))
410             .build();
411         return new AfiSafiBuilder(afiSafi)
412             .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi2.class,
413                 addPath).build();
414     }
415
416     static AfiSafi toNeighborAfiSafiAddPath(final AfiSafi afiSafi, final BgpTableType tableType, final List<AddressFamilies> capabilities) {
417         final Optional<AddressFamilies> capability = capabilities.stream()
418             .filter(af -> af.getAfi().equals(tableType.getAfi()) && af.getSafi().equals(tableType.getSafi()))
419             .findFirst();
420         if (!capability.isPresent()) {
421             return afiSafi;
422         }
423         return new AfiSafiBuilder(afiSafi)
424             .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1.class,
425                 fromSendReceiveMode(capability.get().getSendReceive())).build();
426     }
427
428     private static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1 fromSendReceiveMode(final SendReceive mode) {
429         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1Builder builder =
430             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev171207.AfiSafi1Builder();
431         switch (mode) {
432         case Both:
433             builder.setReceive(true).setSendMax((short) 0);
434             break;
435         case Receive:
436             builder.setReceive(true);
437             break;
438         case Send:
439             builder.setReceive(false).setSendMax((short) 0);
440             break;
441         default:
442             break;
443         }
444         return builder.build();
445     }
446
447     public static Optional<AfiSafi> toAfiSafi(final BgpTableType tableType, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
448         final Optional<Class<? extends AfiSafiType>> afiSafi = tableTypeRegistry.getAfiSafiType(tableType);
449         if (afiSafi.isPresent()) {
450             return Optional.of(new AfiSafiBuilder().setAfiSafiName(afiSafi.get()).build());
451         }
452         return Optional.empty();
453     }
454
455     public static List<BgpTableType> toTableTypes(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer tableTypeRegistry) {
456         return afiSafis.stream()
457             .map(afiSafi -> tableTypeRegistry.getTableType(afiSafi.getAfiSafiName()))
458             .filter(Optional::isPresent)
459             .map(Optional::get)
460             .collect(Collectors.toList());
461     }
462
463     public static Set<TablesKey> toTableKey(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer
464         tableTypeRegistry) {
465         return afiSafis.stream()
466             .map(afiSafi -> tableTypeRegistry.getTableKey(afiSafi.getAfiSafiName()))
467             .filter(Optional::isPresent)
468             .map(Optional::get)
469             .collect(Collectors.toSet());
470     }
471
472     @Nonnull
473     public static boolean isActive(final Neighbor neighbor, final PeerGroup peerGroup) {
474         Boolean activeConnection = null;
475         if (peerGroup != null) {
476             activeConnection = isActive(peerGroup.getTransport());
477         }
478
479         if (activeConnection == null) {
480             activeConnection = isActive(neighbor.getTransport());
481         }
482         if (activeConnection == null) {
483             return true;
484         }
485         return activeConnection;
486     }
487
488     @Nonnull
489     public static PeerRole toPeerRole(final Neighbor neighbor, final PeerGroup peerGroup) {
490         PeerRole role = null;
491         if (peerGroup != null) {
492             role = toPeerRole(peerGroup);
493         }
494
495         if (role == null) {
496             role = toPeerRole(neighbor);
497         }
498
499         if (role == null) {
500             return PeerRole.Ibgp;
501         }
502         return role;
503     }
504
505     public static int getHoldTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
506         Integer hold = null;
507         if (peerGroup != null) {
508             hold = getHoldTimer(peerGroup.getTimers());
509         }
510
511         if (hold == null) {
512             hold = getHoldTimer(neighbor.getTimers());
513         }
514
515         if (hold == null) {
516             return HOLDTIMER;
517         }
518
519         return hold;
520     }
521
522     @Nonnull
523     public static AsNumber getPeerAs(final Neighbor neighbor, final PeerGroup peerGroup, final AsNumber localAs) {
524         AsNumber neighborAs = null;
525         if (peerGroup != null) {
526             neighborAs = getPeerAs(peerGroup.getConfig());
527         }
528
529         if (neighborAs == null) {
530             neighborAs = getPeerAs(neighbor.getConfig());
531         }
532
533         if (neighborAs == null) {
534             return localAs;
535         }
536         return neighborAs;
537     }
538
539     @Nonnull
540     public static int getRetryTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
541         Integer retryTimer = null;
542         if (peerGroup != null) {
543             retryTimer = getRetryTimer(peerGroup.getTimers());
544         }
545
546         if (retryTimer == null) {
547             retryTimer = getRetryTimer(neighbor.getTimers());
548         }
549
550         if (retryTimer == null) {
551             return CONNECT_RETRY;
552         }
553
554         return retryTimer;
555     }
556
557     @Nonnull
558     public static PortNumber getPort(final Neighbor neighbor, final PeerGroup peerGroup) {
559         PortNumber port = null;
560         if (peerGroup != null) {
561             port = getPort(peerGroup);
562         }
563
564         if (port == null) {
565             port = getPort(neighbor);
566         }
567
568         if (port == null) {
569             return PORT;
570         }
571
572         return port;
573     }
574 }