f2f5b7005b6b1107d123ff7e821dc80329c12731
[bgpcep.git] / bgp / rib-impl / src / test / java / org / opendaylight / protocol / bgp / rib / impl / GracefulRestartTest.java
1 /*
2  * Copyright (c) 2018 AT&T Intellectual Property. 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;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
13 import static org.opendaylight.protocol.bgp.rib.impl.CheckUtil.checkIdleState;
14 import static org.opendaylight.protocol.bgp.rib.impl.CheckUtil.checkStateIsNotRestarting;
15 import static org.opendaylight.protocol.bgp.rib.impl.CheckUtil.checkUpState;
16 import static org.opendaylight.protocol.util.CheckUtil.checkReceivedMessages;
17 import static org.opendaylight.protocol.util.CheckUtil.readDataOperational;
18 import static org.opendaylight.protocol.util.CheckUtil.waitFutureSuccess;
19
20 import com.google.common.collect.ImmutableMap;
21 import io.netty.channel.Channel;
22 import io.netty.channel.ChannelFuture;
23 import java.net.InetSocketAddress;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Optional;
32 import java.util.Set;
33 import java.util.stream.Collectors;
34 import org.junit.After;
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.mockito.Mockito;
38 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
39 import org.opendaylight.protocol.bgp.mode.impl.add.all.paths.AllPathSelection;
40 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
41 import org.opendaylight.protocol.bgp.rib.impl.config.BgpPeer;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.bgp.rib.rib.loc.rib.tables.routes.Ipv4RoutesCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.bgp.rib.rib.loc.rib.tables.routes.Ipv6RoutesCase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.Open;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.OpenBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.ProtocolVersion;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.Update;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.open.message.BgpParameters;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlri;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.BgpRib;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerRole;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.RibId;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.Rib;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.RibKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.LocRib;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.BgpOrigin;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv6AddressFamily;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.UnicastSubsequentAddressFamily;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
70 import org.opendaylight.yangtools.yang.binding.Notification;
71 import org.opendaylight.yangtools.yang.common.Uint16;
72 import org.opendaylight.yangtools.yang.common.Uint8;
73
74 public class GracefulRestartTest extends AbstractAddPathTest {
75
76     private BGPSessionImpl session;
77     private BGPPeer peer;
78     private final Set<TablesKey> afiSafiAdvertised = new HashSet<>();
79     private final Set<TablesKey> gracefulAfiSafiAdvertised = new HashSet<>();
80     private RIBImpl ribImpl;
81     private Channel serverChannel;
82     private final SimpleSessionListener listener = new SimpleSessionListener();
83     private final BgpParameters parameters = createParameter(false, true, Collections.singletonMap(TABLES_KEY, true));
84     private static final int DEFERRAL_TIMER = 5;
85     private static final RibId RIBID = new RibId("test-rib");
86     private static final Ipv4Prefix PREFIX2 = new Ipv4Prefix("2.2.2.2/32");
87     private static final Ipv6Prefix PREFIX3 = new Ipv6Prefix("dead:beef::/64");
88     private static final Ipv6Address IPV6_NEXT_HOP = new Ipv6Address("dead:beef::1");
89     private static final TablesKey IPV6_TABLES_KEY = new TablesKey(Ipv6AddressFamily.class,
90             UnicastSubsequentAddressFamily.class);
91
92     private static final InstanceIdentifier<LocRib> LOC_RIB_IID = InstanceIdentifier.builder(BgpRib.class)
93             .child(Rib.class, new RibKey(RIBID))
94             .child(LocRib.class)
95             .build();
96     private static final InstanceIdentifier<Tables> IPV4_IID = LOC_RIB_IID.builder()
97             .child(Tables.class,TABLES_KEY)
98             .build();
99     private static final InstanceIdentifier<Tables> IPV6_IID = LOC_RIB_IID.builder()
100             .child(Tables.class, IPV6_TABLES_KEY)
101             .build();
102
103     @Override
104     @Before
105     public void setUp() throws Exception {
106         super.setUp();
107         final Map<TablesKey, PathSelectionMode> pathTables
108                 = ImmutableMap.of(TABLES_KEY, new AllPathSelection());
109         final ArrayList<BgpTableType> tableTypes = new ArrayList<>(TABLES_TYPE);
110         tableTypes.add(new BgpTableTypeImpl(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class));
111         this.ribImpl = new RIBImpl(this.tableRegistry, RIBID, AS_NUMBER, BGP_ID, this.ribExtension,
112                 this.serverDispatcher, this.codecsRegistry,
113                 getDomBroker(), getDataBroker(), this.policies, tableTypes, pathTables);
114
115         this.ribImpl.instantiateServiceInstance();
116         this.ribImpl.onGlobalContextUpdated(this.schemaService.getGlobalContext());
117         final ChannelFuture channelFuture = this.serverDispatcher.createServer(
118             new InetSocketAddress(RIB_ID, PORT.toJava()));
119         waitFutureSuccess(channelFuture);
120         this.serverChannel = channelFuture.channel();
121
122         gracefulAfiSafiAdvertised.add(TABLES_KEY);
123         afiSafiAdvertised.add(TABLES_KEY);
124         afiSafiAdvertised.add(IPV6_TABLES_KEY);
125         final BgpPeer bgpPeer = Mockito.mock(BgpPeer.class);
126         Mockito.doReturn(GRACEFUL_RESTART_TIME).when(bgpPeer).getGracefulRestartTimer();
127         Mockito.doReturn(Optional.empty()).when(bgpPeer).getErrorHandling();
128         Mockito.doReturn(createParameter(false, true, Collections.singletonMap(TABLES_KEY, false))
129                 .getOptionalCapabilities()).when(bgpPeer).getBgpFixedCapabilities();
130         this.peer = configurePeer(this.tableRegistry, PEER1, this.ribImpl, parameters, PeerRole.Ibgp,
131                 this.serverRegistry, afiSafiAdvertised, gracefulAfiSafiAdvertised, Collections.emptyMap(), bgpPeer);
132         this.session = createPeerSession(PEER1, parameters, this.listener);
133     }
134
135     @Override
136     @After
137     public void tearDown() throws Exception {
138         waitFutureSuccess(this.serverChannel.close());
139         this.session.close();
140         super.tearDown();
141     }
142
143     /**
144      * Test correct behavior when connection restart is unnoticed.
145      * "Correct" means that the previous TCP session MUST be closed, and the new one retained.
146      * Since the previous connection is considered to be terminated, no NOTIFICATION message should be sent.
147      */
148     @Test
149     public void resetConnectionOnOpenTest() {
150
151         checkReceivedMessages(this.listener, 2);
152         final Open open = createClassicOpen(true);
153         this.session.writeAndFlush(open);
154         checkIdleState(this.peer);
155         checkReceivedMessages(this.listener, 2);
156     }
157
158     /**
159      * Test that routes from peer that has advertised the Graceful Restart Capability MUST be retained
160      * for all the address families that were previously received in the Graceful Restart Capability.
161      *
162      * @throws Exception on reading Rib failure
163      */
164     @Test
165     public void retainRoutesOnPeerRestartTest() throws Exception {
166         final List<Ipv4Prefix> ipv4Prefixes = Arrays.asList(new Ipv4Prefix(PREFIX1), new Ipv4Prefix(PREFIX2));
167         final List<Ipv6Prefix> ipv6Prefixes = Collections.singletonList(new Ipv6Prefix(PREFIX3));
168         insertRoutes(ipv4Prefixes, ipv6Prefixes);
169         checkLocRibIpv4Routes(2);
170         checkLocRibIpv6Routes(1);
171
172         this.session.close();
173         checkIdleState(this.peer);
174         checkLocRibIpv4Routes(2);
175         checkLocRibIpv6Routes(0);
176     }
177
178     /**
179      * If the session does not get re-established within the "Restart Time"
180      * that the peer advertised previously, the Receiving Speaker MUST
181      * delete all the stale routes from the peer that it is retaining.
182      *
183      * @throws Exception on reading Rib failure
184      */
185     @Test
186     public void removeRoutesOnHoldTimeExpireTest() throws Exception {
187         retainRoutesOnPeerRestartTest();
188         checkStateIsNotRestarting(peer, GRACEFUL_RESTART_TIME);
189         checkLocRibIpv4Routes(0);
190         checkLocRibIpv6Routes(0);
191     }
192
193     /**
194      * Once the session is re-established, if the Graceful
195      * Restart Capability is not received in the re-established session at
196      * all, then the Receiving Speaker MUST immediately remove all the stale
197      * routes from the peer that it is retaining for that address family.
198      *
199      * @throws Exception on reading Rib failure
200      */
201     @Test
202     public void removeRoutesOnMissingGracefulRestartTest() throws Exception {
203         retainRoutesOnPeerRestartTest();
204         this.session = createPeerSession(PEER1, createParameter(false, true, null), this.listener);
205         checkUpState(listener);
206         checkLocRibIpv4Routes(0);
207         checkLocRibIpv6Routes(0);
208     }
209
210     /**
211      * Once the session is re-established, if a specific address family is not included
212      * in the newly received Graceful Restart Capability, then the Receiving Speaker
213      * MUST immediately remove all the stale routes from the peer that it is retaining
214      * for that address family.
215      *
216      *
217      * @throws Exception on reading Rib failure
218      */
219     @Test
220     public void removeRoutesOnMissingGracefulRestartAfiSafiTest() throws Exception {
221         retainRoutesOnPeerRestartTest();
222         this.session = createPeerSession(PEER1, createParameter(false, true,
223                 Collections.singletonMap(TABLES_KEY, false)), this.listener);
224         checkUpState(listener);
225         checkUpState(this.peer);
226         checkLocRibIpv4Routes(0);
227         checkLocRibIpv6Routes(0);
228     }
229
230     /**
231      * Once the End-of-RIB marker for an address family is received from the peer, it MUST
232      * immediately remove any routes from the peer that are still marked as stale for that
233      * address family.
234      *
235      * @throws Exception on reading Rib failure
236      */
237     @Test
238     public void removeStaleRoutesAfterRestartTest() throws Exception {
239         retainRoutesOnPeerRestartTest();
240         this.session = createPeerSession(PEER1, createParameter(false, true,
241                 Collections.singletonMap(TABLES_KEY, true)), this.listener);
242         checkUpState(this.listener);
243         final List<Ipv4Prefix> ipv4prefixes = Arrays.asList(new Ipv4Prefix(PREFIX1));
244         insertRoutes(ipv4prefixes, null);
245         insertRoutes(null, null);
246         checkLocRibIpv4Routes(1);
247         checkLocRibIpv6Routes(0);
248     }
249
250     /**
251      * Perform local graceful restart and verify routes are preserved.
252      *
253      * @throws Exception on reading Rib failure
254      */
255     @Test
256     public void performLocalGracefulRestart() throws Exception {
257         final List<Ipv4Prefix> ipv4prefixes = Arrays.asList(new Ipv4Prefix(PREFIX1), new Ipv4Prefix(PREFIX2));
258         final List<Ipv6Prefix> ipv6prefixes = Arrays.asList(new Ipv6Prefix(PREFIX3));
259         insertRoutes(ipv4prefixes, ipv6prefixes);
260         checkLocRibIpv4Routes(2);
261         checkLocRibIpv6Routes(1);
262
263         this.peer.restartGracefully(DEFERRAL_TIMER).get();
264         this.session = createPeerSession(PEER1, this.parameters, this.listener);
265         checkUpState(this.listener);
266         checkUpState(this.peer);
267         checkLocRibIpv4Routes(2);
268         checkLocRibIpv6Routes(0);
269     }
270
271     /**
272      * Wait with route selection until EOT is received.
273      *
274      * @throws Exception on reading Rib failure
275      */
276     @Test
277     public void waitForEORonLocalGracefulRestart() throws Exception {
278         performLocalGracefulRestart();
279         final List<Ipv4Prefix> ipv4prefixes = Arrays.asList(new Ipv4Prefix(PREFIX1));
280         final List<Ipv6Prefix> ipv6prefixes = Arrays.asList(new Ipv6Prefix(PREFIX3));
281         insertRoutes(ipv4prefixes, ipv6prefixes);
282         checkLocRibIpv4Routes(2);
283         checkLocRibIpv6Routes(0);
284         insertRoutes(null, null);
285         checkLocRibIpv4Routes(2);
286         checkLocRibIpv6Routes(1);
287     }
288
289     /**
290      * Wait with route selection until deferral time is expired.
291      *
292      * @throws Exception on reading Rib failure
293      */
294     @Test
295     public void waitForDeferralTimerOnLocalGracefulRestart() throws Exception {
296         performLocalGracefulRestart();
297         final List<Ipv4Prefix> ipv4prefixes = Arrays.asList(new Ipv4Prefix(PREFIX1));
298         final List<Ipv6Prefix> ipv6prefixes = Arrays.asList(new Ipv6Prefix(PREFIX3));
299         insertRoutes(ipv4prefixes, ipv6prefixes);
300         checkLocRibIpv4Routes(2);
301         checkLocRibIpv6Routes(0);
302         checkStateIsNotRestarting(this.peer, DEFERRAL_TIMER);
303         checkLocRibIpv4Routes(2);
304         checkLocRibIpv6Routes(1);
305     }
306
307     /**
308      * After graceful restart is performed from peer side we have to re-advertise routes followed by
309      * End-of-RIB marker.
310      *
311      * @throws Exception on reading Rib failure
312      */
313     @Test
314     public void verifySendEORafterRestartTest() throws Exception {
315         final SimpleSessionListener listener2 = new SimpleSessionListener();
316         configurePeer(this.tableRegistry, PEER2, this.ribImpl, this.parameters, PeerRole.Ebgp,
317                 this.serverRegistry, afiSafiAdvertised, gracefulAfiSafiAdvertised);
318         final BGPSessionImpl session2 = createPeerSession(PEER2, this.parameters, listener2);
319         final List<Ipv4Prefix> ipv4Prefixes = Arrays.asList(new Ipv4Prefix(PREFIX1));
320         final List<Ipv4Prefix> ipv4Prefixes2 = Arrays.asList(new Ipv4Prefix(PREFIX2));
321         final List<Ipv6Prefix> ipv6Prefixes = Collections.singletonList(new Ipv6Prefix(PREFIX3));
322         insertRoutes(ipv4Prefixes, ipv6Prefixes);
323         insertRoutes(ipv4Prefixes2, PEER2, null, null, session2, BgpOrigin.Egp);
324         checkLocRibIpv4Routes(2);
325         checkLocRibIpv6Routes(1);
326         org.opendaylight.protocol.util.CheckUtil.checkReceivedMessages(this.listener, 3);
327         // verify sending of Ipv4 EOT, Ipv6 EOT and Ipv4 update with route
328         checkReceivedMessages(this.listener, 3);
329         assertTrue(this.listener.getListMsg().get(0) instanceof Update);
330         assertTrue(BgpPeerUtil.isEndOfRib((Update)this.listener.getListMsg().get(0)));
331         assertTrue(this.listener.getListMsg().get(1) instanceof Update);
332         assertTrue(BgpPeerUtil.isEndOfRib((Update)this.listener.getListMsg().get(1)));
333         assertTrue(this.listener.getListMsg().get(2) instanceof Update);
334         assertFalse(BgpPeerUtil.isEndOfRib((Update)this.listener.getListMsg().get(2)));
335
336         this.session.close();
337         checkIdleState(this.peer);
338         checkLocRibIpv4Routes(2);
339         checkLocRibIpv6Routes(0);
340         // verify nothing new was sent
341         checkReceivedMessages(this.listener, 3);
342
343         this.session = createPeerSession(PEER1, createParameter(false, true,
344                 Collections.singletonMap(TABLES_KEY, true)), this.listener);
345         checkUpState(listener);
346         checkUpState(this.peer);
347         org.opendaylight.protocol.util.CheckUtil.checkReceivedMessages(this.listener, 6);
348         // verify sending of Ipv4 update with route, Ipv4 EOT and Ipv6 EOT; order can vary based on ODTC order
349         final List<Notification> subList = this.listener.getListMsg().subList(3, 6);
350         int eotCount = 0;
351         int routeUpdateCount = 0;
352         for (Notification message : subList) {
353             if (BgpPeerUtil.isEndOfRib((Update) message)) {
354                 eotCount++;
355             } else {
356                 routeUpdateCount++;
357             }
358         }
359         assertEquals(2, eotCount);
360         assertEquals(1, routeUpdateCount);
361     }
362
363     private void checkLocRibIpv4Routes(final int expectedRoutesOnDS) throws Exception {
364         readDataOperational(getDataBroker(), IPV4_IID, table -> {
365             int size = 0;
366             final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
367             if (routesCase != null && routesCase.getIpv4Routes() != null
368                     && routesCase.getIpv4Routes().getIpv4Route() != null) {
369                 size = routesCase.getIpv4Routes().getIpv4Route().size();
370             }
371             assertEquals(expectedRoutesOnDS, size);
372             return table;
373         });
374     }
375
376     private void checkLocRibIpv6Routes(final int expectedRoutesOnDS) throws Exception {
377         readDataOperational(getDataBroker(), IPV6_IID, table -> {
378             int size = 0;
379             final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
380             if (routesCase != null && routesCase.getIpv6Routes() != null
381                     && routesCase.getIpv6Routes().getIpv6Route() != null) {
382                 size = routesCase.getIpv6Routes().getIpv6Route().size();
383             }
384             assertEquals(expectedRoutesOnDS, size);
385             return table;
386         });
387     }
388
389     private void insertRoutes(final List<Ipv4Prefix> ipv4prefixes, final List<Ipv6Prefix> ipv6prefixes) {
390         insertRoutes(ipv4prefixes, PEER1, ipv6prefixes, IPV6_NEXT_HOP, this.session, BgpOrigin.Igp);
391     }
392
393     private static void insertRoutes(final List<Ipv4Prefix> ipv4prefixes, final Ipv4Address ipv4NeighborAddress,
394                               final List<Ipv6Prefix> ipv6prefixes, final Ipv6Address ipv6NeighborAddress,
395                               final BGPSessionImpl session, final BgpOrigin peerRole) {
396         if (ipv4prefixes == null && ipv6prefixes == null) {
397             waitFutureSuccess(session.writeAndFlush(BgpPeerUtil.createEndOfRib(TABLES_KEY)));
398             waitFutureSuccess(session.writeAndFlush(BgpPeerUtil.createEndOfRib(IPV6_TABLES_KEY)));
399             return;
400         }
401
402         if (ipv4prefixes != null && !ipv4prefixes.isEmpty()) {
403             final MpReachNlri reachIpv4 = PeerUtil.createMpReachNlri(new IpAddress(ipv4NeighborAddress),
404                     ipv4prefixes.stream()
405                             .map(IpPrefix::new)
406                             .collect(Collectors.toList()));
407             final Update update1 = PeerUtil.createUpdate(peerRole, Collections.emptyList(), 100, reachIpv4, null);
408             waitFutureSuccess(session.writeAndFlush(update1));
409         }
410
411         if (ipv6prefixes != null && !ipv4prefixes.isEmpty()) {
412             final MpReachNlri reachIpv6 = PeerUtil.createMpReachNlri(new IpAddress(ipv6NeighborAddress),
413                     ipv6prefixes.stream()
414                             .map(IpPrefix::new)
415                             .collect(Collectors.toList()));
416             final Update update2 = PeerUtil.createUpdate(peerRole, Collections.emptyList(), 100, reachIpv6, null);
417             waitFutureSuccess(session.writeAndFlush(update2));
418         }
419     }
420
421     private static Open createClassicOpen(final boolean addGraceful) {
422         final Map<TablesKey, Boolean> graceful = new HashMap<>();
423         if (addGraceful) {
424             graceful.put(new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class), true);
425         }
426         return new OpenBuilder()
427                 .setMyAsNumber(Uint16.valueOf(AS))
428                 .setHoldTimer(Uint16.valueOf(HOLDTIMER))
429                 .setVersion(new ProtocolVersion(Uint8.valueOf(4)))
430                 .setBgpParameters(Collections.singletonList(createParameter(false, true, graceful)))
431                 .setBgpIdentifier(PEER1)
432                 .build();
433     }
434 }