]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_fsm.c
Merge pull request #12989 from opensourcerouting/fix/memory_leaks_bgpd
[mirror_frr.git] / bgpd / bgp_fsm.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP-4 Finite State Machine
3 * From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
4 * Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
5 */
6
7 #include <zebra.h>
8
9 #include "linklist.h"
10 #include "prefix.h"
11 #include "sockunion.h"
12 #include "thread.h"
13 #include "log.h"
14 #include "stream.h"
15 #include "ringbuf.h"
16 #include "memory.h"
17 #include "plist.h"
18 #include "workqueue.h"
19 #include "queue.h"
20 #include "filter.h"
21 #include "command.h"
22 #include "lib_errors.h"
23 #include "zclient.h"
24 #include "lib/json.h"
25 #include "bgpd/bgpd.h"
26 #include "bgpd/bgp_attr.h"
27 #include "bgpd/bgp_debug.h"
28 #include "bgpd/bgp_errors.h"
29 #include "bgpd/bgp_fsm.h"
30 #include "bgpd/bgp_packet.h"
31 #include "bgpd/bgp_network.h"
32 #include "bgpd/bgp_route.h"
33 #include "bgpd/bgp_dump.h"
34 #include "bgpd/bgp_open.h"
35 #include "bgpd/bgp_advertise.h"
36 #include "bgpd/bgp_community.h"
37 #include "bgpd/bgp_updgrp.h"
38 #include "bgpd/bgp_nht.h"
39 #include "bgpd/bgp_bfd.h"
40 #include "bgpd/bgp_memory.h"
41 #include "bgpd/bgp_keepalives.h"
42 #include "bgpd/bgp_io.h"
43 #include "bgpd/bgp_zebra.h"
44 #include "bgpd/bgp_vty.h"
45
46 DEFINE_HOOK(peer_backward_transition, (struct peer * peer), (peer));
47 DEFINE_HOOK(peer_status_changed, (struct peer * peer), (peer));
48
49 enum bgp_fsm_state_progress {
50 BGP_FSM_FAILURE_AND_DELETE = -2,
51 BGP_FSM_FAILURE = -1,
52 BGP_FSM_SUCCESS = 0,
53 BGP_FSM_SUCCESS_STATE_TRANSFER = 1,
54 };
55
56 /* Definition of display strings corresponding to FSM events. This should be
57 * kept consistent with the events defined in bgpd.h
58 */
59 static const char *const bgp_event_str[] = {
60 NULL,
61 "BGP_Start",
62 "BGP_Stop",
63 "TCP_connection_open",
64 "TCP_connection_open_w_delay",
65 "TCP_connection_closed",
66 "TCP_connection_open_failed",
67 "TCP_fatal_error",
68 "ConnectRetry_timer_expired",
69 "Hold_Timer_expired",
70 "KeepAlive_timer_expired",
71 "DelayOpen_timer_expired",
72 "Receive_OPEN_message",
73 "Receive_KEEPALIVE_message",
74 "Receive_UPDATE_message",
75 "Receive_NOTIFICATION_message",
76 "Clearing_Completed",
77 };
78
79 /* BGP FSM (finite state machine) has three types of functions. Type
80 one is thread functions. Type two is event functions. Type three
81 is FSM functions. Timer functions are set by bgp_timer_set
82 function. */
83
84 /* BGP event function. */
85 void bgp_event(struct thread *);
86
87 /* BGP thread functions. */
88 static void bgp_start_timer(struct thread *);
89 static void bgp_connect_timer(struct thread *);
90 static void bgp_holdtime_timer(struct thread *);
91 static void bgp_delayopen_timer(struct thread *);
92
93 /* BGP FSM functions. */
94 static enum bgp_fsm_state_progress bgp_start(struct peer *);
95
96 /* Register peer with NHT */
97 int bgp_peer_reg_with_nht(struct peer *peer)
98 {
99 int connected = 0;
100
101 if (peer->sort == BGP_PEER_EBGP && peer->ttl == BGP_DEFAULT_TTL
102 && !CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
103 && !CHECK_FLAG(peer->bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
104 connected = 1;
105
106 return bgp_find_or_add_nexthop(
107 peer->bgp, peer->bgp, family2afi(peer->su.sa.sa_family),
108 SAFI_UNICAST, NULL, peer, connected, NULL);
109 }
110
111 static void peer_xfer_stats(struct peer *peer_dst, struct peer *peer_src)
112 {
113 /* Copy stats over. These are only the pre-established state stats */
114 peer_dst->open_in += peer_src->open_in;
115 peer_dst->open_out += peer_src->open_out;
116 peer_dst->keepalive_in += peer_src->keepalive_in;
117 peer_dst->keepalive_out += peer_src->keepalive_out;
118 peer_dst->notify_in += peer_src->notify_in;
119 peer_dst->notify_out += peer_src->notify_out;
120 peer_dst->dynamic_cap_in += peer_src->dynamic_cap_in;
121 peer_dst->dynamic_cap_out += peer_src->dynamic_cap_out;
122 }
123
124 static struct peer *peer_xfer_conn(struct peer *from_peer)
125 {
126 struct peer *peer;
127 afi_t afi;
128 safi_t safi;
129 int fd;
130 enum bgp_fsm_status status, pstatus;
131 enum bgp_fsm_events last_evt, last_maj_evt;
132
133 assert(from_peer != NULL);
134
135 peer = from_peer->doppelganger;
136
137 if (!peer || !CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
138 return from_peer;
139
140 /*
141 * Let's check that we are not going to loose known configuration
142 * state based upon doppelganger rules.
143 */
144 FOREACH_AFI_SAFI (afi, safi) {
145 if (from_peer->afc[afi][safi] != peer->afc[afi][safi]) {
146 flog_err(
147 EC_BGP_DOPPELGANGER_CONFIG,
148 "from_peer->afc[%d][%d] is not the same as what we are overwriting",
149 afi, safi);
150 return NULL;
151 }
152 }
153
154 if (bgp_debug_neighbor_events(peer))
155 zlog_debug("%s: peer transfer %p fd %d -> %p fd %d)",
156 from_peer->host, from_peer, from_peer->fd, peer,
157 peer->fd);
158
159 bgp_writes_off(peer);
160 bgp_reads_off(peer);
161 bgp_writes_off(from_peer);
162 bgp_reads_off(from_peer);
163
164 /*
165 * Before exchanging FD remove doppelganger from
166 * keepalive peer hash. It could be possible conf peer
167 * fd is set to -1. If blocked on lock then keepalive
168 * thread can access peer pointer with fd -1.
169 */
170 bgp_keepalives_off(from_peer);
171
172 THREAD_OFF(peer->t_routeadv);
173 THREAD_OFF(peer->t_connect);
174 THREAD_OFF(peer->t_delayopen);
175 THREAD_OFF(peer->t_connect_check_r);
176 THREAD_OFF(peer->t_connect_check_w);
177 THREAD_OFF(from_peer->t_routeadv);
178 THREAD_OFF(from_peer->t_connect);
179 THREAD_OFF(from_peer->t_delayopen);
180 THREAD_OFF(from_peer->t_connect_check_r);
181 THREAD_OFF(from_peer->t_connect_check_w);
182 THREAD_OFF(from_peer->t_process_packet);
183
184 /*
185 * At this point in time, it is possible that there are packets pending
186 * on various buffers. Those need to be transferred or dropped,
187 * otherwise we'll get spurious failures during session establishment.
188 */
189 frr_with_mutex (&peer->io_mtx, &from_peer->io_mtx) {
190 fd = peer->fd;
191 peer->fd = from_peer->fd;
192 from_peer->fd = fd;
193
194 stream_fifo_clean(peer->ibuf);
195 stream_fifo_clean(peer->obuf);
196
197 /*
198 * this should never happen, since bgp_process_packet() is the
199 * only task that sets and unsets the current packet and it
200 * runs in our pthread.
201 */
202 if (peer->curr) {
203 flog_err(
204 EC_BGP_PKT_PROCESS,
205 "[%s] Dropping pending packet on connection transfer:",
206 peer->host);
207 /* there used to be a bgp_packet_dump call here, but
208 * that's extremely confusing since there's no way to
209 * identify the packet in MRT dumps or BMP as dropped
210 * due to connection transfer.
211 */
212 stream_free(peer->curr);
213 peer->curr = NULL;
214 }
215
216 // copy each packet from old peer's output queue to new peer
217 while (from_peer->obuf->head)
218 stream_fifo_push(peer->obuf,
219 stream_fifo_pop(from_peer->obuf));
220
221 // copy each packet from old peer's input queue to new peer
222 while (from_peer->ibuf->head)
223 stream_fifo_push(peer->ibuf,
224 stream_fifo_pop(from_peer->ibuf));
225
226 ringbuf_wipe(peer->ibuf_work);
227 ringbuf_copy(peer->ibuf_work, from_peer->ibuf_work,
228 ringbuf_remain(from_peer->ibuf_work));
229 }
230
231 peer->as = from_peer->as;
232 peer->v_holdtime = from_peer->v_holdtime;
233 peer->v_keepalive = from_peer->v_keepalive;
234 peer->v_routeadv = from_peer->v_routeadv;
235 peer->v_delayopen = from_peer->v_delayopen;
236 peer->v_gr_restart = from_peer->v_gr_restart;
237 peer->cap = from_peer->cap;
238 peer->remote_role = from_peer->remote_role;
239 status = peer->status;
240 pstatus = peer->ostatus;
241 last_evt = peer->last_event;
242 last_maj_evt = peer->last_major_event;
243 peer->status = from_peer->status;
244 peer->ostatus = from_peer->ostatus;
245 peer->last_event = from_peer->last_event;
246 peer->last_major_event = from_peer->last_major_event;
247 from_peer->status = status;
248 from_peer->ostatus = pstatus;
249 from_peer->last_event = last_evt;
250 from_peer->last_major_event = last_maj_evt;
251 peer->remote_id = from_peer->remote_id;
252 peer->last_reset = from_peer->last_reset;
253 peer->max_packet_size = from_peer->max_packet_size;
254
255 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
256 peer->bgp->peer);
257
258 if (bgp_peer_gr_mode_get(peer) == PEER_DISABLE) {
259
260 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
261
262 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
263 peer_nsf_stop(peer);
264 }
265 }
266
267 if (peer->hostname) {
268 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
269 peer->hostname = NULL;
270 }
271 if (from_peer->hostname != NULL) {
272 peer->hostname = from_peer->hostname;
273 from_peer->hostname = NULL;
274 }
275
276 if (peer->domainname) {
277 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
278 peer->domainname = NULL;
279 }
280 if (from_peer->domainname != NULL) {
281 peer->domainname = from_peer->domainname;
282 from_peer->domainname = NULL;
283 }
284
285 if (peer->soft_version) {
286 XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version);
287 peer->soft_version = NULL;
288 }
289 if (from_peer->soft_version) {
290 peer->soft_version = from_peer->soft_version;
291 from_peer->soft_version = NULL;
292 }
293
294 FOREACH_AFI_SAFI (afi, safi) {
295 peer->af_sflags[afi][safi] = from_peer->af_sflags[afi][safi];
296 peer->af_cap[afi][safi] = from_peer->af_cap[afi][safi];
297 peer->afc_nego[afi][safi] = from_peer->afc_nego[afi][safi];
298 peer->afc_adv[afi][safi] = from_peer->afc_adv[afi][safi];
299 peer->afc_recv[afi][safi] = from_peer->afc_recv[afi][safi];
300 peer->orf_plist[afi][safi] = from_peer->orf_plist[afi][safi];
301 peer->llgr[afi][safi] = from_peer->llgr[afi][safi];
302 }
303
304 if (bgp_getsockname(peer) < 0) {
305 flog_err(
306 EC_LIB_SOCKET,
307 "%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
308 (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)
309 ? "accept"
310 : ""),
311 peer->host, peer->fd, from_peer->fd);
312 BGP_EVENT_ADD(peer, BGP_Stop);
313 BGP_EVENT_ADD(from_peer, BGP_Stop);
314 return NULL;
315 }
316 if (from_peer->status > Active) {
317 if (bgp_getsockname(from_peer) < 0) {
318 flog_err(
319 EC_LIB_SOCKET,
320 "%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
321
322 (CHECK_FLAG(from_peer->sflags,
323 PEER_STATUS_ACCEPT_PEER)
324 ? "accept"
325 : ""),
326 from_peer->host, from_peer->fd, peer->fd);
327 bgp_stop(from_peer);
328 from_peer = NULL;
329 }
330 }
331
332
333 // Note: peer_xfer_stats() must be called with I/O turned OFF
334 if (from_peer)
335 peer_xfer_stats(peer, from_peer);
336
337 /* Register peer for NHT. This is to allow RAs to be enabled when
338 * needed, even on a passive connection.
339 */
340 bgp_peer_reg_with_nht(peer);
341 if (from_peer)
342 bgp_replace_nexthop_by_peer(from_peer, peer);
343
344 bgp_reads_on(peer);
345 bgp_writes_on(peer);
346 thread_add_event(bm->master, bgp_process_packet, peer, 0,
347 &peer->t_process_packet);
348
349 return (peer);
350 }
351
352 /* Hook function called after bgp event is occered. And vty's
353 neighbor command invoke this function after making neighbor
354 structure. */
355 void bgp_timer_set(struct peer *peer)
356 {
357 afi_t afi;
358 safi_t safi;
359
360 switch (peer->status) {
361 case Idle:
362 /* First entry point of peer's finite state machine. In Idle
363 status start timer is on unless peer is shutdown or peer is
364 inactive. All other timer must be turned off */
365 if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(peer)
366 || peer->bgp->vrf_id == VRF_UNKNOWN) {
367 THREAD_OFF(peer->t_start);
368 } else {
369 BGP_TIMER_ON(peer->t_start, bgp_start_timer,
370 peer->v_start);
371 }
372 THREAD_OFF(peer->t_connect);
373 THREAD_OFF(peer->t_holdtime);
374 bgp_keepalives_off(peer);
375 THREAD_OFF(peer->t_routeadv);
376 THREAD_OFF(peer->t_delayopen);
377 break;
378
379 case Connect:
380 /* After start timer is expired, the peer moves to Connect
381 status. Make sure start timer is off and connect timer is
382 on. */
383 THREAD_OFF(peer->t_start);
384 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
385 BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
386 (peer->v_delayopen + peer->v_connect));
387 else
388 BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
389 peer->v_connect);
390
391 THREAD_OFF(peer->t_holdtime);
392 bgp_keepalives_off(peer);
393 THREAD_OFF(peer->t_routeadv);
394 break;
395
396 case Active:
397 /* Active is waiting connection from remote peer. And if
398 connect timer is expired, change status to Connect. */
399 THREAD_OFF(peer->t_start);
400 /* If peer is passive mode, do not set connect timer. */
401 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)
402 || CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
403 THREAD_OFF(peer->t_connect);
404 } else {
405 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
406 BGP_TIMER_ON(
407 peer->t_connect, bgp_connect_timer,
408 (peer->v_delayopen + peer->v_connect));
409 else
410 BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
411 peer->v_connect);
412 }
413 THREAD_OFF(peer->t_holdtime);
414 bgp_keepalives_off(peer);
415 THREAD_OFF(peer->t_routeadv);
416 break;
417
418 case OpenSent:
419 /* OpenSent status. */
420 THREAD_OFF(peer->t_start);
421 THREAD_OFF(peer->t_connect);
422 if (peer->v_holdtime != 0) {
423 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
424 peer->v_holdtime);
425 } else {
426 THREAD_OFF(peer->t_holdtime);
427 }
428 bgp_keepalives_off(peer);
429 THREAD_OFF(peer->t_routeadv);
430 THREAD_OFF(peer->t_delayopen);
431 break;
432
433 case OpenConfirm:
434 /* OpenConfirm status. */
435 THREAD_OFF(peer->t_start);
436 THREAD_OFF(peer->t_connect);
437
438 /* If the negotiated Hold Time value is zero, then the Hold Time
439 timer and KeepAlive timers are not started. */
440 if (peer->v_holdtime == 0) {
441 THREAD_OFF(peer->t_holdtime);
442 bgp_keepalives_off(peer);
443 } else {
444 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
445 peer->v_holdtime);
446 bgp_keepalives_on(peer);
447 }
448 THREAD_OFF(peer->t_routeadv);
449 THREAD_OFF(peer->t_delayopen);
450 break;
451
452 case Established:
453 /* In Established status start and connect timer is turned
454 off. */
455 THREAD_OFF(peer->t_start);
456 THREAD_OFF(peer->t_connect);
457 THREAD_OFF(peer->t_delayopen);
458
459 /* Same as OpenConfirm, if holdtime is zero then both holdtime
460 and keepalive must be turned off. */
461 if (peer->v_holdtime == 0) {
462 THREAD_OFF(peer->t_holdtime);
463 bgp_keepalives_off(peer);
464 } else {
465 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
466 peer->v_holdtime);
467 bgp_keepalives_on(peer);
468 }
469 break;
470 case Deleted:
471 THREAD_OFF(peer->t_gr_restart);
472 THREAD_OFF(peer->t_gr_stale);
473
474 FOREACH_AFI_SAFI (afi, safi)
475 THREAD_OFF(peer->t_llgr_stale[afi][safi]);
476
477 THREAD_OFF(peer->t_pmax_restart);
478 THREAD_OFF(peer->t_refresh_stalepath);
479 /* fallthru */
480 case Clearing:
481 THREAD_OFF(peer->t_start);
482 THREAD_OFF(peer->t_connect);
483 THREAD_OFF(peer->t_holdtime);
484 bgp_keepalives_off(peer);
485 THREAD_OFF(peer->t_routeadv);
486 THREAD_OFF(peer->t_delayopen);
487 break;
488 case BGP_STATUS_MAX:
489 flog_err(EC_LIB_DEVELOPMENT,
490 "BGP_STATUS_MAX while a legal state is not valid state for the FSM");
491 break;
492 }
493 }
494
495 /* BGP start timer. This function set BGP_Start event to thread value
496 and process event. */
497 static void bgp_start_timer(struct thread *thread)
498 {
499 struct peer *peer;
500
501 peer = THREAD_ARG(thread);
502
503 if (bgp_debug_neighbor_events(peer))
504 zlog_debug("%s [FSM] Timer (start timer expire).", peer->host);
505
506 THREAD_VAL(thread) = BGP_Start;
507 bgp_event(thread); /* bgp_event unlocks peer */
508 }
509
510 /* BGP connect retry timer. */
511 static void bgp_connect_timer(struct thread *thread)
512 {
513 struct peer *peer;
514
515 peer = THREAD_ARG(thread);
516
517 /* stop the DelayOpenTimer if it is running */
518 THREAD_OFF(peer->t_delayopen);
519
520 assert(!peer->t_write);
521 assert(!peer->t_read);
522
523 if (bgp_debug_neighbor_events(peer))
524 zlog_debug("%s [FSM] Timer (connect timer expire)", peer->host);
525
526 if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
527 bgp_stop(peer);
528 else {
529 THREAD_VAL(thread) = ConnectRetry_timer_expired;
530 bgp_event(thread); /* bgp_event unlocks peer */
531 }
532 }
533
534 /* BGP holdtime timer. */
535 static void bgp_holdtime_timer(struct thread *thread)
536 {
537 atomic_size_t inq_count;
538 struct peer *peer;
539
540 peer = THREAD_ARG(thread);
541
542 if (bgp_debug_neighbor_events(peer))
543 zlog_debug("%s [FSM] Timer (holdtime timer expire)",
544 peer->host);
545
546 /*
547 * Given that we do not have any expectation of ordering
548 * for handling packets from a peer -vs- handling
549 * the hold timer for a peer as that they are both
550 * events on the peer. If we have incoming
551 * data on the peers inq, let's give the system a chance
552 * to handle that data. This can be especially true
553 * for systems where we are heavily loaded for one
554 * reason or another.
555 */
556 inq_count = atomic_load_explicit(&peer->ibuf->count,
557 memory_order_relaxed);
558 if (inq_count)
559 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
560 peer->v_holdtime);
561
562 THREAD_VAL(thread) = Hold_Timer_expired;
563 bgp_event(thread); /* bgp_event unlocks peer */
564 }
565
566 void bgp_routeadv_timer(struct thread *thread)
567 {
568 struct peer *peer;
569
570 peer = THREAD_ARG(thread);
571
572 if (bgp_debug_neighbor_events(peer))
573 zlog_debug("%s [FSM] Timer (routeadv timer expire)",
574 peer->host);
575
576 peer->synctime = monotime(NULL);
577
578 thread_add_timer_msec(bm->master, bgp_generate_updgrp_packets, peer, 0,
579 &peer->t_generate_updgrp_packets);
580
581 /* MRAI timer will be started again when FIFO is built, no need to
582 * do it here.
583 */
584 }
585
586 /* RFC 4271 DelayOpenTimer */
587 void bgp_delayopen_timer(struct thread *thread)
588 {
589 struct peer *peer;
590
591 peer = THREAD_ARG(thread);
592
593 if (bgp_debug_neighbor_events(peer))
594 zlog_debug("%s [FSM] Timer (DelayOpentimer expire)",
595 peer->host);
596
597 THREAD_VAL(thread) = DelayOpen_timer_expired;
598 bgp_event(thread); /* bgp_event unlocks peer */
599 }
600
601 /* BGP Peer Down Cause */
602 const char *const peer_down_str[] = {"",
603 "Router ID changed",
604 "Remote AS changed",
605 "Local AS change",
606 "Cluster ID changed",
607 "Confederation identifier changed",
608 "Confederation peer changed",
609 "RR client config change",
610 "RS client config change",
611 "Update source change",
612 "Address family activated",
613 "Admin. shutdown",
614 "User reset",
615 "BGP Notification received",
616 "BGP Notification send",
617 "Peer closed the session",
618 "Neighbor deleted",
619 "Peer-group add member",
620 "Peer-group delete member",
621 "Capability changed",
622 "Passive config change",
623 "Multihop config change",
624 "NSF peer closed the session",
625 "Intf peering v6only config change",
626 "BFD down received",
627 "Interface down",
628 "Neighbor address lost",
629 "No path to specified Neighbor",
630 "Waiting for Peer IPv6 LLA",
631 "Waiting for VRF to be initialized",
632 "No AFI/SAFI activated for peer",
633 "AS Set config change",
634 "Waiting for peer OPEN",
635 "Reached received prefix count",
636 "Socket Error",
637 "Admin. shutdown (RTT)"};
638
639 static void bgp_graceful_restart_timer_off(struct peer *peer)
640 {
641 afi_t afi;
642 safi_t safi;
643
644 FOREACH_AFI_SAFI (afi, safi)
645 if (CHECK_FLAG(peer->af_sflags[afi][safi],
646 PEER_STATUS_LLGR_WAIT))
647 return;
648
649 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
650 THREAD_OFF(peer->t_gr_stale);
651
652 if (peer_dynamic_neighbor(peer) &&
653 !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
654 if (bgp_debug_neighbor_events(peer))
655 zlog_debug("%s (dynamic neighbor) deleted (%s)",
656 peer->host, __func__);
657 peer_delete(peer);
658 }
659
660 bgp_timer_set(peer);
661 }
662
663 static void bgp_llgr_stale_timer_expire(struct thread *thread)
664 {
665 struct peer_af *paf;
666 struct peer *peer;
667 afi_t afi;
668 safi_t safi;
669
670 paf = THREAD_ARG(thread);
671
672 peer = paf->peer;
673 afi = paf->afi;
674 safi = paf->safi;
675
676 /* If the timer for the "Long-lived Stale Time" expires before the
677 * session is re-established, the helper MUST delete all the
678 * stale routes from the neighbor that it is retaining.
679 */
680 if (bgp_debug_neighbor_events(peer))
681 zlog_debug("%pBP Long-lived stale timer (%s) expired", peer,
682 get_afi_safi_str(afi, safi, false));
683
684 UNSET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_LLGR_WAIT);
685
686 bgp_clear_stale_route(peer, afi, safi);
687
688 bgp_graceful_restart_timer_off(peer);
689 }
690
691 static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
692 {
693 struct bgp_dest *dest;
694 struct bgp_path_info *pi;
695 struct bgp_table *table;
696 struct attr attr;
697
698 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
699 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
700 dest = bgp_route_next(dest)) {
701 struct bgp_dest *rm;
702
703 table = bgp_dest_get_bgp_table_info(dest);
704 if (!table)
705 continue;
706
707 for (rm = bgp_table_top(table); rm;
708 rm = bgp_route_next(rm))
709 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
710 pi = pi->next) {
711 if (pi->peer != peer)
712 continue;
713
714 if (bgp_attr_get_community(pi->attr) &&
715 community_include(
716 bgp_attr_get_community(
717 pi->attr),
718 COMMUNITY_NO_LLGR))
719 continue;
720
721 if (bgp_debug_neighbor_events(peer))
722 zlog_debug(
723 "%pBP Long-lived set stale community (LLGR_STALE) for: %pFX",
724 peer, &dest->p);
725
726 attr = *pi->attr;
727 bgp_attr_add_llgr_community(&attr);
728 pi->attr = bgp_attr_intern(&attr);
729 bgp_recalculate_afi_safi_bestpaths(
730 peer->bgp, afi, safi);
731
732 break;
733 }
734 }
735 } else {
736 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
737 dest = bgp_route_next(dest))
738 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
739 pi = pi->next) {
740 if (pi->peer != peer)
741 continue;
742
743 if (bgp_attr_get_community(pi->attr) &&
744 community_include(
745 bgp_attr_get_community(pi->attr),
746 COMMUNITY_NO_LLGR))
747 continue;
748
749 if (bgp_debug_neighbor_events(peer))
750 zlog_debug(
751 "%pBP Long-lived set stale community (LLGR_STALE) for: %pFX",
752 peer, &dest->p);
753
754 attr = *pi->attr;
755 bgp_attr_add_llgr_community(&attr);
756 pi->attr = bgp_attr_intern(&attr);
757 bgp_recalculate_afi_safi_bestpaths(peer->bgp,
758 afi, safi);
759
760 break;
761 }
762 }
763 }
764
765 static void bgp_graceful_restart_timer_expire(struct thread *thread)
766 {
767 struct peer *peer, *tmp_peer;
768 struct listnode *node, *nnode;
769 struct peer_af *paf;
770 afi_t afi;
771 safi_t safi;
772
773 peer = THREAD_ARG(thread);
774
775 if (bgp_debug_neighbor_events(peer)) {
776 zlog_debug("%pBP graceful restart timer expired", peer);
777 zlog_debug("%pBP graceful restart stalepath timer stopped",
778 peer);
779 }
780
781 FOREACH_AFI_SAFI (afi, safi) {
782 if (!peer->nsf[afi][safi])
783 continue;
784
785 /* Once the "Restart Time" period ends, the LLGR period is
786 * said to have begun and the following procedures MUST be
787 * performed:
788 *
789 * The helper router MUST start a timer for the
790 * "Long-lived Stale Time".
791 *
792 * The helper router MUST attach the LLGR_STALE community
793 * for the stale routes being retained. Note that this
794 * requirement implies that the routes would need to be
795 * readvertised, to disseminate the modified community.
796 */
797 if (peer->llgr[afi][safi].stale_time) {
798 paf = peer_af_find(peer, afi, safi);
799 if (!paf)
800 continue;
801
802 if (bgp_debug_neighbor_events(peer))
803 zlog_debug(
804 "%pBP Long-lived stale timer (%s) started for %d sec",
805 peer,
806 get_afi_safi_str(afi, safi, false),
807 peer->llgr[afi][safi].stale_time);
808
809 SET_FLAG(peer->af_sflags[afi][safi],
810 PEER_STATUS_LLGR_WAIT);
811
812 bgp_set_llgr_stale(peer, afi, safi);
813 bgp_clear_stale_route(peer, afi, safi);
814
815 thread_add_timer(bm->master,
816 bgp_llgr_stale_timer_expire, paf,
817 peer->llgr[afi][safi].stale_time,
818 &peer->t_llgr_stale[afi][safi]);
819
820 for (ALL_LIST_ELEMENTS(peer->bgp->peer, node, nnode,
821 tmp_peer))
822 bgp_announce_route(tmp_peer, afi, safi, false);
823 } else {
824 bgp_clear_stale_route(peer, afi, safi);
825 }
826 }
827
828 bgp_graceful_restart_timer_off(peer);
829 }
830
831 static void bgp_graceful_stale_timer_expire(struct thread *thread)
832 {
833 struct peer *peer;
834 afi_t afi;
835 safi_t safi;
836
837 peer = THREAD_ARG(thread);
838
839 if (bgp_debug_neighbor_events(peer))
840 zlog_debug("%pBP graceful restart stalepath timer expired",
841 peer);
842
843 /* NSF delete stale route */
844 FOREACH_AFI_SAFI_NSF (afi, safi)
845 if (peer->nsf[afi][safi])
846 bgp_clear_stale_route(peer, afi, safi);
847 }
848
849 /* Selection deferral timer processing function */
850 static void bgp_graceful_deferral_timer_expire(struct thread *thread)
851 {
852 struct afi_safi_info *info;
853 afi_t afi;
854 safi_t safi;
855 struct bgp *bgp;
856
857 info = THREAD_ARG(thread);
858 afi = info->afi;
859 safi = info->safi;
860 bgp = info->bgp;
861
862 if (BGP_DEBUG(update, UPDATE_OUT))
863 zlog_debug(
864 "afi %d, safi %d : graceful restart deferral timer expired",
865 afi, safi);
866
867 bgp->gr_info[afi][safi].eor_required = 0;
868 bgp->gr_info[afi][safi].eor_received = 0;
869 XFREE(MTYPE_TMP, info);
870
871 /* Best path selection */
872 bgp_best_path_select_defer(bgp, afi, safi);
873 }
874
875 static bool bgp_update_delay_applicable(struct bgp *bgp)
876 {
877 /* update_delay_over flag should be reset (set to 0) for any new
878 applicability of the update-delay during BGP process lifetime.
879 And it should be set after an occurence of the update-delay is
880 over)*/
881 if (!bgp->update_delay_over)
882 return true;
883 return false;
884 }
885
886 bool bgp_update_delay_active(struct bgp *bgp)
887 {
888 if (bgp->t_update_delay)
889 return true;
890 return false;
891 }
892
893 bool bgp_update_delay_configured(struct bgp *bgp)
894 {
895 if (bgp->v_update_delay)
896 return true;
897 return false;
898 }
899
900 /* Do the post-processing needed when bgp comes out of the read-only mode
901 on ending the update delay. */
902 void bgp_update_delay_end(struct bgp *bgp)
903 {
904 THREAD_OFF(bgp->t_update_delay);
905 THREAD_OFF(bgp->t_establish_wait);
906
907 /* Reset update-delay related state */
908 bgp->update_delay_over = 1;
909 bgp->established = 0;
910 bgp->restarted_peers = 0;
911 bgp->implicit_eors = 0;
912 bgp->explicit_eors = 0;
913
914 frr_timestamp(3, bgp->update_delay_end_time,
915 sizeof(bgp->update_delay_end_time));
916
917 /*
918 * Add an end-of-initial-update marker to the main process queues so
919 * that
920 * the route advertisement timer for the peers can be started. Also set
921 * the zebra and peer update hold flags. These flags are used to achieve
922 * three stages in the update-delay post processing:
923 * 1. Finish best-path selection for all the prefixes held on the
924 * queues.
925 * (routes in BGP are updated, and peers sync queues are populated
926 * too)
927 * 2. As the eoiu mark is reached in the bgp process routine, ship all
928 * the
929 * routes to zebra. With that zebra should see updates from BGP
930 * close
931 * to each other.
932 * 3. Unblock the peer update writes. With that peer update packing
933 * with
934 * the prefixes should be at its maximum.
935 */
936 bgp_add_eoiu_mark(bgp);
937 bgp->main_zebra_update_hold = 1;
938 bgp->main_peers_update_hold = 1;
939
940 /*
941 * Resume the queue processing. This should trigger the event that would
942 * take care of processing any work that was queued during the read-only
943 * mode.
944 */
945 work_queue_unplug(bgp->process_queue);
946 }
947
948 /**
949 * see bgp_fsm.h
950 */
951 void bgp_start_routeadv(struct bgp *bgp)
952 {
953 struct listnode *node, *nnode;
954 struct peer *peer;
955
956 zlog_info("%s, update hold status %d", __func__,
957 bgp->main_peers_update_hold);
958
959 if (bgp->main_peers_update_hold)
960 return;
961
962 frr_timestamp(3, bgp->update_delay_peers_resume_time,
963 sizeof(bgp->update_delay_peers_resume_time));
964
965 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
966 if (!peer_established(peer))
967 continue;
968 THREAD_OFF(peer->t_routeadv);
969 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
970 }
971 }
972
973 /**
974 * see bgp_fsm.h
975 */
976 void bgp_adjust_routeadv(struct peer *peer)
977 {
978 time_t nowtime = monotime(NULL);
979 double diff;
980 unsigned long remain;
981
982 /* Bypass checks for special case of MRAI being 0 */
983 if (peer->v_routeadv == 0) {
984 /* Stop existing timer, just in case it is running for a
985 * different
986 * duration and schedule write thread immediately.
987 */
988 THREAD_OFF(peer->t_routeadv);
989
990 peer->synctime = monotime(NULL);
991 /* If suppress fib pending is enabled, route is advertised to
992 * peers when the status is received from the FIB. The delay
993 * is added to update group packet generate which will allow
994 * more routes to be sent in the update message
995 */
996 BGP_UPDATE_GROUP_TIMER_ON(&peer->t_generate_updgrp_packets,
997 bgp_generate_updgrp_packets);
998 return;
999 }
1000
1001
1002 /*
1003 * CASE I:
1004 * If the last update was written more than MRAI back, expire the timer
1005 * instantly so that we can send the update out sooner.
1006 *
1007 * <------- MRAI --------->
1008 * |-----------------|-----------------------|
1009 * <------------- m ------------>
1010 * ^ ^ ^
1011 * | | |
1012 * | | current time
1013 * | timer start
1014 * last write
1015 *
1016 * m > MRAI
1017 */
1018 diff = difftime(nowtime, peer->last_update);
1019 if (diff > (double)peer->v_routeadv) {
1020 THREAD_OFF(peer->t_routeadv);
1021 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
1022 return;
1023 }
1024
1025 /*
1026 * CASE II:
1027 * - Find when to expire the MRAI timer.
1028 * If MRAI timer is not active, assume we can start it now.
1029 *
1030 * <------- MRAI --------->
1031 * |------------|-----------------------|
1032 * <-------- m ----------><----- r ----->
1033 * ^ ^ ^
1034 * | | |
1035 * | | current time
1036 * | timer start
1037 * last write
1038 *
1039 * (MRAI - m) < r
1040 */
1041 if (peer->t_routeadv)
1042 remain = thread_timer_remain_second(peer->t_routeadv);
1043 else
1044 remain = peer->v_routeadv;
1045 diff = peer->v_routeadv - diff;
1046 if (diff <= (double)remain) {
1047 THREAD_OFF(peer->t_routeadv);
1048 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, diff);
1049 }
1050 }
1051
1052 static bool bgp_maxmed_onstartup_applicable(struct bgp *bgp)
1053 {
1054 if (!bgp->maxmed_onstartup_over)
1055 return true;
1056 return false;
1057 }
1058
1059 bool bgp_maxmed_onstartup_configured(struct bgp *bgp)
1060 {
1061 if (bgp->v_maxmed_onstartup != BGP_MAXMED_ONSTARTUP_UNCONFIGURED)
1062 return true;
1063 return false;
1064 }
1065
1066 bool bgp_maxmed_onstartup_active(struct bgp *bgp)
1067 {
1068 if (bgp->t_maxmed_onstartup)
1069 return true;
1070 return false;
1071 }
1072
1073 void bgp_maxmed_update(struct bgp *bgp)
1074 {
1075 uint8_t maxmed_active;
1076 uint32_t maxmed_value;
1077
1078 if (bgp->v_maxmed_admin) {
1079 maxmed_active = 1;
1080 maxmed_value = bgp->maxmed_admin_value;
1081 } else if (bgp->t_maxmed_onstartup) {
1082 maxmed_active = 1;
1083 maxmed_value = bgp->maxmed_onstartup_value;
1084 } else {
1085 maxmed_active = 0;
1086 maxmed_value = BGP_MAXMED_VALUE_DEFAULT;
1087 }
1088
1089 if (bgp->maxmed_active != maxmed_active
1090 || bgp->maxmed_value != maxmed_value) {
1091 bgp->maxmed_active = maxmed_active;
1092 bgp->maxmed_value = maxmed_value;
1093
1094 update_group_announce(bgp);
1095 }
1096 }
1097
1098 int bgp_fsm_error_subcode(int status)
1099 {
1100 int fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_UNSPECIFIC;
1101
1102 switch (status) {
1103 case OpenSent:
1104 fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_OPENSENT;
1105 break;
1106 case OpenConfirm:
1107 fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_OPENCONFIRM;
1108 break;
1109 case Established:
1110 fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_ESTABLISHED;
1111 break;
1112 default:
1113 break;
1114 }
1115
1116 return fsm_err_subcode;
1117 }
1118
1119 /* The maxmed onstartup timer expiry callback. */
1120 static void bgp_maxmed_onstartup_timer(struct thread *thread)
1121 {
1122 struct bgp *bgp;
1123
1124 zlog_info("Max med on startup ended - timer expired.");
1125
1126 bgp = THREAD_ARG(thread);
1127 THREAD_OFF(bgp->t_maxmed_onstartup);
1128 bgp->maxmed_onstartup_over = 1;
1129
1130 bgp_maxmed_update(bgp);
1131 }
1132
1133 static void bgp_maxmed_onstartup_begin(struct bgp *bgp)
1134 {
1135 /* Applicable only once in the process lifetime on the startup */
1136 if (bgp->maxmed_onstartup_over)
1137 return;
1138
1139 zlog_info("Begin maxmed onstartup mode - timer %d seconds",
1140 bgp->v_maxmed_onstartup);
1141
1142 thread_add_timer(bm->master, bgp_maxmed_onstartup_timer, bgp,
1143 bgp->v_maxmed_onstartup, &bgp->t_maxmed_onstartup);
1144
1145 if (!bgp->v_maxmed_admin) {
1146 bgp->maxmed_active = 1;
1147 bgp->maxmed_value = bgp->maxmed_onstartup_value;
1148 }
1149
1150 /* Route announce to all peers should happen after this in
1151 * bgp_establish() */
1152 }
1153
1154 static void bgp_maxmed_onstartup_process_status_change(struct peer *peer)
1155 {
1156 if (peer_established(peer) && !peer->bgp->established) {
1157 bgp_maxmed_onstartup_begin(peer->bgp);
1158 }
1159 }
1160
1161 /* The update delay timer expiry callback. */
1162 static void bgp_update_delay_timer(struct thread *thread)
1163 {
1164 struct bgp *bgp;
1165
1166 zlog_info("Update delay ended - timer expired.");
1167
1168 bgp = THREAD_ARG(thread);
1169 THREAD_OFF(bgp->t_update_delay);
1170 bgp_update_delay_end(bgp);
1171 }
1172
1173 /* The establish wait timer expiry callback. */
1174 static void bgp_establish_wait_timer(struct thread *thread)
1175 {
1176 struct bgp *bgp;
1177
1178 zlog_info("Establish wait - timer expired.");
1179
1180 bgp = THREAD_ARG(thread);
1181 THREAD_OFF(bgp->t_establish_wait);
1182 bgp_check_update_delay(bgp);
1183 }
1184
1185 /* Steps to begin the update delay:
1186 - initialize queues if needed
1187 - stop the queue processing
1188 - start the timer */
1189 static void bgp_update_delay_begin(struct bgp *bgp)
1190 {
1191 struct listnode *node, *nnode;
1192 struct peer *peer;
1193
1194 /* Stop the processing of queued work. Enqueue shall continue */
1195 work_queue_plug(bgp->process_queue);
1196
1197 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
1198 peer->update_delay_over = 0;
1199
1200 /* Start the update-delay timer */
1201 thread_add_timer(bm->master, bgp_update_delay_timer, bgp,
1202 bgp->v_update_delay, &bgp->t_update_delay);
1203
1204 if (bgp->v_establish_wait != bgp->v_update_delay)
1205 thread_add_timer(bm->master, bgp_establish_wait_timer, bgp,
1206 bgp->v_establish_wait, &bgp->t_establish_wait);
1207
1208 frr_timestamp(3, bgp->update_delay_begin_time,
1209 sizeof(bgp->update_delay_begin_time));
1210 }
1211
1212 static void bgp_update_delay_process_status_change(struct peer *peer)
1213 {
1214 if (peer_established(peer)) {
1215 if (!peer->bgp->established++) {
1216 bgp_update_delay_begin(peer->bgp);
1217 zlog_info(
1218 "Begin read-only mode - update-delay timer %d seconds",
1219 peer->bgp->v_update_delay);
1220 }
1221 if (CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV))
1222 bgp_update_restarted_peers(peer);
1223 }
1224 if (peer->ostatus == Established
1225 && bgp_update_delay_active(peer->bgp)) {
1226 /* Adjust the update-delay state to account for this flap.
1227 NOTE: Intentionally skipping adjusting implicit_eors or
1228 explicit_eors
1229 counters. Extra sanity check in bgp_check_update_delay()
1230 should
1231 be enough to take care of any additive discrepancy in bgp eor
1232 counters */
1233 peer->bgp->established--;
1234 peer->update_delay_over = 0;
1235 }
1236 }
1237
1238 /* Called after event occurred, this function change status and reset
1239 read/write and timer thread. */
1240 void bgp_fsm_change_status(struct peer *peer, enum bgp_fsm_status status)
1241 {
1242 struct bgp *bgp;
1243 uint32_t peer_count;
1244
1245 bgp = peer->bgp;
1246 peer_count = bgp->established_peers;
1247
1248 if (status == Established)
1249 bgp->established_peers++;
1250 else if ((peer_established(peer)) && (status != Established))
1251 bgp->established_peers--;
1252
1253 if (bgp_debug_neighbor_events(peer)) {
1254 struct vrf *vrf = vrf_lookup_by_id(bgp->vrf_id);
1255
1256 zlog_debug("%s : vrf %s(%u), Status: %s established_peers %u", __func__,
1257 vrf ? vrf->name : "Unknown", bgp->vrf_id,
1258 lookup_msg(bgp_status_msg, status, NULL),
1259 bgp->established_peers);
1260 }
1261
1262 /* Set to router ID to the value provided by RIB if there are no peers
1263 * in the established state and peer count did not change
1264 */
1265 if ((peer_count != bgp->established_peers) &&
1266 (bgp->established_peers == 0))
1267 bgp_router_id_zebra_bump(bgp->vrf_id, NULL);
1268
1269 /* Transition into Clearing or Deleted must /always/ clear all routes..
1270 * (and must do so before actually changing into Deleted..
1271 */
1272 if (status >= Clearing) {
1273 bgp_clear_route_all(peer);
1274
1275 /* If no route was queued for the clear-node processing,
1276 * generate the
1277 * completion event here. This is needed because if there are no
1278 * routes
1279 * to trigger the background clear-node thread, the event won't
1280 * get
1281 * generated and the peer would be stuck in Clearing. Note that
1282 * this
1283 * event is for the peer and helps the peer transition out of
1284 * Clearing
1285 * state; it should not be generated per (AFI,SAFI). The event
1286 * is
1287 * directly posted here without calling clear_node_complete() as
1288 * we
1289 * shouldn't do an extra unlock. This event will get processed
1290 * after
1291 * the state change that happens below, so peer will be in
1292 * Clearing
1293 * (or Deleted).
1294 */
1295 if (!work_queue_is_scheduled(peer->clear_node_queue) &&
1296 status != Deleted)
1297 BGP_EVENT_ADD(peer, Clearing_Completed);
1298 }
1299
1300 /* Preserve old status and change into new status. */
1301 peer->ostatus = peer->status;
1302 peer->status = status;
1303
1304 /* Reset received keepalives counter on every FSM change */
1305 peer->rtt_keepalive_rcv = 0;
1306
1307 /* Fire backward transition hook if that's the case */
1308 if (peer->ostatus == Established && peer->status != Established)
1309 hook_call(peer_backward_transition, peer);
1310
1311 /* Save event that caused status change. */
1312 peer->last_major_event = peer->cur_event;
1313
1314 /* Operations after status change */
1315 hook_call(peer_status_changed, peer);
1316
1317 if (status == Established)
1318 UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
1319
1320 /* If max-med processing is applicable, do the necessary. */
1321 if (status == Established) {
1322 if (bgp_maxmed_onstartup_configured(peer->bgp)
1323 && bgp_maxmed_onstartup_applicable(peer->bgp))
1324 bgp_maxmed_onstartup_process_status_change(peer);
1325 else
1326 peer->bgp->maxmed_onstartup_over = 1;
1327 }
1328
1329 /* If update-delay processing is applicable, do the necessary. */
1330 if (bgp_update_delay_configured(peer->bgp)
1331 && bgp_update_delay_applicable(peer->bgp))
1332 bgp_update_delay_process_status_change(peer);
1333
1334 if (bgp_debug_neighbor_events(peer))
1335 zlog_debug("%s fd %d went from %s to %s", peer->host, peer->fd,
1336 lookup_msg(bgp_status_msg, peer->ostatus, NULL),
1337 lookup_msg(bgp_status_msg, peer->status, NULL));
1338 }
1339
1340 /* Flush the event queue and ensure the peer is shut down */
1341 static enum bgp_fsm_state_progress bgp_clearing_completed(struct peer *peer)
1342 {
1343 enum bgp_fsm_state_progress rc = bgp_stop(peer);
1344
1345 if (rc >= BGP_FSM_SUCCESS)
1346 BGP_EVENT_FLUSH(peer);
1347
1348 return rc;
1349 }
1350
1351 /* Administrative BGP peer stop event. */
1352 /* May be called multiple times for the same peer */
1353 enum bgp_fsm_state_progress bgp_stop(struct peer *peer)
1354 {
1355 afi_t afi;
1356 safi_t safi;
1357 char orf_name[BUFSIZ];
1358 enum bgp_fsm_state_progress ret = BGP_FSM_SUCCESS;
1359 struct bgp *bgp = peer->bgp;
1360 struct graceful_restart_info *gr_info = NULL;
1361
1362 peer->nsf_af_count = 0;
1363
1364 /* deregister peer */
1365 if (peer->bfd_config
1366 && peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE)
1367 bfd_sess_uninstall(peer->bfd_config->session);
1368
1369 if (peer_dynamic_neighbor_no_nsf(peer) &&
1370 !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
1371 if (bgp_debug_neighbor_events(peer))
1372 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1373 peer->host, __func__);
1374 peer_delete(peer);
1375 return BGP_FSM_FAILURE_AND_DELETE;
1376 }
1377
1378 /* Can't do this in Clearing; events are used for state transitions */
1379 if (peer->status != Clearing) {
1380 /* Delete all existing events of the peer */
1381 BGP_EVENT_FLUSH(peer);
1382 }
1383
1384 /* Increment Dropped count. */
1385 if (peer_established(peer)) {
1386 peer->dropped++;
1387
1388 /* Notify BGP conditional advertisement process */
1389 peer->advmap_table_change = true;
1390
1391 /* bgp log-neighbor-changes of neighbor Down */
1392 if (CHECK_FLAG(peer->bgp->flags,
1393 BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
1394 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
1395
1396 zlog_info(
1397 "%%ADJCHANGE: neighbor %pBP in vrf %s Down %s",
1398 peer,
1399 vrf ? ((vrf->vrf_id != VRF_DEFAULT)
1400 ? vrf->name
1401 : VRF_DEFAULT_NAME)
1402 : "",
1403 peer_down_str[(int)peer->last_reset]);
1404 }
1405
1406 /* graceful restart */
1407 if (peer->t_gr_stale) {
1408 THREAD_OFF(peer->t_gr_stale);
1409 if (bgp_debug_neighbor_events(peer))
1410 zlog_debug(
1411 "%pBP graceful restart stalepath timer stopped",
1412 peer);
1413 }
1414 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
1415 if (bgp_debug_neighbor_events(peer)) {
1416 zlog_debug(
1417 "%pBP graceful restart timer started for %d sec",
1418 peer, peer->v_gr_restart);
1419 zlog_debug(
1420 "%pBP graceful restart stalepath timer started for %d sec",
1421 peer, peer->bgp->stalepath_time);
1422 }
1423 BGP_TIMER_ON(peer->t_gr_restart,
1424 bgp_graceful_restart_timer_expire,
1425 peer->v_gr_restart);
1426 BGP_TIMER_ON(peer->t_gr_stale,
1427 bgp_graceful_stale_timer_expire,
1428 peer->bgp->stalepath_time);
1429 } else {
1430 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
1431
1432 FOREACH_AFI_SAFI_NSF (afi, safi)
1433 peer->nsf[afi][safi] = 0;
1434 }
1435
1436 /* Stop route-refresh stalepath timer */
1437 if (peer->t_refresh_stalepath) {
1438 THREAD_OFF(peer->t_refresh_stalepath);
1439
1440 if (bgp_debug_neighbor_events(peer))
1441 zlog_debug(
1442 "%pBP route-refresh restart stalepath timer stopped",
1443 peer);
1444 }
1445
1446 /* If peer reset before receiving EOR, decrement EOR count and
1447 * cancel the selection deferral timer if there are no
1448 * pending EOR messages to be received
1449 */
1450 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
1451 FOREACH_AFI_SAFI (afi, safi) {
1452 if (!peer->afc_nego[afi][safi]
1453 || CHECK_FLAG(peer->af_sflags[afi][safi],
1454 PEER_STATUS_EOR_RECEIVED))
1455 continue;
1456
1457 gr_info = &bgp->gr_info[afi][safi];
1458 if (!gr_info)
1459 continue;
1460
1461 if (gr_info->eor_required)
1462 gr_info->eor_required--;
1463
1464 if (BGP_DEBUG(update, UPDATE_OUT))
1465 zlog_debug("peer %s, EOR_required %d",
1466 peer->host,
1467 gr_info->eor_required);
1468
1469 /* There is no pending EOR message */
1470 if (gr_info->eor_required == 0) {
1471 if (gr_info->t_select_deferral) {
1472 void *info = THREAD_ARG(
1473 gr_info->t_select_deferral);
1474 XFREE(MTYPE_TMP, info);
1475 }
1476 THREAD_OFF(gr_info->t_select_deferral);
1477 gr_info->eor_received = 0;
1478 }
1479 }
1480 }
1481
1482 /* set last reset time */
1483 peer->resettime = peer->uptime = monotime(NULL);
1484
1485 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1486 zlog_debug("%s remove from all update group",
1487 peer->host);
1488 update_group_remove_peer_afs(peer);
1489
1490 /* Reset peer synctime */
1491 peer->synctime = 0;
1492 }
1493
1494 /* stop keepalives */
1495 bgp_keepalives_off(peer);
1496
1497 /* Stop read and write threads. */
1498 bgp_writes_off(peer);
1499 bgp_reads_off(peer);
1500
1501 THREAD_OFF(peer->t_connect_check_r);
1502 THREAD_OFF(peer->t_connect_check_w);
1503
1504 /* Stop all timers. */
1505 THREAD_OFF(peer->t_start);
1506 THREAD_OFF(peer->t_connect);
1507 THREAD_OFF(peer->t_holdtime);
1508 THREAD_OFF(peer->t_routeadv);
1509 THREAD_OFF(peer->t_delayopen);
1510
1511 /* Clear input and output buffer. */
1512 frr_with_mutex (&peer->io_mtx) {
1513 if (peer->ibuf)
1514 stream_fifo_clean(peer->ibuf);
1515 if (peer->obuf)
1516 stream_fifo_clean(peer->obuf);
1517
1518 if (peer->ibuf_work)
1519 ringbuf_wipe(peer->ibuf_work);
1520 if (peer->obuf_work)
1521 stream_reset(peer->obuf_work);
1522
1523 if (peer->curr) {
1524 stream_free(peer->curr);
1525 peer->curr = NULL;
1526 }
1527 }
1528
1529 /* Close of file descriptor. */
1530 if (peer->fd >= 0) {
1531 close(peer->fd);
1532 peer->fd = -1;
1533 }
1534
1535 /* Reset capabilities. */
1536 peer->cap = 0;
1537
1538 /* Resetting neighbor role to the default value */
1539 peer->remote_role = ROLE_UNDEFINED;
1540
1541 FOREACH_AFI_SAFI (afi, safi) {
1542 /* Reset all negotiated variables */
1543 peer->afc_nego[afi][safi] = 0;
1544 peer->afc_adv[afi][safi] = 0;
1545 peer->afc_recv[afi][safi] = 0;
1546
1547 /* peer address family capability flags*/
1548 peer->af_cap[afi][safi] = 0;
1549
1550 /* peer address family status flags*/
1551 peer->af_sflags[afi][safi] = 0;
1552
1553 /* Received ORF prefix-filter */
1554 peer->orf_plist[afi][safi] = NULL;
1555
1556 if ((peer->status == OpenConfirm) || (peer_established(peer))) {
1557 /* ORF received prefix-filter pnt */
1558 snprintf(orf_name, sizeof(orf_name), "%s.%d.%d",
1559 peer->host, afi, safi);
1560 prefix_bgp_orf_remove_all(afi, orf_name);
1561 }
1562 }
1563
1564 /* Reset keepalive and holdtime */
1565 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) {
1566 peer->v_keepalive = peer->keepalive;
1567 peer->v_holdtime = peer->holdtime;
1568 } else {
1569 peer->v_keepalive = peer->bgp->default_keepalive;
1570 peer->v_holdtime = peer->bgp->default_holdtime;
1571 }
1572
1573 /* Reset DelayOpenTime */
1574 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
1575 peer->v_delayopen = peer->delayopen;
1576 else
1577 peer->v_delayopen = peer->bgp->default_delayopen;
1578
1579 peer->update_time = 0;
1580
1581 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)
1582 && !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
1583 peer_delete(peer);
1584 ret = BGP_FSM_FAILURE_AND_DELETE;
1585 } else {
1586 bgp_peer_conf_if_to_su_update(peer);
1587 }
1588 return ret;
1589 }
1590
1591 /* BGP peer is stoped by the error. */
1592 static enum bgp_fsm_state_progress bgp_stop_with_error(struct peer *peer)
1593 {
1594 /* Double start timer. */
1595 peer->v_start *= 2;
1596
1597 /* Overflow check. */
1598 if (peer->v_start >= (60 * 2))
1599 peer->v_start = (60 * 2);
1600
1601 if (peer_dynamic_neighbor_no_nsf(peer)) {
1602 if (bgp_debug_neighbor_events(peer))
1603 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1604 peer->host, __func__);
1605 peer_delete(peer);
1606 return BGP_FSM_FAILURE;
1607 }
1608
1609 return bgp_stop(peer);
1610 }
1611
1612
1613 /* something went wrong, send notify and tear down */
1614 static enum bgp_fsm_state_progress
1615 bgp_stop_with_notify(struct peer *peer, uint8_t code, uint8_t sub_code)
1616 {
1617 /* Send notify to remote peer */
1618 bgp_notify_send(peer, code, sub_code);
1619
1620 if (peer_dynamic_neighbor_no_nsf(peer)) {
1621 if (bgp_debug_neighbor_events(peer))
1622 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1623 peer->host, __func__);
1624 peer_delete(peer);
1625 return BGP_FSM_FAILURE;
1626 }
1627
1628 /* Clear start timer value to default. */
1629 peer->v_start = BGP_INIT_START_TIMER;
1630
1631 return bgp_stop(peer);
1632 }
1633
1634 /**
1635 * Determines whether a TCP session has successfully established for a peer and
1636 * events as appropriate.
1637 *
1638 * This function is called when setting up a new session. After connect() is
1639 * called on the peer's socket (in bgp_start()), the fd is passed to poll()
1640 * to wait for connection success or failure. When poll() returns, this
1641 * function is called to evaluate the result.
1642 *
1643 * Due to differences in behavior of poll() on Linux and BSD - specifically,
1644 * the value of .revents in the case of a closed connection - this function is
1645 * scheduled both for a read and a write event. The write event is triggered
1646 * when the connection is established. A read event is triggered when the
1647 * connection is closed. Thus we need to cancel whichever one did not occur.
1648 */
1649 static void bgp_connect_check(struct thread *thread)
1650 {
1651 int status;
1652 socklen_t slen;
1653 int ret;
1654 struct peer *peer;
1655
1656 peer = THREAD_ARG(thread);
1657 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
1658 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
1659 assert(!peer->t_read);
1660 assert(!peer->t_write);
1661
1662 THREAD_OFF(peer->t_connect_check_r);
1663 THREAD_OFF(peer->t_connect_check_w);
1664
1665 /* Check file descriptor. */
1666 slen = sizeof(status);
1667 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *)&status,
1668 &slen);
1669
1670 /* If getsockopt is fail, this is fatal error. */
1671 if (ret < 0) {
1672 zlog_err("can't get sockopt for nonblocking connect: %d(%s)",
1673 errno, safe_strerror(errno));
1674 BGP_EVENT_ADD(peer, TCP_fatal_error);
1675 return;
1676 }
1677
1678 /* When status is 0 then TCP connection is established. */
1679 if (status == 0) {
1680 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
1681 BGP_EVENT_ADD(peer, TCP_connection_open_w_delay);
1682 else
1683 BGP_EVENT_ADD(peer, TCP_connection_open);
1684 return;
1685 } else {
1686 if (bgp_debug_neighbor_events(peer))
1687 zlog_debug("%s [Event] Connect failed %d(%s)",
1688 peer->host, status, safe_strerror(status));
1689 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1690 return;
1691 }
1692 }
1693
1694 /* TCP connection open. Next we send open message to remote peer. And
1695 add read thread for reading open message. */
1696 static enum bgp_fsm_state_progress bgp_connect_success(struct peer *peer)
1697 {
1698 if (peer->fd < 0) {
1699 flog_err(EC_BGP_CONNECT, "%s peer's fd is negative value %d",
1700 __func__, peer->fd);
1701 return bgp_stop(peer);
1702 }
1703
1704 if (bgp_getsockname(peer) < 0) {
1705 flog_err_sys(EC_LIB_SOCKET,
1706 "%s: bgp_getsockname(): failed for peer %s, fd %d",
1707 __func__, peer->host, peer->fd);
1708 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
1709 bgp_fsm_error_subcode(peer->status));
1710 bgp_writes_on(peer);
1711 return BGP_FSM_FAILURE;
1712 }
1713
1714 /*
1715 * If we are doing nht for a peer that ls v6 LL based
1716 * massage the event system to make things happy
1717 */
1718 bgp_nht_interface_events(peer);
1719
1720 bgp_reads_on(peer);
1721
1722 if (bgp_debug_neighbor_events(peer)) {
1723 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
1724 zlog_debug("%s open active, local address %pSU",
1725 peer->host, peer->su_local);
1726 else
1727 zlog_debug("%s passive open", peer->host);
1728 }
1729
1730 /* Send an open message */
1731 bgp_open_send(peer);
1732
1733 return BGP_FSM_SUCCESS;
1734 }
1735
1736 /* TCP connection open with RFC 4271 optional session attribute DelayOpen flag
1737 * set.
1738 */
1739 static enum bgp_fsm_state_progress
1740 bgp_connect_success_w_delayopen(struct peer *peer)
1741 {
1742 if (peer->fd < 0) {
1743 flog_err(EC_BGP_CONNECT, "%s: peer's fd is negative value %d",
1744 __func__, peer->fd);
1745 return bgp_stop(peer);
1746 }
1747
1748 if (bgp_getsockname(peer) < 0) {
1749 flog_err_sys(EC_LIB_SOCKET,
1750 "%s: bgp_getsockname(): failed for peer %s, fd %d",
1751 __func__, peer->host, peer->fd);
1752 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
1753 bgp_fsm_error_subcode(peer->status));
1754 bgp_writes_on(peer);
1755 return BGP_FSM_FAILURE;
1756 }
1757
1758 /*
1759 * If we are doing nht for a peer that ls v6 LL based
1760 * massage the event system to make things happy
1761 */
1762 bgp_nht_interface_events(peer);
1763
1764 bgp_reads_on(peer);
1765
1766 if (bgp_debug_neighbor_events(peer)) {
1767 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
1768 zlog_debug("%s open active, local address %pSU",
1769 peer->host, peer->su_local);
1770 else
1771 zlog_debug("%s passive open", peer->host);
1772 }
1773
1774 /* set the DelayOpenTime to the inital value */
1775 peer->v_delayopen = peer->delayopen;
1776
1777 /* Start the DelayOpenTimer if it is not already running */
1778 if (!peer->t_delayopen)
1779 BGP_TIMER_ON(peer->t_delayopen, bgp_delayopen_timer,
1780 peer->v_delayopen);
1781
1782 if (bgp_debug_neighbor_events(peer))
1783 zlog_debug("%s [FSM] BGP OPEN message delayed for %d seconds",
1784 peer->host, peer->delayopen);
1785
1786 return BGP_FSM_SUCCESS;
1787 }
1788
1789 /* TCP connect fail */
1790 static enum bgp_fsm_state_progress bgp_connect_fail(struct peer *peer)
1791 {
1792 if (peer_dynamic_neighbor_no_nsf(peer)) {
1793 if (bgp_debug_neighbor_events(peer))
1794 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1795 peer->host, __func__);
1796 peer_delete(peer);
1797 return BGP_FSM_FAILURE_AND_DELETE;
1798 }
1799
1800 /*
1801 * If we are doing nht for a peer that ls v6 LL based
1802 * massage the event system to make things happy
1803 */
1804 bgp_nht_interface_events(peer);
1805
1806 return bgp_stop(peer);
1807 }
1808
1809 /* This function is the first starting point of all BGP connection. It
1810 * try to connect to remote peer with non-blocking IO.
1811 */
1812 enum bgp_fsm_state_progress bgp_start(struct peer *peer)
1813 {
1814 int status;
1815
1816 bgp_peer_conf_if_to_su_update(peer);
1817
1818 if (peer->su.sa.sa_family == AF_UNSPEC) {
1819 if (bgp_debug_neighbor_events(peer))
1820 zlog_debug(
1821 "%s [FSM] Unable to get neighbor's IP address, waiting...",
1822 peer->host);
1823 peer->last_reset = PEER_DOWN_NBR_ADDR;
1824 return BGP_FSM_FAILURE;
1825 }
1826
1827 if (BGP_PEER_START_SUPPRESSED(peer)) {
1828 if (bgp_debug_neighbor_events(peer))
1829 flog_err(EC_BGP_FSM,
1830 "%s [FSM] Trying to start suppressed peer - this is never supposed to happen!",
1831 peer->host);
1832 if (CHECK_FLAG(peer->sflags, PEER_STATUS_RTT_SHUTDOWN))
1833 peer->last_reset = PEER_DOWN_RTT_SHUTDOWN;
1834 else if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
1835 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
1836 else if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHUTDOWN))
1837 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
1838 else if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
1839 peer->last_reset = PEER_DOWN_PFX_COUNT;
1840 return BGP_FSM_FAILURE;
1841 }
1842
1843 /* Scrub some information that might be left over from a previous,
1844 * session
1845 */
1846 /* Connection information. */
1847 if (peer->su_local) {
1848 sockunion_free(peer->su_local);
1849 peer->su_local = NULL;
1850 }
1851
1852 if (peer->su_remote) {
1853 sockunion_free(peer->su_remote);
1854 peer->su_remote = NULL;
1855 }
1856
1857 /* Clear remote router-id. */
1858 peer->remote_id.s_addr = INADDR_ANY;
1859
1860 /* Clear peer capability flag. */
1861 peer->cap = 0;
1862
1863 /* If the peer is passive mode, force to move to Active mode. */
1864 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)) {
1865 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1866 return BGP_FSM_SUCCESS;
1867 }
1868
1869 if (peer->bgp->vrf_id == VRF_UNKNOWN) {
1870 if (bgp_debug_neighbor_events(peer))
1871 flog_err(
1872 EC_BGP_FSM,
1873 "%s [FSM] In a VRF that is not initialised yet",
1874 peer->host);
1875 peer->last_reset = PEER_DOWN_VRF_UNINIT;
1876 return BGP_FSM_FAILURE;
1877 }
1878
1879 /* Register peer for NHT. If next hop is already resolved, proceed
1880 * with connection setup, else wait.
1881 */
1882 if (!bgp_peer_reg_with_nht(peer)) {
1883 if (bgp_zebra_num_connects()) {
1884 if (bgp_debug_neighbor_events(peer))
1885 zlog_debug(
1886 "%s [FSM] Waiting for NHT, no path to neighbor present",
1887 peer->host);
1888 peer->last_reset = PEER_DOWN_WAITING_NHT;
1889 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1890 return BGP_FSM_SUCCESS;
1891 }
1892 }
1893
1894 assert(!peer->t_write);
1895 assert(!peer->t_read);
1896 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
1897 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
1898 status = bgp_connect(peer);
1899
1900 switch (status) {
1901 case connect_error:
1902 if (bgp_debug_neighbor_events(peer))
1903 zlog_debug("%s [FSM] Connect error", peer->host);
1904 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1905 break;
1906 case connect_success:
1907 if (bgp_debug_neighbor_events(peer))
1908 zlog_debug(
1909 "%s [FSM] Connect immediately success, fd %d",
1910 peer->host, peer->fd);
1911
1912 BGP_EVENT_ADD(peer, TCP_connection_open);
1913 break;
1914 case connect_in_progress:
1915 /* To check nonblocking connect, we wait until socket is
1916 readable or writable. */
1917 if (bgp_debug_neighbor_events(peer))
1918 zlog_debug(
1919 "%s [FSM] Non blocking connect waiting result, fd %d",
1920 peer->host, peer->fd);
1921 if (peer->fd < 0) {
1922 flog_err(EC_BGP_FSM,
1923 "%s peer's fd is negative value %d", __func__,
1924 peer->fd);
1925 return BGP_FSM_FAILURE;
1926 }
1927 /*
1928 * - when the socket becomes ready, poll() will signify POLLOUT
1929 * - if it fails to connect, poll() will signify POLLHUP
1930 * - POLLHUP is handled as a 'read' event by thread.c
1931 *
1932 * therefore, we schedule both a read and a write event with
1933 * bgp_connect_check() as the handler for each and cancel the
1934 * unused event in that function.
1935 */
1936 thread_add_read(bm->master, bgp_connect_check, peer, peer->fd,
1937 &peer->t_connect_check_r);
1938 thread_add_write(bm->master, bgp_connect_check, peer, peer->fd,
1939 &peer->t_connect_check_w);
1940 break;
1941 }
1942 return BGP_FSM_SUCCESS;
1943 }
1944
1945 /* Connect retry timer is expired when the peer status is Connect. */
1946 static enum bgp_fsm_state_progress bgp_reconnect(struct peer *peer)
1947 {
1948 enum bgp_fsm_state_progress ret;
1949
1950 ret = bgp_stop(peer);
1951 if (ret < BGP_FSM_SUCCESS)
1952 return ret;
1953
1954 /* Send graceful restart capabilty */
1955 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
1956 peer->bgp->peer);
1957
1958 return bgp_start(peer);
1959 }
1960
1961 static enum bgp_fsm_state_progress bgp_fsm_open(struct peer *peer)
1962 {
1963 /* If DelayOpen is active, we may still need to send an open message */
1964 if ((peer->status == Connect) || (peer->status == Active))
1965 bgp_open_send(peer);
1966
1967 /* Send keepalive and make keepalive timer */
1968 bgp_keepalive_send(peer);
1969
1970 return BGP_FSM_SUCCESS;
1971 }
1972
1973 /* FSM error, unexpected event. This is error of BGP connection. So cut the
1974 peer and change to Idle status. */
1975 static enum bgp_fsm_state_progress bgp_fsm_event_error(struct peer *peer)
1976 {
1977 flog_err(EC_BGP_FSM, "%s [FSM] unexpected packet received in state %s",
1978 peer->host, lookup_msg(bgp_status_msg, peer->status, NULL));
1979
1980 return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR,
1981 bgp_fsm_error_subcode(peer->status));
1982 }
1983
1984 /* Hold timer expire. This is error of BGP connection. So cut the
1985 peer and change to Idle status. */
1986 static enum bgp_fsm_state_progress bgp_fsm_holdtime_expire(struct peer *peer)
1987 {
1988 if (bgp_debug_neighbor_events(peer))
1989 zlog_debug("%s [FSM] Hold timer expire", peer->host);
1990
1991 /* RFC8538 updates RFC 4724 by defining an extension that permits
1992 * the Graceful Restart procedures to be performed when the BGP
1993 * speaker receives a BGP NOTIFICATION message or the Hold Time expires.
1994 */
1995 if (peer_established(peer) &&
1996 bgp_has_graceful_restart_notification(peer))
1997 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE))
1998 SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
1999
2000 return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0);
2001 }
2002
2003 /* RFC 4271 DelayOpenTimer_Expires event */
2004 static enum bgp_fsm_state_progress
2005 bgp_fsm_delayopen_timer_expire(struct peer *peer)
2006 {
2007 /* Stop the DelayOpenTimer */
2008 THREAD_OFF(peer->t_delayopen);
2009
2010 /* Send open message to peer */
2011 bgp_open_send(peer);
2012
2013 /* Set the HoldTimer to a large value (4 minutes) */
2014 peer->v_holdtime = 245;
2015
2016 return BGP_FSM_SUCCESS;
2017 }
2018
2019 /* Start the selection deferral timer thread for the specified AFI, SAFI */
2020 static int bgp_start_deferral_timer(struct bgp *bgp, afi_t afi, safi_t safi,
2021 struct graceful_restart_info *gr_info)
2022 {
2023 struct afi_safi_info *thread_info;
2024
2025 /* If the deferral timer is active, then increment eor count */
2026 if (gr_info->t_select_deferral) {
2027 gr_info->eor_required++;
2028 return 0;
2029 }
2030
2031 /* Start the deferral timer when the first peer enabled for the graceful
2032 * restart is established
2033 */
2034 if (gr_info->eor_required == 0) {
2035 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
2036
2037 thread_info->afi = afi;
2038 thread_info->safi = safi;
2039 thread_info->bgp = bgp;
2040
2041 thread_add_timer(bm->master, bgp_graceful_deferral_timer_expire,
2042 thread_info, bgp->select_defer_time,
2043 &gr_info->t_select_deferral);
2044 }
2045 gr_info->eor_required++;
2046 /* Send message to RIB indicating route update pending */
2047 if (gr_info->af_enabled[afi][safi] == false) {
2048 gr_info->af_enabled[afi][safi] = true;
2049 /* Send message to RIB */
2050 bgp_zebra_update(bgp, afi, safi,
2051 ZEBRA_CLIENT_ROUTE_UPDATE_PENDING);
2052 }
2053 if (BGP_DEBUG(update, UPDATE_OUT))
2054 zlog_debug("Started the deferral timer for %s eor_required %d",
2055 get_afi_safi_str(afi, safi, false),
2056 gr_info->eor_required);
2057 return 0;
2058 }
2059
2060 /* Update the graceful restart information for the specified AFI, SAFI */
2061 static int bgp_update_gr_info(struct peer *peer, afi_t afi, safi_t safi)
2062 {
2063 struct graceful_restart_info *gr_info;
2064 struct bgp *bgp = peer->bgp;
2065 int ret = 0;
2066
2067 if ((afi < AFI_IP) || (afi >= AFI_MAX)) {
2068 if (BGP_DEBUG(update, UPDATE_OUT))
2069 zlog_debug("%s : invalid afi %d", __func__, afi);
2070 return -1;
2071 }
2072
2073 if ((safi < SAFI_UNICAST) || (safi > SAFI_MPLS_VPN)) {
2074 if (BGP_DEBUG(update, UPDATE_OUT))
2075 zlog_debug("%s : invalid safi %d", __func__, safi);
2076 return -1;
2077 }
2078
2079 /* Restarting router */
2080 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
2081 && BGP_PEER_RESTARTING_MODE(peer)) {
2082 /* Check if the forwarding state is preserved */
2083 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)) {
2084 gr_info = &(bgp->gr_info[afi][safi]);
2085 ret = bgp_start_deferral_timer(bgp, afi, safi, gr_info);
2086 }
2087 }
2088 return ret;
2089 }
2090
2091 /**
2092 * Transition to Established state.
2093 *
2094 * Convert peer from stub to full fledged peer, set some timers, and generate
2095 * initial updates.
2096 */
2097 static enum bgp_fsm_state_progress bgp_establish(struct peer *peer)
2098 {
2099 afi_t afi;
2100 safi_t safi;
2101 int nsf_af_count = 0;
2102 enum bgp_fsm_state_progress ret = BGP_FSM_SUCCESS;
2103 struct peer *other;
2104 int status;
2105
2106 other = peer->doppelganger;
2107 hash_release(peer->bgp->peerhash, peer);
2108 if (other)
2109 hash_release(peer->bgp->peerhash, other);
2110
2111 peer = peer_xfer_conn(peer);
2112 if (!peer) {
2113 flog_err(EC_BGP_CONNECT, "%%Neighbor failed in xfer_conn");
2114 return BGP_FSM_FAILURE;
2115 }
2116
2117 if (other == peer)
2118 ret = BGP_FSM_SUCCESS_STATE_TRANSFER;
2119
2120 /* Reset capability open status flag. */
2121 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
2122 SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2123
2124 /* Clear start timer value to default. */
2125 peer->v_start = BGP_INIT_START_TIMER;
2126
2127 /* Increment established count. */
2128 peer->established++;
2129 bgp_fsm_change_status(peer, Established);
2130
2131 /* bgp log-neighbor-changes of neighbor Up */
2132 if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
2133 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
2134 zlog_info("%%ADJCHANGE: neighbor %pBP in vrf %s Up", peer,
2135 vrf ? ((vrf->vrf_id != VRF_DEFAULT)
2136 ? vrf->name
2137 : VRF_DEFAULT_NAME)
2138 : "");
2139 }
2140 /* assign update-group/subgroup */
2141 update_group_adjust_peer_afs(peer);
2142
2143 /* graceful restart */
2144 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
2145 if (bgp_debug_neighbor_events(peer)) {
2146 if (BGP_PEER_RESTARTING_MODE(peer))
2147 zlog_debug("%pBP BGP_RESTARTING_MODE", peer);
2148 else if (BGP_PEER_HELPER_MODE(peer))
2149 zlog_debug("%pBP BGP_HELPER_MODE", peer);
2150 }
2151
2152 FOREACH_AFI_SAFI_NSF (afi, safi) {
2153 if (peer->afc_nego[afi][safi] &&
2154 CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV) &&
2155 CHECK_FLAG(peer->af_cap[afi][safi],
2156 PEER_CAP_RESTART_AF_RCV)) {
2157 if (peer->nsf[afi][safi] &&
2158 !CHECK_FLAG(peer->af_cap[afi][safi],
2159 PEER_CAP_RESTART_AF_PRESERVE_RCV))
2160 bgp_clear_stale_route(peer, afi, safi);
2161
2162 peer->nsf[afi][safi] = 1;
2163 nsf_af_count++;
2164 } else {
2165 if (peer->nsf[afi][safi])
2166 bgp_clear_stale_route(peer, afi, safi);
2167 peer->nsf[afi][safi] = 0;
2168 }
2169 /* Update the graceful restart information */
2170 if (peer->afc_nego[afi][safi]) {
2171 if (!BGP_SELECT_DEFER_DISABLE(peer->bgp)) {
2172 status = bgp_update_gr_info(peer, afi, safi);
2173 if (status < 0)
2174 zlog_err(
2175 "Error in updating graceful restart for %s",
2176 get_afi_safi_str(afi, safi,
2177 false));
2178 } else {
2179 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer) &&
2180 BGP_PEER_RESTARTING_MODE(peer) &&
2181 CHECK_FLAG(peer->bgp->flags,
2182 BGP_FLAG_GR_PRESERVE_FWD))
2183 peer->bgp->gr_info[afi][safi]
2184 .eor_required++;
2185 }
2186 }
2187 }
2188
2189 if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
2190 if ((bgp_peer_gr_mode_get(peer) == PEER_GR)
2191 || ((bgp_peer_gr_mode_get(peer) == PEER_GLOBAL_INHERIT)
2192 && (bgp_global_gr_mode_get(peer->bgp) == GLOBAL_GR))) {
2193 FOREACH_AFI_SAFI (afi, safi)
2194 /* Send route processing complete
2195 message to RIB */
2196 bgp_zebra_update(
2197 peer->bgp, afi, safi,
2198 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2199 }
2200 } else {
2201 /* Peer sends R-bit. In this case, we need to send
2202 * ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE to Zebra. */
2203 if (CHECK_FLAG(peer->cap,
2204 PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV)) {
2205 FOREACH_AFI_SAFI (afi, safi)
2206 /* Send route processing complete
2207 message to RIB */
2208 bgp_zebra_update(
2209 peer->bgp, afi, safi,
2210 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2211 }
2212 }
2213
2214 peer->nsf_af_count = nsf_af_count;
2215
2216 if (nsf_af_count)
2217 SET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
2218 else {
2219 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
2220 if (peer->t_gr_stale) {
2221 THREAD_OFF(peer->t_gr_stale);
2222 if (bgp_debug_neighbor_events(peer))
2223 zlog_debug(
2224 "%pBP graceful restart stalepath timer stopped",
2225 peer);
2226 }
2227 }
2228
2229 if (peer->t_gr_restart) {
2230 THREAD_OFF(peer->t_gr_restart);
2231 if (bgp_debug_neighbor_events(peer))
2232 zlog_debug("%pBP graceful restart timer stopped", peer);
2233 }
2234
2235 /* Reset uptime, turn on keepalives, send current table. */
2236 if (!peer->v_holdtime)
2237 bgp_keepalives_on(peer);
2238
2239 peer->uptime = monotime(NULL);
2240
2241 /* Send route-refresh when ORF is enabled.
2242 * Stop Long-lived Graceful Restart timers.
2243 */
2244 FOREACH_AFI_SAFI (afi, safi) {
2245 if (peer->t_llgr_stale[afi][safi]) {
2246 THREAD_OFF(peer->t_llgr_stale[afi][safi]);
2247 if (bgp_debug_neighbor_events(peer))
2248 zlog_debug(
2249 "%pBP Long-lived stale timer stopped for afi/safi: %d/%d",
2250 peer, afi, safi);
2251 }
2252
2253 if (CHECK_FLAG(peer->af_cap[afi][safi],
2254 PEER_CAP_ORF_PREFIX_SM_ADV)) {
2255 if (CHECK_FLAG(peer->af_cap[afi][safi],
2256 PEER_CAP_ORF_PREFIX_RM_RCV))
2257 bgp_route_refresh_send(
2258 peer, afi, safi, ORF_TYPE_PREFIX,
2259 REFRESH_IMMEDIATE, 0,
2260 BGP_ROUTE_REFRESH_NORMAL);
2261 else if (CHECK_FLAG(peer->af_cap[afi][safi],
2262 PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
2263 bgp_route_refresh_send(
2264 peer, afi, safi, ORF_TYPE_PREFIX_OLD,
2265 REFRESH_IMMEDIATE, 0,
2266 BGP_ROUTE_REFRESH_NORMAL);
2267 }
2268 }
2269
2270 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2271 FOREACH_AFI_SAFI (afi, safi) {
2272 if (CHECK_FLAG(peer->af_cap[afi][safi],
2273 PEER_CAP_ORF_PREFIX_RM_ADV))
2274 if (CHECK_FLAG(peer->af_cap[afi][safi],
2275 PEER_CAP_ORF_PREFIX_SM_RCV)
2276 || CHECK_FLAG(peer->af_cap[afi][safi],
2277 PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
2278 SET_FLAG(peer->af_sflags[afi][safi],
2279 PEER_STATUS_ORF_WAIT_REFRESH);
2280 }
2281
2282 bgp_announce_peer(peer);
2283
2284 /* Start the route advertisement timer to send updates to the peer - if
2285 * BGP
2286 * is not in read-only mode. If it is, the timer will be started at the
2287 * end
2288 * of read-only mode.
2289 */
2290 if (!bgp_update_delay_active(peer->bgp)) {
2291 THREAD_OFF(peer->t_routeadv);
2292 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
2293 }
2294
2295 if (peer->doppelganger && (peer->doppelganger->status != Deleted)) {
2296 if (bgp_debug_neighbor_events(peer))
2297 zlog_debug(
2298 "[Event] Deleting stub connection for peer %s",
2299 peer->host);
2300
2301 if (peer->doppelganger->status > Active)
2302 bgp_notify_send(peer->doppelganger, BGP_NOTIFY_CEASE,
2303 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
2304 else
2305 peer_delete(peer->doppelganger);
2306 }
2307
2308 /*
2309 * If we are replacing the old peer for a doppelganger
2310 * then switch it around in the bgp->peerhash
2311 * the doppelgangers su and this peer's su are the same
2312 * so the hash_release is the same for either.
2313 */
2314 (void)hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
2315
2316 /* Start BFD peer if not already running. */
2317 if (peer->bfd_config)
2318 bgp_peer_bfd_update_source(peer);
2319
2320 return ret;
2321 }
2322
2323 /* Keepalive packet is received. */
2324 static enum bgp_fsm_state_progress bgp_fsm_keepalive(struct peer *peer)
2325 {
2326 THREAD_OFF(peer->t_holdtime);
2327 return BGP_FSM_SUCCESS;
2328 }
2329
2330 /* Update packet is received. */
2331 static enum bgp_fsm_state_progress bgp_fsm_update(struct peer *peer)
2332 {
2333 THREAD_OFF(peer->t_holdtime);
2334 return BGP_FSM_SUCCESS;
2335 }
2336
2337 /* This is empty event. */
2338 static enum bgp_fsm_state_progress bgp_ignore(struct peer *peer)
2339 {
2340 flog_err(
2341 EC_BGP_FSM,
2342 "%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d",
2343 peer->host, bgp_event_str[peer->cur_event],
2344 lookup_msg(bgp_status_msg, peer->status, NULL),
2345 bgp_event_str[peer->last_event],
2346 bgp_event_str[peer->last_major_event], peer->fd);
2347 return BGP_FSM_SUCCESS;
2348 }
2349
2350 /* This is to handle unexpected events.. */
2351 static enum bgp_fsm_state_progress bgp_fsm_exception(struct peer *peer)
2352 {
2353 flog_err(
2354 EC_BGP_FSM,
2355 "%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d",
2356 peer->host, bgp_event_str[peer->cur_event],
2357 lookup_msg(bgp_status_msg, peer->status, NULL),
2358 bgp_event_str[peer->last_event],
2359 bgp_event_str[peer->last_major_event], peer->fd);
2360 return bgp_stop(peer);
2361 }
2362
2363 void bgp_fsm_nht_update(struct peer *peer, bool has_valid_nexthops)
2364 {
2365 if (!peer)
2366 return;
2367
2368 switch (peer->status) {
2369 case Idle:
2370 if (has_valid_nexthops)
2371 BGP_EVENT_ADD(peer, BGP_Start);
2372 break;
2373 case Connect:
2374 if (!has_valid_nexthops) {
2375 THREAD_OFF(peer->t_connect);
2376 BGP_EVENT_ADD(peer, TCP_fatal_error);
2377 }
2378 break;
2379 case Active:
2380 if (has_valid_nexthops) {
2381 THREAD_OFF(peer->t_connect);
2382 BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
2383 }
2384 break;
2385 case OpenSent:
2386 case OpenConfirm:
2387 case Established:
2388 if (!has_valid_nexthops
2389 && (peer->gtsm_hops == BGP_GTSM_HOPS_CONNECTED
2390 || peer->bgp->fast_convergence))
2391 BGP_EVENT_ADD(peer, TCP_fatal_error);
2392 case Clearing:
2393 case Deleted:
2394 case BGP_STATUS_MAX:
2395 break;
2396 }
2397 }
2398
2399 /* Finite State Machine structure */
2400 static const struct {
2401 enum bgp_fsm_state_progress (*func)(struct peer *);
2402 enum bgp_fsm_status next_state;
2403 } FSM[BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] = {
2404 {
2405 /* Idle state: In Idle state, all events other than BGP_Start is
2406 ignored. With BGP_Start event, finite state machine calls
2407 bgp_start(). */
2408 {bgp_start, Connect}, /* BGP_Start */
2409 {bgp_stop, Idle}, /* BGP_Stop */
2410 {bgp_stop, Idle}, /* TCP_connection_open */
2411 {bgp_stop, Idle}, /* TCP_connection_open_w_delay */
2412 {bgp_stop, Idle}, /* TCP_connection_closed */
2413 {bgp_ignore, Idle}, /* TCP_connection_open_failed */
2414 {bgp_stop, Idle}, /* TCP_fatal_error */
2415 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
2416 {bgp_ignore, Idle}, /* Hold_Timer_expired */
2417 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
2418 {bgp_ignore, Idle}, /* DelayOpen_timer_expired */
2419 {bgp_ignore, Idle}, /* Receive_OPEN_message */
2420 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
2421 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
2422 {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
2423 {bgp_ignore, Idle}, /* Clearing_Completed */
2424 },
2425 {
2426 /* Connect */
2427 {bgp_ignore, Connect}, /* BGP_Start */
2428 {bgp_stop, Idle}, /* BGP_Stop */
2429 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
2430 {bgp_connect_success_w_delayopen,
2431 Connect}, /* TCP_connection_open_w_delay */
2432 {bgp_stop, Idle}, /* TCP_connection_closed */
2433 {bgp_connect_fail, Active}, /* TCP_connection_open_failed */
2434 {bgp_connect_fail, Idle}, /* TCP_fatal_error */
2435 {bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
2436 {bgp_fsm_exception, Idle}, /* Hold_Timer_expired */
2437 {bgp_fsm_exception, Idle}, /* KeepAlive_timer_expired */
2438 {bgp_fsm_delayopen_timer_expire,
2439 OpenSent}, /* DelayOpen_timer_expired */
2440 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
2441 {bgp_fsm_exception, Idle}, /* Receive_KEEPALIVE_message */
2442 {bgp_fsm_exception, Idle}, /* Receive_UPDATE_message */
2443 {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
2444 {bgp_fsm_exception, Idle}, /* Clearing_Completed */
2445 },
2446 {
2447 /* Active, */
2448 {bgp_ignore, Active}, /* BGP_Start */
2449 {bgp_stop, Idle}, /* BGP_Stop */
2450 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
2451 {bgp_connect_success_w_delayopen,
2452 Active}, /* TCP_connection_open_w_delay */
2453 {bgp_stop, Idle}, /* TCP_connection_closed */
2454 {bgp_ignore, Active}, /* TCP_connection_open_failed */
2455 {bgp_fsm_exception, Idle}, /* TCP_fatal_error */
2456 {bgp_start, Connect}, /* ConnectRetry_timer_expired */
2457 {bgp_fsm_exception, Idle}, /* Hold_Timer_expired */
2458 {bgp_fsm_exception, Idle}, /* KeepAlive_timer_expired */
2459 {bgp_fsm_delayopen_timer_expire,
2460 OpenSent}, /* DelayOpen_timer_expired */
2461 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
2462 {bgp_fsm_exception, Idle}, /* Receive_KEEPALIVE_message */
2463 {bgp_fsm_exception, Idle}, /* Receive_UPDATE_message */
2464 {bgp_fsm_exception, Idle}, /* Receive_NOTIFICATION_message */
2465 {bgp_fsm_exception, Idle}, /* Clearing_Completed */
2466 },
2467 {
2468 /* OpenSent, */
2469 {bgp_ignore, OpenSent}, /* BGP_Start */
2470 {bgp_stop, Idle}, /* BGP_Stop */
2471 {bgp_stop, Active}, /* TCP_connection_open */
2472 {bgp_fsm_exception, Idle}, /* TCP_connection_open_w_delay */
2473 {bgp_stop, Active}, /* TCP_connection_closed */
2474 {bgp_stop, Active}, /* TCP_connection_open_failed */
2475 {bgp_stop, Active}, /* TCP_fatal_error */
2476 {bgp_fsm_exception, Idle}, /* ConnectRetry_timer_expired */
2477 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
2478 {bgp_fsm_exception, Idle}, /* KeepAlive_timer_expired */
2479 {bgp_fsm_exception, Idle}, /* DelayOpen_timer_expired */
2480 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
2481 {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
2482 {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
2483 {bgp_fsm_event_error, Idle}, /* Receive_NOTIFICATION_message */
2484 {bgp_fsm_exception, Idle}, /* Clearing_Completed */
2485 },
2486 {
2487 /* OpenConfirm, */
2488 {bgp_ignore, OpenConfirm}, /* BGP_Start */
2489 {bgp_stop, Idle}, /* BGP_Stop */
2490 {bgp_stop, Idle}, /* TCP_connection_open */
2491 {bgp_fsm_exception, Idle}, /* TCP_connection_open_w_delay */
2492 {bgp_stop, Idle}, /* TCP_connection_closed */
2493 {bgp_stop, Idle}, /* TCP_connection_open_failed */
2494 {bgp_stop, Idle}, /* TCP_fatal_error */
2495 {bgp_fsm_exception, Idle}, /* ConnectRetry_timer_expired */
2496 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
2497 {bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
2498 {bgp_fsm_exception, Idle}, /* DelayOpen_timer_expired */
2499 {bgp_fsm_exception, Idle}, /* Receive_OPEN_message */
2500 {bgp_establish, Established}, /* Receive_KEEPALIVE_message */
2501 {bgp_fsm_exception, Idle}, /* Receive_UPDATE_message */
2502 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
2503 {bgp_fsm_exception, Idle}, /* Clearing_Completed */
2504 },
2505 {
2506 /* Established, */
2507 {bgp_ignore, Established}, /* BGP_Start */
2508 {bgp_stop, Clearing}, /* BGP_Stop */
2509 {bgp_stop, Clearing}, /* TCP_connection_open */
2510 {bgp_fsm_exception, Idle}, /* TCP_connection_open_w_delay */
2511 {bgp_stop, Clearing}, /* TCP_connection_closed */
2512 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
2513 {bgp_stop, Clearing}, /* TCP_fatal_error */
2514 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
2515 {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
2516 {bgp_ignore, Established}, /* KeepAlive_timer_expired */
2517 {bgp_fsm_exception, Idle}, /* DelayOpen_timer_expired */
2518 {bgp_stop, Clearing}, /* Receive_OPEN_message */
2519 {bgp_fsm_keepalive,
2520 Established}, /* Receive_KEEPALIVE_message */
2521 {bgp_fsm_update, Established}, /* Receive_UPDATE_message */
2522 {bgp_stop_with_error,
2523 Clearing}, /* Receive_NOTIFICATION_message */
2524 {bgp_fsm_exception, Idle}, /* Clearing_Completed */
2525 },
2526 {
2527 /* Clearing, */
2528 {bgp_ignore, Clearing}, /* BGP_Start */
2529 {bgp_stop, Clearing}, /* BGP_Stop */
2530 {bgp_stop, Clearing}, /* TCP_connection_open */
2531 {bgp_stop, Clearing}, /* TCP_connection_open_w_delay */
2532 {bgp_stop, Clearing}, /* TCP_connection_closed */
2533 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
2534 {bgp_stop, Clearing}, /* TCP_fatal_error */
2535 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
2536 {bgp_stop, Clearing}, /* Hold_Timer_expired */
2537 {bgp_stop, Clearing}, /* KeepAlive_timer_expired */
2538 {bgp_stop, Clearing}, /* DelayOpen_timer_expired */
2539 {bgp_stop, Clearing}, /* Receive_OPEN_message */
2540 {bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
2541 {bgp_stop, Clearing}, /* Receive_UPDATE_message */
2542 {bgp_stop, Clearing}, /* Receive_NOTIFICATION_message */
2543 {bgp_clearing_completed, Idle}, /* Clearing_Completed */
2544 },
2545 {
2546 /* Deleted, */
2547 {bgp_ignore, Deleted}, /* BGP_Start */
2548 {bgp_ignore, Deleted}, /* BGP_Stop */
2549 {bgp_ignore, Deleted}, /* TCP_connection_open */
2550 {bgp_ignore, Deleted}, /* TCP_connection_open_w_delay */
2551 {bgp_ignore, Deleted}, /* TCP_connection_closed */
2552 {bgp_ignore, Deleted}, /* TCP_connection_open_failed */
2553 {bgp_ignore, Deleted}, /* TCP_fatal_error */
2554 {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
2555 {bgp_ignore, Deleted}, /* Hold_Timer_expired */
2556 {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
2557 {bgp_ignore, Deleted}, /* DelayOpen_timer_expired */
2558 {bgp_ignore, Deleted}, /* Receive_OPEN_message */
2559 {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
2560 {bgp_ignore, Deleted}, /* Receive_UPDATE_message */
2561 {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */
2562 {bgp_ignore, Deleted}, /* Clearing_Completed */
2563 },
2564 };
2565
2566 /* Execute event process. */
2567 void bgp_event(struct thread *thread)
2568 {
2569 enum bgp_fsm_events event;
2570 struct peer *peer;
2571
2572 peer = THREAD_ARG(thread);
2573 event = THREAD_VAL(thread);
2574
2575 peer_lock(peer);
2576 bgp_event_update(peer, event);
2577 peer_unlock(peer);
2578 }
2579
2580 int bgp_event_update(struct peer *peer, enum bgp_fsm_events event)
2581 {
2582 enum bgp_fsm_status next;
2583 enum bgp_fsm_state_progress ret = 0;
2584 struct peer *other;
2585 int passive_conn = 0;
2586 int dyn_nbr;
2587
2588 /* default return code */
2589 ret = FSM_PEER_NOOP;
2590
2591 other = peer->doppelganger;
2592 passive_conn =
2593 (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) ? 1 : 0;
2594 dyn_nbr = peer_dynamic_neighbor(peer);
2595
2596 /* Logging this event. */
2597 next = FSM[peer->status - 1][event - 1].next_state;
2598
2599 if (bgp_debug_neighbor_events(peer) && peer->status != next)
2600 zlog_debug("%s [FSM] %s (%s->%s), fd %d", peer->host,
2601 bgp_event_str[event],
2602 lookup_msg(bgp_status_msg, peer->status, NULL),
2603 lookup_msg(bgp_status_msg, next, NULL), peer->fd);
2604
2605 peer->last_event = peer->cur_event;
2606 peer->cur_event = event;
2607
2608 /* Call function. */
2609 if (FSM[peer->status - 1][event - 1].func)
2610 ret = (*(FSM[peer->status - 1][event - 1].func))(peer);
2611
2612 if (ret >= BGP_FSM_SUCCESS) {
2613 if (ret == BGP_FSM_SUCCESS_STATE_TRANSFER &&
2614 next == Established) {
2615 /* The case when doppelganger swap accurred in
2616 bgp_establish.
2617 Update the peer pointer accordingly */
2618 ret = FSM_PEER_TRANSFERRED;
2619 peer = other;
2620 }
2621
2622 /* If status is changed. */
2623 if (next != peer->status) {
2624 bgp_fsm_change_status(peer, next);
2625
2626 /*
2627 * If we're going to ESTABLISHED then we executed a
2628 * peer transfer. In this case we can either return
2629 * FSM_PEER_TRANSITIONED or FSM_PEER_TRANSFERRED.
2630 * Opting for TRANSFERRED since transfer implies
2631 * session establishment.
2632 */
2633 if (ret != FSM_PEER_TRANSFERRED)
2634 ret = FSM_PEER_TRANSITIONED;
2635 }
2636
2637 /* Make sure timer is set. */
2638 bgp_timer_set(peer);
2639
2640 } else {
2641 /*
2642 * If we got a return value of -1, that means there was an
2643 * error, restart the FSM. Since bgp_stop() was called on the
2644 * peer. only a few fields are safe to access here. In any case
2645 * we need to indicate that the peer was stopped in the return
2646 * code.
2647 */
2648 if (!dyn_nbr && !passive_conn && peer->bgp &&
2649 ret != BGP_FSM_FAILURE_AND_DELETE) {
2650 flog_err(
2651 EC_BGP_FSM,
2652 "%s [FSM] Failure handling event %s in state %s, prior events %s, %s, fd %d",
2653 peer->host, bgp_event_str[peer->cur_event],
2654 lookup_msg(bgp_status_msg, peer->status, NULL),
2655 bgp_event_str[peer->last_event],
2656 bgp_event_str[peer->last_major_event],
2657 peer->fd);
2658 bgp_stop(peer);
2659 bgp_fsm_change_status(peer, Idle);
2660 bgp_timer_set(peer);
2661 }
2662 ret = FSM_PEER_STOPPED;
2663 }
2664
2665 return ret;
2666 }
2667 /* BGP GR Code */
2668
2669 int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp,
2670 enum global_mode global_new_state,
2671 enum global_mode global_old_state)
2672 {
2673 struct peer *peer = {0};
2674 struct listnode *node = {0};
2675 struct listnode *nnode = {0};
2676 enum peer_mode peer_old_state = PEER_INVALID;
2677
2678 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
2679
2680 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2681 zlog_debug("%s [BGP_GR] Peer: (%s) :", __func__,
2682 peer->host);
2683
2684 peer_old_state = bgp_peer_gr_mode_get(peer);
2685
2686 if (peer_old_state == PEER_GLOBAL_INHERIT) {
2687
2688 /*
2689 *Reset only these peers and send a
2690 *new open message with the change capabilities.
2691 *Considering the mode to be "global_new_state" and
2692 *do all operation accordingly
2693 */
2694
2695 switch (global_new_state) {
2696 case GLOBAL_HELPER:
2697 BGP_PEER_GR_HELPER_ENABLE(peer);
2698 break;
2699 case GLOBAL_GR:
2700 BGP_PEER_GR_ENABLE(peer);
2701 break;
2702 case GLOBAL_DISABLE:
2703 BGP_PEER_GR_DISABLE(peer);
2704 break;
2705 case GLOBAL_INVALID:
2706 zlog_debug("%s [BGP_GR] GLOBAL_INVALID",
2707 __func__);
2708 return BGP_ERR_GR_OPERATION_FAILED;
2709 }
2710 }
2711 }
2712
2713 bgp->global_gr_present_state = global_new_state;
2714
2715 return BGP_GR_SUCCESS;
2716 }
2717
2718 int bgp_gr_update_all(struct bgp *bgp, int global_gr_cmd)
2719 {
2720 enum global_mode global_new_state = GLOBAL_INVALID;
2721 enum global_mode global_old_state = GLOBAL_INVALID;
2722
2723 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2724 zlog_debug("%s [BGP_GR]START: global_gr_cmd :%s:", __func__,
2725 print_global_gr_cmd(global_gr_cmd));
2726
2727 global_old_state = bgp_global_gr_mode_get(bgp);
2728
2729 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2730 zlog_debug("[BGP_GR] global_old_gr_state :%s:",
2731 print_global_gr_mode(global_old_state));
2732
2733 if (global_old_state != GLOBAL_INVALID) {
2734 global_new_state =
2735 bgp->GLOBAL_GR_FSM[global_old_state][global_gr_cmd];
2736
2737 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2738 zlog_debug("[BGP_GR] global_new_gr_state :%s:",
2739 print_global_gr_mode(global_new_state));
2740 } else {
2741 zlog_err("%s [BGP_GR] global_old_state == GLOBAL_INVALID",
2742 __func__);
2743 return BGP_ERR_GR_OPERATION_FAILED;
2744 }
2745
2746 if (global_new_state == GLOBAL_INVALID) {
2747 zlog_err("%s [BGP_GR] global_new_state == GLOBAL_INVALID",
2748 __func__);
2749 return BGP_ERR_GR_INVALID_CMD;
2750 }
2751 if (global_new_state == global_old_state) {
2752 /* Trace msg */
2753 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2754 zlog_debug(
2755 "%s [BGP_GR] global_new_state == global_old_state :%s",
2756 __func__,
2757 print_global_gr_mode(global_new_state));
2758 return BGP_GR_NO_OPERATION;
2759 }
2760
2761 return bgp_gr_lookup_n_update_all_peer(bgp, global_new_state,
2762 global_old_state);
2763 }
2764
2765 const char *print_peer_gr_mode(enum peer_mode pr_mode)
2766 {
2767 const char *peer_gr_mode = NULL;
2768
2769 switch (pr_mode) {
2770 case PEER_HELPER:
2771 peer_gr_mode = "PEER_HELPER";
2772 break;
2773 case PEER_GR:
2774 peer_gr_mode = "PEER_GR";
2775 break;
2776 case PEER_DISABLE:
2777 peer_gr_mode = "PEER_DISABLE";
2778 break;
2779 case PEER_INVALID:
2780 peer_gr_mode = "PEER_INVALID";
2781 break;
2782 case PEER_GLOBAL_INHERIT:
2783 peer_gr_mode = "PEER_GLOBAL_INHERIT";
2784 break;
2785 }
2786
2787 return peer_gr_mode;
2788 }
2789
2790 const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd)
2791 {
2792 const char *peer_gr_cmd = NULL;
2793
2794 switch (pr_gr_cmd) {
2795 case PEER_GR_CMD:
2796 peer_gr_cmd = "PEER_GR_CMD";
2797 break;
2798 case NO_PEER_GR_CMD:
2799 peer_gr_cmd = "NO_PEER_GR_CMD";
2800 break;
2801 case PEER_DISABLE_CMD:
2802 peer_gr_cmd = "PEER_DISABLE_GR_CMD";
2803 break;
2804 case NO_PEER_DISABLE_CMD:
2805 peer_gr_cmd = "NO_PEER_DISABLE_GR_CMD";
2806 break;
2807 case PEER_HELPER_CMD:
2808 peer_gr_cmd = "PEER_HELPER_CMD";
2809 break;
2810 case NO_PEER_HELPER_CMD:
2811 peer_gr_cmd = "NO_PEER_HELPER_CMD";
2812 break;
2813 }
2814
2815 return peer_gr_cmd;
2816 }
2817
2818 const char *print_global_gr_mode(enum global_mode gl_mode)
2819 {
2820 const char *global_gr_mode = NULL;
2821
2822 switch (gl_mode) {
2823 case GLOBAL_HELPER:
2824 global_gr_mode = "GLOBAL_HELPER";
2825 break;
2826 case GLOBAL_GR:
2827 global_gr_mode = "GLOBAL_GR";
2828 break;
2829 case GLOBAL_DISABLE:
2830 global_gr_mode = "GLOBAL_DISABLE";
2831 break;
2832 case GLOBAL_INVALID:
2833 global_gr_mode = "GLOBAL_INVALID";
2834 break;
2835 }
2836
2837 return global_gr_mode;
2838 }
2839
2840 const char *print_global_gr_cmd(enum global_gr_command gl_gr_cmd)
2841 {
2842 const char *global_gr_cmd = NULL;
2843
2844 switch (gl_gr_cmd) {
2845 case GLOBAL_GR_CMD:
2846 global_gr_cmd = "GLOBAL_GR_CMD";
2847 break;
2848 case NO_GLOBAL_GR_CMD:
2849 global_gr_cmd = "NO_GLOBAL_GR_CMD";
2850 break;
2851 case GLOBAL_DISABLE_CMD:
2852 global_gr_cmd = "GLOBAL_DISABLE_CMD";
2853 break;
2854 case NO_GLOBAL_DISABLE_CMD:
2855 global_gr_cmd = "NO_GLOBAL_DISABLE_CMD";
2856 break;
2857 }
2858
2859 return global_gr_cmd;
2860 }
2861
2862 enum global_mode bgp_global_gr_mode_get(struct bgp *bgp)
2863 {
2864 return bgp->global_gr_present_state;
2865 }
2866
2867 enum peer_mode bgp_peer_gr_mode_get(struct peer *peer)
2868 {
2869 return peer->peer_gr_present_state;
2870 }
2871
2872 int bgp_neighbor_graceful_restart(struct peer *peer, int peer_gr_cmd)
2873 {
2874 enum peer_mode peer_new_state = PEER_INVALID;
2875 enum peer_mode peer_old_state = PEER_INVALID;
2876 struct bgp_peer_gr peer_state;
2877 int result = BGP_GR_FAILURE;
2878
2879 /*
2880 * fetch peer_old_state from peer structure also
2881 * fetch global_old_state from bgp structure,
2882 * peer had a back pointer to bgpo struct ;
2883 */
2884
2885 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2886 zlog_debug("%s [BGP_GR] START:Peer: (%s) : peer_gr_cmd :%s:",
2887 __func__, peer->host,
2888 print_peer_gr_cmd(peer_gr_cmd));
2889
2890 peer_old_state = bgp_peer_gr_mode_get(peer);
2891
2892 if (peer_old_state == PEER_INVALID) {
2893 zlog_debug("[BGP_GR] peer_old_state == Invalid state !");
2894 return BGP_ERR_GR_OPERATION_FAILED;
2895 }
2896
2897 peer_state = peer->PEER_GR_FSM[peer_old_state][peer_gr_cmd];
2898 peer_new_state = peer_state.next_state;
2899
2900 if (peer_new_state == PEER_INVALID) {
2901 zlog_debug(
2902 "[BGP_GR] Invalid bgp graceful restart command used !");
2903 return BGP_ERR_GR_INVALID_CMD;
2904 }
2905
2906 if (peer_new_state != peer_old_state) {
2907 result = peer_state.action_fun(peer, peer_old_state,
2908 peer_new_state);
2909 } else {
2910 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2911 zlog_debug(
2912 "[BGP_GR] peer_old_state == peer_new_state !");
2913 return BGP_GR_NO_OPERATION;
2914 }
2915
2916 if (result == BGP_GR_SUCCESS) {
2917
2918 /* Update the mode i.e peer_new_state into the peer structure */
2919 peer->peer_gr_present_state = peer_new_state;
2920 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2921 zlog_debug(
2922 "[BGP_GR] Successfully change the state of the peer to : %s : !",
2923 print_peer_gr_mode(peer_new_state));
2924
2925 return BGP_GR_SUCCESS;
2926 }
2927
2928 return result;
2929 }
2930
2931 unsigned int bgp_peer_gr_action(struct peer *peer, int old_peer_state,
2932 int new_peer_state)
2933 {
2934 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2935 zlog_debug(
2936 "%s [BGP_GR] Move peer from old_peer_state :%s: to new_peer_state :%s: !!!!",
2937 __func__, print_peer_gr_mode(old_peer_state),
2938 print_peer_gr_mode(new_peer_state));
2939
2940 int bgp_gr_global_mode = GLOBAL_INVALID;
2941 unsigned int ret = BGP_GR_FAILURE;
2942
2943 if (old_peer_state == new_peer_state) {
2944 /* Nothing to do over here as the present and old state is the
2945 * same */
2946 return BGP_GR_NO_OPERATION;
2947 }
2948 if ((old_peer_state == PEER_INVALID)
2949 || (new_peer_state == PEER_INVALID)) {
2950 /* something bad happend , print error message */
2951 return BGP_ERR_GR_INVALID_CMD;
2952 }
2953
2954 bgp_gr_global_mode = bgp_global_gr_mode_get(peer->bgp);
2955
2956 if ((old_peer_state == PEER_GLOBAL_INHERIT)
2957 && (new_peer_state != PEER_GLOBAL_INHERIT)) {
2958
2959 /* fetch the Mode running in the Global state machine
2960 *from the bgp structure into a variable called
2961 *bgp_gr_global_mode
2962 */
2963
2964 /* Here we are checking if the
2965 *1. peer_new_state == global_mode == helper_mode
2966 *2. peer_new_state == global_mode == GR_mode
2967 *3. peer_new_state == global_mode == disabled_mode
2968 */
2969
2970 BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer);
2971
2972 if (new_peer_state == bgp_gr_global_mode) {
2973 /*This is incremental updates i.e no tear down
2974 *of the existing session
2975 *as the peer is already working in the same mode.
2976 */
2977 ret = BGP_GR_SUCCESS;
2978 } else {
2979 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2980 zlog_debug(
2981 "[BGP_GR] Peer state changed from :%s ",
2982 print_peer_gr_mode(old_peer_state));
2983
2984 bgp_peer_move_to_gr_mode(peer, new_peer_state);
2985
2986 ret = BGP_GR_SUCCESS;
2987 }
2988 }
2989 /* In the case below peer is going into Global inherit mode i.e.
2990 * the peer would work as the mode configured at the global level
2991 */
2992 else if ((new_peer_state == PEER_GLOBAL_INHERIT)
2993 && (old_peer_state != PEER_GLOBAL_INHERIT)) {
2994 /* Here in this case it would be destructive
2995 * in all the cases except one case when,
2996 * Global GR is configured Disabled
2997 * and present_peer_state is not disable
2998 */
2999
3000 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
3001
3002 if (old_peer_state == bgp_gr_global_mode) {
3003
3004 /* This is incremental updates
3005 *i.e no tear down of the existing session
3006 *as the peer is already working in the same mode.
3007 */
3008 ret = BGP_GR_SUCCESS;
3009 } else {
3010 /* Destructive always */
3011 /* Tear down the old session
3012 * and send the new capability
3013 * as per the bgp_gr_global_mode
3014 */
3015
3016 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3017 zlog_debug(
3018 "[BGP_GR] Peer state changed from :%s",
3019 print_peer_gr_mode(old_peer_state));
3020
3021 bgp_peer_move_to_gr_mode(peer, bgp_gr_global_mode);
3022
3023 ret = BGP_GR_SUCCESS;
3024 }
3025 } else {
3026 /*
3027 *This else case, it include all the cases except -->
3028 *(new_peer_state != Peer_Global) &&
3029 *( old_peer_state != Peer_Global )
3030 */
3031 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3032 zlog_debug("[BGP_GR] Peer state changed from :%s",
3033 print_peer_gr_mode(old_peer_state));
3034
3035 bgp_peer_move_to_gr_mode(peer, new_peer_state);
3036
3037 ret = BGP_GR_SUCCESS;
3038 }
3039
3040 return ret;
3041 }
3042
3043 inline void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state)
3044
3045 {
3046 int bgp_global_gr_mode = bgp_global_gr_mode_get(peer->bgp);
3047
3048 switch (new_state) {
3049 case PEER_HELPER:
3050 BGP_PEER_GR_HELPER_ENABLE(peer);
3051 break;
3052 case PEER_GR:
3053 BGP_PEER_GR_ENABLE(peer);
3054 break;
3055 case PEER_DISABLE:
3056 BGP_PEER_GR_DISABLE(peer);
3057 break;
3058 case PEER_GLOBAL_INHERIT:
3059 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
3060
3061 if (bgp_global_gr_mode == GLOBAL_HELPER) {
3062 BGP_PEER_GR_HELPER_ENABLE(peer);
3063 } else if (bgp_global_gr_mode == GLOBAL_GR) {
3064 BGP_PEER_GR_ENABLE(peer);
3065 } else if (bgp_global_gr_mode == GLOBAL_DISABLE) {
3066 BGP_PEER_GR_DISABLE(peer);
3067 } else {
3068 zlog_err(
3069 "[BGP_GR] Default switch inherit mode ::: SOMETHING IS WRONG !!!");
3070 }
3071 break;
3072 default:
3073 zlog_err(
3074 "[BGP_GR] Default switch mode ::: SOMETHING IS WRONG !!!");
3075 break;
3076 }
3077 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3078 zlog_debug("[BGP_GR] Peer state changed --to--> : %d : !",
3079 new_state);
3080 }
3081
3082 void bgp_peer_gr_flags_update(struct peer *peer)
3083 {
3084 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3085 zlog_debug("%s [BGP_GR] called !", __func__);
3086 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
3087 PEER_GRACEFUL_RESTART_NEW_STATE_HELPER))
3088 SET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER);
3089 else
3090 UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER);
3091 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3092 zlog_debug(
3093 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !",
3094 peer->host,
3095 (CHECK_FLAG(peer->flags,
3096 PEER_FLAG_GRACEFUL_RESTART_HELPER)
3097 ? "Set"
3098 : "UnSet"));
3099 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
3100 PEER_GRACEFUL_RESTART_NEW_STATE_RESTART))
3101 SET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART);
3102 else
3103 UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART);
3104 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3105 zlog_debug(
3106 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !",
3107 peer->host,
3108 (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
3109 ? "Set"
3110 : "UnSet"));
3111 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
3112 PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT))
3113 SET_FLAG(peer->flags,
3114 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
3115 else
3116 UNSET_FLAG(peer->flags,
3117 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
3118 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3119 zlog_debug(
3120 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !",
3121 peer->host,
3122 (CHECK_FLAG(peer->flags,
3123 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT)
3124 ? "Set"
3125 : "UnSet"));
3126
3127 if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
3128 && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)) {
3129 zlog_debug("[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_MODE!",
3130 peer->host);
3131
3132 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
3133
3134 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
3135
3136 peer_nsf_stop(peer);
3137 zlog_debug(
3138 "[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_WAIT!",
3139 peer->host);
3140 }
3141 }
3142 }