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