0a336103067326c09062c2923a086026cfc40ce2
[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 package org.opendaylight.protocol.bgp.rib.impl.config;
9
10 import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil.INSTANCE;
11
12 import com.google.common.collect.ImmutableList;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Optional;
19 import java.util.Set;
20 import java.util.stream.Collectors;
21 import org.eclipse.jdt.annotation.NonNull;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
24 import org.opendaylight.protocol.bgp.mode.impl.add.all.paths.AllPathSelection;
25 import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
26 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
27 import org.opendaylight.protocol.bgp.parser.spi.RevisedErrorHandlingSupport;
28 import org.opendaylight.protocol.bgp.parser.spi.pojo.RevisedErrorHandlingSupportImpl;
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.graceful.restart.GracefulRestart;
38 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ErrorHandling;
39 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflector;
40 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Timers;
41 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Transport;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.Config;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborKey;
45 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroup;
46 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
47 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
48 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
49 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.PeerType;
50 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.SendReceive;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.mp.capabilities.add.path.capability.AddressFamilies;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.mp.capabilities.add.path.capability.AddressFamiliesBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.GlobalAddPathsConfig;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.GlobalConfigAugmentation;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborAddPathsConfig;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborPeerGroupConfig;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTransportConfig;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.PeerGroupTransportConfig;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.TransportConfig;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerRole;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.ClusterIdentifier;
68 import org.opendaylight.yangtools.yang.binding.Augmentation;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
70 import org.opendaylight.yangtools.yang.common.Uint16;
71
72 final class OpenConfigMappingUtil {
73
74     static final String APPLICATION_PEER_GROUP_NAME = "application-peers";
75     static final Optional<String> APPLICATION_PEER_GROUP_NAME_OPT = Optional.of(APPLICATION_PEER_GROUP_NAME);
76     static final int HOLDTIMER = 90;
77     private static final AfiSafi IPV4_AFISAFI = new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build();
78     private static final List<AfiSafi> DEFAULT_AFISAFI = ImmutableList.of(IPV4_AFISAFI);
79     private static final int CONNECT_RETRY = 30;
80     private static final PortNumber PORT = new PortNumber(179);
81
82     private OpenConfigMappingUtil() {
83         throw new UnsupportedOperationException();
84     }
85
86     static String getRibInstanceName(final InstanceIdentifier<?> rootIdentifier) {
87         return rootIdentifier.firstKeyOf(Protocol.class).getName();
88     }
89
90     static KeyMapping getNeighborKey(final Neighbor neighbor) {
91         if (neighbor.getConfig() != null) {
92             final String authPassword = neighbor.getConfig().getAuthPassword();
93             if (authPassword != null) {
94                 return KeyMapping.getKeyMapping(INSTANCE.inetAddressFor(neighbor.getNeighborAddress()), authPassword);
95             }
96         }
97         return null;
98     }
99
100     static InstanceIdentifier<Neighbor> getNeighborInstanceIdentifier(
101             final InstanceIdentifier<Bgp> rootIdentifier,
102             final NeighborKey neighborKey) {
103         return rootIdentifier.child(Neighbors.class).child(Neighbor.class, neighborKey);
104     }
105
106     static String getNeighborInstanceName(final InstanceIdentifier<?> rootIdentifier) {
107         return Ipv4Util.toStringIP(rootIdentifier.firstKeyOf(Neighbor.class).getNeighborAddress());
108     }
109
110     //make sure IPv4 Unicast (RFC 4271) when required
111     static List<AfiSafi> getAfiSafiWithDefault(
112             final BgpCommonAfiSafiList afiSAfis, final boolean setDeafultIPv4) {
113         if (afiSAfis == null || afiSAfis.getAfiSafi() == null) {
114             return setDeafultIPv4 ? DEFAULT_AFISAFI : Collections.emptyList();
115         }
116         final List<AfiSafi> afiSafi = afiSAfis.getAfiSafi();
117         if (setDeafultIPv4) {
118             final boolean anyMatch = afiSafi.stream()
119                     .anyMatch(input -> input.getAfiSafiName().equals(IPV4UNICAST.class));
120             if (!anyMatch) {
121                 final List<AfiSafi> newAfiSafi = new ArrayList<>(afiSafi.size() + 1);
122                 newAfiSafi.addAll(afiSafi);
123                 newAfiSafi.add(IPV4_AFISAFI);
124                 return newAfiSafi;
125             }
126         }
127         return afiSafi;
128     }
129
130     static ClusterIdentifier getGlobalClusterIdentifier(final org.opendaylight.yang.gen.v1.http.openconfig.net
131             .yang.bgp.rev151009.bgp.global.base.Config globalConfig) {
132         final GlobalConfigAugmentation globalConfigAugmentation
133                 = globalConfig.augmentation(GlobalConfigAugmentation.class);
134         if (globalConfigAugmentation != null && globalConfigAugmentation.getRouteReflectorClusterId() != null) {
135             return new ClusterIdentifier(globalConfigAugmentation.getRouteReflectorClusterId().getIpv4Address());
136         }
137         return new ClusterIdentifier(globalConfig.getRouterId());
138     }
139
140     static @Nullable ClusterIdentifier getNeighborClusterIdentifier(
141             final @Nullable RouteReflector routeReflector, final @Nullable PeerGroup peerGroup) {
142         if (peerGroup != null) {
143             final ClusterIdentifier clusteriId = extractClusterId(peerGroup.getRouteReflector());
144             if (clusteriId != null) {
145                 return clusteriId;
146             }
147         }
148
149         return extractClusterId(routeReflector);
150     }
151
152     private static ClusterIdentifier extractClusterId(final RouteReflector routeReflector) {
153         if (routeReflector != null) {
154             final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.route
155                     .reflector.Config config = routeReflector.getConfig();
156             if (config != null && config.getRouteReflectorClusterId() != null) {
157                 return new ClusterIdentifier(config.getRouteReflectorClusterId().getIpv4Address());
158             }
159         }
160         return null;
161     }
162
163     static Map<BgpTableType, PathSelectionMode> toPathSelectionMode(final List<AfiSafi> afiSafis,
164             final BGPTableTypeRegistryConsumer tableTypeRegistry) {
165         final Map<BgpTableType, PathSelectionMode> pathSelectionModes = new HashMap<>();
166         for (final AfiSafi afiSafi : afiSafis) {
167             final BgpNeighborAddPathsConfig afiSafi2 = afiSafi.augmentation(GlobalAddPathsConfig.class);
168             if (afiSafi2 != null) {
169                 final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
170                 if (bgpTableType.isPresent()) {
171                     final short sendMax = afiSafi2.getSendMax().toJava();
172                     final PathSelectionMode selectionMode;
173                     if (sendMax > 1) {
174                         selectionMode = new AddPathBestNPathSelection(sendMax);
175                     } else {
176                         selectionMode = new AllPathSelection();
177                     }
178                     pathSelectionModes.put(bgpTableType.get(), selectionMode);
179                 }
180             }
181         }
182         return pathSelectionModes;
183     }
184
185     static boolean isApplicationPeer(final Neighbor neighbor) {
186         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group
187                 .Config config = neighbor.getConfig();
188         if (config != null) {
189             final NeighborPeerGroupConfig config1 = config.augmentation(NeighborPeerGroupConfig.class);
190             if (config1 != null) {
191                 final String peerGroup = config1.getPeerGroup();
192                 return peerGroup != null && peerGroup.equals(APPLICATION_PEER_GROUP_NAME);
193             }
194         }
195         return false;
196     }
197
198     static List<AddressFamilies> toAddPathCapability(final List<AfiSafi> afiSafis,
199             final BGPTableTypeRegistryConsumer tableTypeRegistry) {
200         final List<AddressFamilies> addPathCapability = new ArrayList<>();
201         for (final AfiSafi afiSafi : afiSafis) {
202             final BgpNeighborAddPathsConfig afiSafi1 = afiSafi.augmentation(NeighborAddPathsConfig.class);
203             final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
204             if (afiSafi1 != null && bgpTableType.isPresent()) {
205                 final AddressFamiliesBuilder builder = new AddressFamiliesBuilder(bgpTableType.get());
206                 builder.setSendReceive(toSendReceiveMode(afiSafi1));
207                 addPathCapability.add(builder.build());
208             }
209         }
210         return addPathCapability;
211     }
212
213     private static SendReceive toSendReceiveMode(final BgpNeighborAddPathsConfig addPath) {
214         if (addPath.isReceive() && addPath.getSendMax() != null) {
215             return SendReceive.Both;
216         }
217         if (addPath.getSendMax() != null) {
218             return SendReceive.Send;
219         }
220         return SendReceive.Receive;
221     }
222
223     private static boolean isRrClient(final BgpNeighborGroup neighbor) {
224         final RouteReflector routeReflector = neighbor.getRouteReflector();
225         if (routeReflector != null && routeReflector.getConfig() != null) {
226             return routeReflector.getConfig().isRouteReflectorClient();
227         }
228         return false;
229     }
230
231     static List<BgpTableType> toTableTypes(final List<AfiSafi> afiSafis,
232             final BGPTableTypeRegistryConsumer tableTypeRegistry) {
233         return afiSafis.stream()
234                 .map(afiSafi -> tableTypeRegistry.getTableType(afiSafi.getAfiSafiName()))
235                 .filter(Optional::isPresent)
236                 .map(Optional::get)
237                 .collect(Collectors.toList());
238     }
239
240     static Set<TablesKey> toTableKey(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer
241             tableTypeRegistry) {
242         return afiSafis.stream()
243                 .map(afiSafi -> tableTypeRegistry.getTableKey(afiSafi.getAfiSafiName()))
244                 .filter(Optional::isPresent)
245                 .map(Optional::get)
246                 .collect(Collectors.toSet());
247     }
248
249     static boolean isActive(final Neighbor neighbor, final PeerGroup peerGroup) {
250         Optional<Boolean> activeConnection = peerGroup == null ? Optional.empty() : isActive(peerGroup.getTransport());
251         if (!activeConnection.isPresent()) {
252             activeConnection = isActive(neighbor.getTransport());
253         }
254         return activeConnection.orElse(Boolean.TRUE);
255     }
256
257     private static Optional<Boolean> isActive(final Transport transport) {
258         if (transport != null) {
259             final Config config = transport.getConfig();
260             if (config != null) {
261                 final Boolean passive = config.isPassiveMode();
262                 if (passive != null) {
263                     return Optional.of(!passive);
264                 }
265             }
266         }
267         return Optional.empty();
268     }
269
270     static PeerRole toPeerRole(final BgpNeighborGroup neighbor) {
271         if (isRrClient(neighbor)) {
272             return PeerRole.RrClient;
273         }
274
275         if (neighbor.getConfig() != null) {
276             final PeerType peerType = neighbor.getConfig().getPeerType();
277             if (peerType == PeerType.EXTERNAL) {
278                 return PeerRole.Ebgp;
279             } else if (peerType == PeerType.INTERNAL) {
280                 return PeerRole.Ibgp;
281             }
282         }
283         return null;
284     }
285
286     static @NonNull PeerRole toPeerRole(final Neighbor neighbor, final PeerGroup peerGroup) {
287         PeerRole role = null;
288         if (peerGroup != null) {
289             role = toPeerRole(peerGroup);
290         }
291
292         if (role == null) {
293             role = toPeerRole(neighbor);
294         }
295
296         if (role == null) {
297             return PeerRole.Ibgp;
298         }
299         return role;
300     }
301
302     static int getHoldTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
303         Integer hold = null;
304         if (peerGroup != null) {
305             hold = getHoldTimer(peerGroup.getTimers());
306         }
307
308         if (hold == null) {
309             hold = getHoldTimer(neighbor.getTimers());
310         }
311
312         if (hold == null) {
313             return HOLDTIMER;
314         }
315
316         return hold;
317     }
318
319     private static @Nullable Integer getHoldTimer(final Timers timers) {
320         if (timers == null) {
321             return null;
322         }
323         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers
324                 .Config config = timers.getConfig();
325         if (config != null && config.getHoldTime() != null) {
326             return config.getHoldTime().intValue();
327         }
328         return null;
329     }
330
331     static int getGracefulRestartTimer(final Neighbor neighbor, final PeerGroup peerGroup, final int holdTimer) {
332         Uint16 timer = null;
333         if (peerGroup != null) {
334             timer = getGracefulRestartTimer(peerGroup.getGracefulRestart());
335         }
336
337         if (timer == null) {
338             timer = getGracefulRestartTimer(neighbor.getGracefulRestart());
339         }
340
341         /*
342          * RFC4724: "A suggested default for the Restart Time is a value less than or
343          * equal to the HOLDTIME carried in the OPEN."
344          */
345         return timer == null ? holdTimer : timer.toJava();
346     }
347
348     private static @Nullable Uint16 getGracefulRestartTimer(final GracefulRestart gracefulRestart) {
349         if (gracefulRestart != null) {
350             final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.graceful.restart.graceful
351                     .restart.Config config = gracefulRestart.getConfig();
352             if (config != null) {
353                 return config.getRestartTime();
354             }
355         }
356         return null;
357     }
358
359     static @NonNull AsNumber getRemotePeerAs(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009
360             .bgp.neighbor.group.Config config, final PeerGroup peerGroup, final AsNumber localAs) {
361         AsNumber neighborAs = null;
362         if (peerGroup != null) {
363             neighborAs = getRemotePeerAs(peerGroup.getConfig());
364         }
365
366         if (neighborAs == null) {
367             neighborAs = getRemotePeerAs(config);
368         }
369
370         if (neighborAs == null) {
371             return localAs;
372         }
373         return neighborAs;
374     }
375
376     private static AsNumber getRemotePeerAs(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
377             .rev151009.bgp.neighbor.group.@Nullable Config config) {
378         return config == null ? null : config.getPeerAs();
379     }
380
381     static @NonNull AsNumber getLocalPeerAs(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
382             .rev151009.bgp.neighbor.group.@Nullable Config config, final @NonNull AsNumber globalAs) {
383         if (config != null) {
384             final AsNumber peerAs = config.getLocalAs();
385             if (peerAs != null) {
386                 return peerAs;
387             }
388         }
389         return globalAs;
390     }
391
392     static int getRetryTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
393         Integer retryTimer = null;
394         if (peerGroup != null) {
395             retryTimer = getRetryTimer(peerGroup.getTimers());
396         }
397
398         if (retryTimer == null) {
399             retryTimer = getRetryTimer(neighbor.getTimers());
400         }
401
402         if (retryTimer == null) {
403             return CONNECT_RETRY;
404         }
405
406         return retryTimer;
407     }
408
409     private static @Nullable Integer getRetryTimer(final Timers timers) {
410         if (timers == null) {
411             return null;
412         }
413         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers
414                 .Config config = timers.getConfig();
415         if (config != null && config.getConnectRetry() != null) {
416             return config.getConnectRetry().intValue();
417         }
418         return null;
419     }
420
421     static @NonNull PortNumber getPort(final Neighbor neighbor, final PeerGroup peerGroup) {
422         PortNumber port = null;
423         if (peerGroup != null) {
424             port = getPort(peerGroup.getTransport(), PeerGroupTransportConfig.class);
425         }
426
427         if (port == null) {
428             port = getPort(neighbor.getTransport(), NeighborTransportConfig.class);
429         }
430
431         if (port == null) {
432             return PORT;
433         }
434
435         return port;
436     }
437
438     private static <T extends TransportConfig & Augmentation<Config>> @Nullable PortNumber getPort(
439             final @Nullable Transport transport, final Class<T> augment) {
440         if (transport != null) {
441             final Config config = transport.getConfig();
442             if (config != null) {
443                 final T peerTc = config.augmentation(augment);
444                 if (peerTc != null) {
445                     return peerTc.getRemotePort();
446                 }
447             }
448         }
449         return null;
450     }
451
452     static @Nullable IpAddress getLocalAddress(@Nullable final Transport transport) {
453         if (transport != null && transport.getConfig() != null) {
454             final BgpNeighborTransportConfig.LocalAddress localAddress = transport.getConfig().getLocalAddress();
455             if (localAddress != null) {
456                 return localAddress.getIpAddress();
457             }
458         }
459         return null;
460     }
461
462     static @Nullable RevisedErrorHandlingSupport getRevisedErrorHandling(final PeerRole role,final PeerGroup peerGroup,
463             final Neighbor neighbor) {
464         Optional<Boolean> enabled = getRevisedErrorHandling(neighbor);
465         if (!enabled.isPresent()) {
466             enabled = getRevisedErrorHandling(peerGroup);
467         }
468         if (!enabled.orElse(Boolean.FALSE)) {
469             return null;
470         }
471         switch (role) {
472             case Ebgp:
473                 return RevisedErrorHandlingSupportImpl.forExternalPeer();
474             case Ibgp:
475             case Internal:
476             case RrClient:
477                 return RevisedErrorHandlingSupportImpl.forInternalPeer();
478             default:
479                 throw new IllegalStateException("Unhandled role " + role);
480         }
481     }
482
483     private static Optional<Boolean> getRevisedErrorHandling(final BgpNeighborGroup group) {
484         if (group == null) {
485             return Optional.empty();
486         }
487         final ErrorHandling errorHandling = group.getErrorHandling();
488         if (errorHandling == null) {
489             return Optional.empty();
490         }
491         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.error.handling
492             .Config config = errorHandling.getConfig();
493         return config == null ? Optional.empty() : Optional.of(config.isTreatAsWithdraw());
494     }
495 }