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
11 #include "sockunion.h"
18 #include "workqueue.h"
22 #include "lib_errors.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"
46 DEFINE_HOOK(peer_backward_transition
, (struct peer
* peer
), (peer
));
47 DEFINE_HOOK(peer_status_changed
, (struct peer
* peer
), (peer
));
49 enum bgp_fsm_state_progress
{
50 BGP_FSM_FAILURE_AND_DELETE
= -2,
53 BGP_FSM_SUCCESS_STATE_TRANSFER
= 1,
56 /* Definition of display strings corresponding to FSM events. This should be
57 * kept consistent with the events defined in bgpd.h
59 static const char *const bgp_event_str
[] = {
63 "TCP_connection_open",
64 "TCP_connection_open_w_delay",
65 "TCP_connection_closed",
66 "TCP_connection_open_failed",
68 "ConnectRetry_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",
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
84 /* BGP event function. */
85 void bgp_event(struct thread
*);
87 /* BGP thread functions. */
88 static void bgp_start_timer(struct thread
*);
89 static void bgp_connect_timer(struct thread
*);
90 static void bgp_holdtime_timer(struct thread
*);
91 static void bgp_delayopen_timer(struct thread
*);
93 /* BGP FSM functions. */
94 static enum bgp_fsm_state_progress
bgp_start(struct peer
*);
96 /* Register peer with NHT */
97 int bgp_peer_reg_with_nht(struct peer
*peer
)
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
))
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
);
111 static void peer_xfer_stats(struct peer
*peer_dst
, struct peer
*peer_src
)
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
;
124 static struct peer
*peer_xfer_conn(struct peer
*from_peer
)
130 enum bgp_fsm_status status
, pstatus
;
131 enum bgp_fsm_events last_evt
, last_maj_evt
;
133 assert(from_peer
!= NULL
);
135 peer
= from_peer
->doppelganger
;
137 if (!peer
|| !CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
141 * Let's check that we are not going to loose known configuration
142 * state based upon doppelganger rules.
144 FOREACH_AFI_SAFI (afi
, safi
) {
145 if (from_peer
->afc
[afi
][safi
] != peer
->afc
[afi
][safi
]) {
147 EC_BGP_DOPPELGANGER_CONFIG
,
148 "from_peer->afc[%d][%d] is not the same as what we are overwriting",
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
,
159 bgp_writes_off(peer
);
161 bgp_writes_off(from_peer
);
162 bgp_reads_off(from_peer
);
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.
170 bgp_keepalives_off(from_peer
);
172 THREAD_OFF(peer
->t_routeadv
);
173 THREAD_OFF(peer
->t_connect
);
174 THREAD_OFF(peer
->t_delayopen
);
175 THREAD_OFF(peer
->t_connect_check_r
);
176 THREAD_OFF(peer
->t_connect_check_w
);
177 THREAD_OFF(from_peer
->t_routeadv
);
178 THREAD_OFF(from_peer
->t_connect
);
179 THREAD_OFF(from_peer
->t_delayopen
);
180 THREAD_OFF(from_peer
->t_connect_check_r
);
181 THREAD_OFF(from_peer
->t_connect_check_w
);
182 THREAD_OFF(from_peer
->t_process_packet
);
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.
189 frr_with_mutex (&peer
->io_mtx
, &from_peer
->io_mtx
) {
191 peer
->fd
= from_peer
->fd
;
194 stream_fifo_clean(peer
->ibuf
);
195 stream_fifo_clean(peer
->obuf
);
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.
205 "[%s] Dropping pending packet on connection transfer:",
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.
212 stream_free(peer
->curr
);
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
));
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
));
226 ringbuf_wipe(peer
->ibuf_work
);
227 ringbuf_copy(peer
->ibuf_work
, from_peer
->ibuf_work
,
228 ringbuf_remain(from_peer
->ibuf_work
));
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
;
255 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer
->bgp
,
258 if (bgp_peer_gr_mode_get(peer
) == PEER_DISABLE
) {
260 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
262 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)) {
267 if (peer
->hostname
) {
268 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
269 peer
->hostname
= NULL
;
271 if (from_peer
->hostname
!= NULL
) {
272 peer
->hostname
= from_peer
->hostname
;
273 from_peer
->hostname
= NULL
;
276 if (peer
->domainname
) {
277 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
278 peer
->domainname
= NULL
;
280 if (from_peer
->domainname
!= NULL
) {
281 peer
->domainname
= from_peer
->domainname
;
282 from_peer
->domainname
= NULL
;
285 if (peer
->soft_version
) {
286 XFREE(MTYPE_BGP_SOFT_VERSION
, peer
->soft_version
);
287 peer
->soft_version
= NULL
;
289 if (from_peer
->soft_version
) {
290 peer
->soft_version
= from_peer
->soft_version
;
291 from_peer
->soft_version
= NULL
;
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
];
304 if (bgp_getsockname(peer
) < 0) {
307 "%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
308 (CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
)
311 peer
->host
, peer
->fd
, from_peer
->fd
);
312 BGP_EVENT_ADD(peer
, BGP_Stop
);
313 BGP_EVENT_ADD(from_peer
, BGP_Stop
);
316 if (from_peer
->status
> Active
) {
317 if (bgp_getsockname(from_peer
) < 0) {
320 "%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
322 (CHECK_FLAG(from_peer
->sflags
,
323 PEER_STATUS_ACCEPT_PEER
)
326 from_peer
->host
, from_peer
->fd
, peer
->fd
);
333 // Note: peer_xfer_stats() must be called with I/O turned OFF
335 peer_xfer_stats(peer
, from_peer
);
337 /* Register peer for NHT. This is to allow RAs to be enabled when
338 * needed, even on a passive connection.
340 bgp_peer_reg_with_nht(peer
);
342 bgp_replace_nexthop_by_peer(from_peer
, peer
);
346 thread_add_event(bm
->master
, bgp_process_packet
, peer
, 0,
347 &peer
->t_process_packet
);
352 /* Hook function called after bgp event is occered. And vty's
353 neighbor command invoke this function after making neighbor
355 void bgp_timer_set(struct peer
*peer
)
360 switch (peer
->status
) {
362 /* First entry point of peer's finite state machine. In Idle
363 status start timer is on unless peer is shutdown or peer is
364 inactive. All other timer must be turned off */
365 if (BGP_PEER_START_SUPPRESSED(peer
) || !peer_active(peer
)
366 || peer
->bgp
->vrf_id
== VRF_UNKNOWN
) {
367 THREAD_OFF(peer
->t_start
);
369 BGP_TIMER_ON(peer
->t_start
, bgp_start_timer
,
372 THREAD_OFF(peer
->t_connect
);
373 THREAD_OFF(peer
->t_holdtime
);
374 bgp_keepalives_off(peer
);
375 THREAD_OFF(peer
->t_routeadv
);
376 THREAD_OFF(peer
->t_delayopen
);
380 /* After start timer is expired, the peer moves to Connect
381 status. Make sure start timer is off and connect timer is
383 THREAD_OFF(peer
->t_start
);
384 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER_DELAYOPEN
))
385 BGP_TIMER_ON(peer
->t_connect
, bgp_connect_timer
,
386 (peer
->v_delayopen
+ peer
->v_connect
));
388 BGP_TIMER_ON(peer
->t_connect
, bgp_connect_timer
,
391 THREAD_OFF(peer
->t_holdtime
);
392 bgp_keepalives_off(peer
);
393 THREAD_OFF(peer
->t_routeadv
);
397 /* Active is waiting connection from remote peer. And if
398 connect timer is expired, change status to Connect. */
399 THREAD_OFF(peer
->t_start
);
400 /* If peer is passive mode, do not set connect timer. */
401 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)
402 || CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)) {
403 THREAD_OFF(peer
->t_connect
);
405 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER_DELAYOPEN
))
407 peer
->t_connect
, bgp_connect_timer
,
408 (peer
->v_delayopen
+ peer
->v_connect
));
410 BGP_TIMER_ON(peer
->t_connect
, bgp_connect_timer
,
413 THREAD_OFF(peer
->t_holdtime
);
414 bgp_keepalives_off(peer
);
415 THREAD_OFF(peer
->t_routeadv
);
419 /* OpenSent status. */
420 THREAD_OFF(peer
->t_start
);
421 THREAD_OFF(peer
->t_connect
);
422 if (peer
->v_holdtime
!= 0) {
423 BGP_TIMER_ON(peer
->t_holdtime
, bgp_holdtime_timer
,
426 THREAD_OFF(peer
->t_holdtime
);
428 bgp_keepalives_off(peer
);
429 THREAD_OFF(peer
->t_routeadv
);
430 THREAD_OFF(peer
->t_delayopen
);
434 /* OpenConfirm status. */
435 THREAD_OFF(peer
->t_start
);
436 THREAD_OFF(peer
->t_connect
);
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
444 THREAD_OFF(peer
->t_holdtime
);
445 if (peer
->v_holdtime
== 0)
446 bgp_keepalives_off(peer
);
448 BGP_TIMER_ON(peer
->t_holdtime
, bgp_holdtime_timer
,
450 bgp_keepalives_on(peer
);
452 THREAD_OFF(peer
->t_routeadv
);
453 THREAD_OFF(peer
->t_delayopen
);
457 /* In Established status start and connect timer is turned
459 THREAD_OFF(peer
->t_start
);
460 THREAD_OFF(peer
->t_connect
);
461 THREAD_OFF(peer
->t_delayopen
);
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
469 THREAD_OFF(peer
->t_holdtime
);
470 if (peer
->v_holdtime
== 0)
471 bgp_keepalives_off(peer
);
473 BGP_TIMER_ON(peer
->t_holdtime
, bgp_holdtime_timer
,
475 bgp_keepalives_on(peer
);
479 THREAD_OFF(peer
->t_gr_restart
);
480 THREAD_OFF(peer
->t_gr_stale
);
482 FOREACH_AFI_SAFI (afi
, safi
)
483 THREAD_OFF(peer
->t_llgr_stale
[afi
][safi
]);
485 THREAD_OFF(peer
->t_pmax_restart
);
486 THREAD_OFF(peer
->t_refresh_stalepath
);
489 THREAD_OFF(peer
->t_start
);
490 THREAD_OFF(peer
->t_connect
);
491 THREAD_OFF(peer
->t_holdtime
);
492 bgp_keepalives_off(peer
);
493 THREAD_OFF(peer
->t_routeadv
);
494 THREAD_OFF(peer
->t_delayopen
);
497 flog_err(EC_LIB_DEVELOPMENT
,
498 "BGP_STATUS_MAX while a legal state is not valid state for the FSM");
503 /* BGP start timer. This function set BGP_Start event to thread value
504 and process event. */
505 static void bgp_start_timer(struct thread
*thread
)
509 peer
= THREAD_ARG(thread
);
511 if (bgp_debug_neighbor_events(peer
))
512 zlog_debug("%s [FSM] Timer (start timer expire).", peer
->host
);
514 THREAD_VAL(thread
) = BGP_Start
;
515 bgp_event(thread
); /* bgp_event unlocks peer */
518 /* BGP connect retry timer. */
519 static void bgp_connect_timer(struct thread
*thread
)
523 peer
= THREAD_ARG(thread
);
525 /* stop the DelayOpenTimer if it is running */
526 THREAD_OFF(peer
->t_delayopen
);
528 assert(!peer
->t_write
);
529 assert(!peer
->t_read
);
531 if (bgp_debug_neighbor_events(peer
))
532 zlog_debug("%s [FSM] Timer (connect timer expire)", peer
->host
);
534 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
))
537 THREAD_VAL(thread
) = ConnectRetry_timer_expired
;
538 bgp_event(thread
); /* bgp_event unlocks peer */
542 /* BGP holdtime timer. */
543 static void bgp_holdtime_timer(struct thread
*thread
)
545 atomic_size_t inq_count
;
548 peer
= THREAD_ARG(thread
);
550 if (bgp_debug_neighbor_events(peer
))
551 zlog_debug("%s [FSM] Timer (holdtime timer expire)",
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
564 inq_count
= atomic_load_explicit(&peer
->ibuf
->count
,
565 memory_order_relaxed
);
567 BGP_TIMER_ON(peer
->t_holdtime
, bgp_holdtime_timer
,
570 THREAD_VAL(thread
) = Hold_Timer_expired
;
571 bgp_event(thread
); /* bgp_event unlocks peer */
574 void bgp_routeadv_timer(struct thread
*thread
)
578 peer
= THREAD_ARG(thread
);
580 if (bgp_debug_neighbor_events(peer
))
581 zlog_debug("%s [FSM] Timer (routeadv timer expire)",
584 peer
->synctime
= monotime(NULL
);
586 thread_add_timer_msec(bm
->master
, bgp_generate_updgrp_packets
, peer
, 0,
587 &peer
->t_generate_updgrp_packets
);
589 /* MRAI timer will be started again when FIFO is built, no need to
594 /* RFC 4271 DelayOpenTimer */
595 void bgp_delayopen_timer(struct thread
*thread
)
599 peer
= THREAD_ARG(thread
);
601 if (bgp_debug_neighbor_events(peer
))
602 zlog_debug("%s [FSM] Timer (DelayOpentimer expire)",
605 THREAD_VAL(thread
) = DelayOpen_timer_expired
;
606 bgp_event(thread
); /* bgp_event unlocks peer */
609 /* BGP Peer Down Cause */
610 const char *const peer_down_str
[] = {"",
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",
623 "BGP Notification received",
624 "BGP Notification send",
625 "Peer closed the session",
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",
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",
645 "Admin. shutdown (RTT)"};
647 static void bgp_graceful_restart_timer_off(struct peer
*peer
)
652 FOREACH_AFI_SAFI (afi
, safi
)
653 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
654 PEER_STATUS_LLGR_WAIT
))
657 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
658 THREAD_OFF(peer
->t_gr_stale
);
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__
);
671 static void bgp_llgr_stale_timer_expire(struct thread
*thread
)
678 paf
= THREAD_ARG(thread
);
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.
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));
692 UNSET_FLAG(peer
->af_sflags
[afi
][safi
], PEER_STATUS_LLGR_WAIT
);
694 bgp_clear_stale_route(peer
, afi
, safi
);
696 bgp_graceful_restart_timer_off(peer
);
699 static void bgp_set_llgr_stale(struct peer
*peer
, afi_t afi
, safi_t safi
)
701 struct bgp_dest
*dest
;
702 struct bgp_path_info
*pi
;
703 struct bgp_table
*table
;
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
)) {
711 table
= bgp_dest_get_bgp_table_info(dest
);
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
;
719 if (pi
->peer
!= peer
)
722 if (bgp_attr_get_community(pi
->attr
) &&
724 bgp_attr_get_community(
729 if (bgp_debug_neighbor_events(peer
))
731 "%pBP Long-lived set stale community (LLGR_STALE) for: %pFX",
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
);
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
;
748 if (pi
->peer
!= peer
)
751 if (bgp_attr_get_community(pi
->attr
) &&
753 bgp_attr_get_community(pi
->attr
),
757 if (bgp_debug_neighbor_events(peer
))
759 "%pBP Long-lived set stale community (LLGR_STALE) for: %pFX",
763 bgp_attr_add_llgr_community(&attr
);
764 pi
->attr
= bgp_attr_intern(&attr
);
765 bgp_recalculate_afi_safi_bestpaths(peer
->bgp
,
773 static void bgp_graceful_restart_timer_expire(struct thread
*thread
)
775 struct peer
*peer
, *tmp_peer
;
776 struct listnode
*node
, *nnode
;
781 peer
= THREAD_ARG(thread
);
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",
789 FOREACH_AFI_SAFI (afi
, safi
) {
790 if (!peer
->nsf
[afi
][safi
])
793 /* Once the "Restart Time" period ends, the LLGR period is
794 * said to have begun and the following procedures MUST be
797 * The helper router MUST start a timer for the
798 * "Long-lived Stale Time".
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.
805 if (peer
->llgr
[afi
][safi
].stale_time
) {
806 paf
= peer_af_find(peer
, afi
, safi
);
810 if (bgp_debug_neighbor_events(peer
))
812 "%pBP Long-lived stale timer (%s) started for %d sec",
814 get_afi_safi_str(afi
, safi
, false),
815 peer
->llgr
[afi
][safi
].stale_time
);
817 SET_FLAG(peer
->af_sflags
[afi
][safi
],
818 PEER_STATUS_LLGR_WAIT
);
820 bgp_set_llgr_stale(peer
, afi
, safi
);
821 bgp_clear_stale_route(peer
, afi
, safi
);
823 thread_add_timer(bm
->master
,
824 bgp_llgr_stale_timer_expire
, paf
,
825 peer
->llgr
[afi
][safi
].stale_time
,
826 &peer
->t_llgr_stale
[afi
][safi
]);
828 for (ALL_LIST_ELEMENTS(peer
->bgp
->peer
, node
, nnode
,
830 bgp_announce_route(tmp_peer
, afi
, safi
, false);
832 bgp_clear_stale_route(peer
, afi
, safi
);
836 bgp_graceful_restart_timer_off(peer
);
839 static void bgp_graceful_stale_timer_expire(struct thread
*thread
)
845 peer
= THREAD_ARG(thread
);
847 if (bgp_debug_neighbor_events(peer
))
848 zlog_debug("%pBP graceful restart stalepath timer expired",
851 /* NSF delete stale route */
852 FOREACH_AFI_SAFI_NSF (afi
, safi
)
853 if (peer
->nsf
[afi
][safi
])
854 bgp_clear_stale_route(peer
, afi
, safi
);
857 /* Selection deferral timer processing function */
858 static void bgp_graceful_deferral_timer_expire(struct thread
*thread
)
860 struct afi_safi_info
*info
;
865 info
= THREAD_ARG(thread
);
870 if (BGP_DEBUG(update
, UPDATE_OUT
))
872 "afi %d, safi %d : graceful restart deferral timer expired",
875 bgp
->gr_info
[afi
][safi
].eor_required
= 0;
876 bgp
->gr_info
[afi
][safi
].eor_received
= 0;
877 XFREE(MTYPE_TMP
, info
);
879 /* Best path selection */
880 bgp_best_path_select_defer(bgp
, afi
, safi
);
883 static bool bgp_update_delay_applicable(struct bgp
*bgp
)
885 /* update_delay_over flag should be reset (set to 0) for any new
886 applicability of the update-delay during BGP process lifetime.
887 And it should be set after an occurence of the update-delay is
889 if (!bgp
->update_delay_over
)
894 bool bgp_update_delay_active(struct bgp
*bgp
)
896 if (bgp
->t_update_delay
)
901 bool bgp_update_delay_configured(struct bgp
*bgp
)
903 if (bgp
->v_update_delay
)
908 /* Do the post-processing needed when bgp comes out of the read-only mode
909 on ending the update delay. */
910 void bgp_update_delay_end(struct bgp
*bgp
)
912 THREAD_OFF(bgp
->t_update_delay
);
913 THREAD_OFF(bgp
->t_establish_wait
);
915 /* Reset update-delay related state */
916 bgp
->update_delay_over
= 1;
917 bgp
->established
= 0;
918 bgp
->restarted_peers
= 0;
919 bgp
->implicit_eors
= 0;
920 bgp
->explicit_eors
= 0;
922 frr_timestamp(3, bgp
->update_delay_end_time
,
923 sizeof(bgp
->update_delay_end_time
));
926 * Add an end-of-initial-update marker to the main process queues so
928 * the route advertisement timer for the peers can be started. Also set
929 * the zebra and peer update hold flags. These flags are used to achieve
930 * three stages in the update-delay post processing:
931 * 1. Finish best-path selection for all the prefixes held on the
933 * (routes in BGP are updated, and peers sync queues are populated
935 * 2. As the eoiu mark is reached in the bgp process routine, ship all
937 * routes to zebra. With that zebra should see updates from BGP
940 * 3. Unblock the peer update writes. With that peer update packing
942 * the prefixes should be at its maximum.
944 bgp_add_eoiu_mark(bgp
);
945 bgp
->main_zebra_update_hold
= 1;
946 bgp
->main_peers_update_hold
= 1;
949 * Resume the queue processing. This should trigger the event that would
950 * take care of processing any work that was queued during the read-only
953 work_queue_unplug(bgp
->process_queue
);
959 void bgp_start_routeadv(struct bgp
*bgp
)
961 struct listnode
*node
, *nnode
;
964 zlog_info("%s, update hold status %d", __func__
,
965 bgp
->main_peers_update_hold
);
967 if (bgp
->main_peers_update_hold
)
970 frr_timestamp(3, bgp
->update_delay_peers_resume_time
,
971 sizeof(bgp
->update_delay_peers_resume_time
));
973 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
974 if (!peer_established(peer
))
976 THREAD_OFF(peer
->t_routeadv
);
977 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, 0);
984 void bgp_adjust_routeadv(struct peer
*peer
)
986 time_t nowtime
= monotime(NULL
);
988 unsigned long remain
;
990 /* Bypass checks for special case of MRAI being 0 */
991 if (peer
->v_routeadv
== 0) {
992 /* Stop existing timer, just in case it is running for a
994 * duration and schedule write thread immediately.
996 THREAD_OFF(peer
->t_routeadv
);
998 peer
->synctime
= monotime(NULL
);
999 /* If suppress fib pending is enabled, route is advertised to
1000 * peers when the status is received from the FIB. The delay
1001 * is added to update group packet generate which will allow
1002 * more routes to be sent in the update message
1004 BGP_UPDATE_GROUP_TIMER_ON(&peer
->t_generate_updgrp_packets
,
1005 bgp_generate_updgrp_packets
);
1012 * If the last update was written more than MRAI back, expire the timer
1013 * instantly so that we can send the update out sooner.
1015 * <------- MRAI --------->
1016 * |-----------------|-----------------------|
1017 * <------------- m ------------>
1026 diff
= difftime(nowtime
, peer
->last_update
);
1027 if (diff
> (double)peer
->v_routeadv
) {
1028 THREAD_OFF(peer
->t_routeadv
);
1029 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, 0);
1035 * - Find when to expire the MRAI timer.
1036 * If MRAI timer is not active, assume we can start it now.
1038 * <------- MRAI --------->
1039 * |------------|-----------------------|
1040 * <-------- m ----------><----- r ----->
1049 if (peer
->t_routeadv
)
1050 remain
= thread_timer_remain_second(peer
->t_routeadv
);
1052 remain
= peer
->v_routeadv
;
1053 diff
= peer
->v_routeadv
- diff
;
1054 if (diff
<= (double)remain
) {
1055 THREAD_OFF(peer
->t_routeadv
);
1056 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, diff
);
1060 static bool bgp_maxmed_onstartup_applicable(struct bgp
*bgp
)
1062 if (!bgp
->maxmed_onstartup_over
)
1067 bool bgp_maxmed_onstartup_configured(struct bgp
*bgp
)
1069 if (bgp
->v_maxmed_onstartup
!= BGP_MAXMED_ONSTARTUP_UNCONFIGURED
)
1074 bool bgp_maxmed_onstartup_active(struct bgp
*bgp
)
1076 if (bgp
->t_maxmed_onstartup
)
1081 void bgp_maxmed_update(struct bgp
*bgp
)
1083 uint8_t maxmed_active
;
1084 uint32_t maxmed_value
;
1086 if (bgp
->v_maxmed_admin
) {
1088 maxmed_value
= bgp
->maxmed_admin_value
;
1089 } else if (bgp
->t_maxmed_onstartup
) {
1091 maxmed_value
= bgp
->maxmed_onstartup_value
;
1094 maxmed_value
= BGP_MAXMED_VALUE_DEFAULT
;
1097 if (bgp
->maxmed_active
!= maxmed_active
1098 || bgp
->maxmed_value
!= maxmed_value
) {
1099 bgp
->maxmed_active
= maxmed_active
;
1100 bgp
->maxmed_value
= maxmed_value
;
1102 update_group_announce(bgp
);
1106 int bgp_fsm_error_subcode(int status
)
1108 int fsm_err_subcode
= BGP_NOTIFY_FSM_ERR_SUBCODE_UNSPECIFIC
;
1112 fsm_err_subcode
= BGP_NOTIFY_FSM_ERR_SUBCODE_OPENSENT
;
1115 fsm_err_subcode
= BGP_NOTIFY_FSM_ERR_SUBCODE_OPENCONFIRM
;
1118 fsm_err_subcode
= BGP_NOTIFY_FSM_ERR_SUBCODE_ESTABLISHED
;
1124 return fsm_err_subcode
;
1127 /* The maxmed onstartup timer expiry callback. */
1128 static void bgp_maxmed_onstartup_timer(struct thread
*thread
)
1132 zlog_info("Max med on startup ended - timer expired.");
1134 bgp
= THREAD_ARG(thread
);
1135 THREAD_OFF(bgp
->t_maxmed_onstartup
);
1136 bgp
->maxmed_onstartup_over
= 1;
1138 bgp_maxmed_update(bgp
);
1141 static void bgp_maxmed_onstartup_begin(struct bgp
*bgp
)
1143 /* Applicable only once in the process lifetime on the startup */
1144 if (bgp
->maxmed_onstartup_over
)
1147 zlog_info("Begin maxmed onstartup mode - timer %d seconds",
1148 bgp
->v_maxmed_onstartup
);
1150 thread_add_timer(bm
->master
, bgp_maxmed_onstartup_timer
, bgp
,
1151 bgp
->v_maxmed_onstartup
, &bgp
->t_maxmed_onstartup
);
1153 if (!bgp
->v_maxmed_admin
) {
1154 bgp
->maxmed_active
= 1;
1155 bgp
->maxmed_value
= bgp
->maxmed_onstartup_value
;
1158 /* Route announce to all peers should happen after this in
1159 * bgp_establish() */
1162 static void bgp_maxmed_onstartup_process_status_change(struct peer
*peer
)
1164 if (peer_established(peer
) && !peer
->bgp
->established
) {
1165 bgp_maxmed_onstartup_begin(peer
->bgp
);
1169 /* The update delay timer expiry callback. */
1170 static void bgp_update_delay_timer(struct thread
*thread
)
1174 zlog_info("Update delay ended - timer expired.");
1176 bgp
= THREAD_ARG(thread
);
1177 THREAD_OFF(bgp
->t_update_delay
);
1178 bgp_update_delay_end(bgp
);
1181 /* The establish wait timer expiry callback. */
1182 static void bgp_establish_wait_timer(struct thread
*thread
)
1186 zlog_info("Establish wait - timer expired.");
1188 bgp
= THREAD_ARG(thread
);
1189 THREAD_OFF(bgp
->t_establish_wait
);
1190 bgp_check_update_delay(bgp
);
1193 /* Steps to begin the update delay:
1194 - initialize queues if needed
1195 - stop the queue processing
1196 - start the timer */
1197 static void bgp_update_delay_begin(struct bgp
*bgp
)
1199 struct listnode
*node
, *nnode
;
1202 /* Stop the processing of queued work. Enqueue shall continue */
1203 work_queue_plug(bgp
->process_queue
);
1205 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
1206 peer
->update_delay_over
= 0;
1208 /* Start the update-delay timer */
1209 thread_add_timer(bm
->master
, bgp_update_delay_timer
, bgp
,
1210 bgp
->v_update_delay
, &bgp
->t_update_delay
);
1212 if (bgp
->v_establish_wait
!= bgp
->v_update_delay
)
1213 thread_add_timer(bm
->master
, bgp_establish_wait_timer
, bgp
,
1214 bgp
->v_establish_wait
, &bgp
->t_establish_wait
);
1216 frr_timestamp(3, bgp
->update_delay_begin_time
,
1217 sizeof(bgp
->update_delay_begin_time
));
1220 static void bgp_update_delay_process_status_change(struct peer
*peer
)
1222 if (peer_established(peer
)) {
1223 if (!peer
->bgp
->established
++) {
1224 bgp_update_delay_begin(peer
->bgp
);
1226 "Begin read-only mode - update-delay timer %d seconds",
1227 peer
->bgp
->v_update_delay
);
1229 if (CHECK_FLAG(peer
->cap
, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV
))
1230 bgp_update_restarted_peers(peer
);
1232 if (peer
->ostatus
== Established
1233 && bgp_update_delay_active(peer
->bgp
)) {
1234 /* Adjust the update-delay state to account for this flap.
1235 NOTE: Intentionally skipping adjusting implicit_eors or
1237 counters. Extra sanity check in bgp_check_update_delay()
1239 be enough to take care of any additive discrepancy in bgp eor
1241 peer
->bgp
->established
--;
1242 peer
->update_delay_over
= 0;
1246 /* Called after event occurred, this function change status and reset
1247 read/write and timer thread. */
1248 void bgp_fsm_change_status(struct peer
*peer
, enum bgp_fsm_status status
)
1251 uint32_t peer_count
;
1254 peer_count
= bgp
->established_peers
;
1256 if (status
== Established
)
1257 bgp
->established_peers
++;
1258 else if ((peer_established(peer
)) && (status
!= Established
))
1259 bgp
->established_peers
--;
1261 if (bgp_debug_neighbor_events(peer
)) {
1262 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
1264 zlog_debug("%s : vrf %s(%u), Status: %s established_peers %u", __func__
,
1265 vrf
? vrf
->name
: "Unknown", bgp
->vrf_id
,
1266 lookup_msg(bgp_status_msg
, status
, NULL
),
1267 bgp
->established_peers
);
1270 /* Set to router ID to the value provided by RIB if there are no peers
1271 * in the established state and peer count did not change
1273 if ((peer_count
!= bgp
->established_peers
) &&
1274 (bgp
->established_peers
== 0))
1275 bgp_router_id_zebra_bump(bgp
->vrf_id
, NULL
);
1277 /* Transition into Clearing or Deleted must /always/ clear all routes..
1278 * (and must do so before actually changing into Deleted..
1280 if (status
>= Clearing
) {
1281 bgp_clear_route_all(peer
);
1283 /* If no route was queued for the clear-node processing,
1285 * completion event here. This is needed because if there are no
1287 * to trigger the background clear-node thread, the event won't
1289 * generated and the peer would be stuck in Clearing. Note that
1291 * event is for the peer and helps the peer transition out of
1293 * state; it should not be generated per (AFI,SAFI). The event
1295 * directly posted here without calling clear_node_complete() as
1297 * shouldn't do an extra unlock. This event will get processed
1299 * the state change that happens below, so peer will be in
1303 if (!work_queue_is_scheduled(peer
->clear_node_queue
) &&
1305 BGP_EVENT_ADD(peer
, Clearing_Completed
);
1308 /* Preserve old status and change into new status. */
1309 peer
->ostatus
= peer
->status
;
1310 peer
->status
= status
;
1312 /* Reset received keepalives counter on every FSM change */
1313 peer
->rtt_keepalive_rcv
= 0;
1315 /* Fire backward transition hook if that's the case */
1316 if (peer
->ostatus
== Established
&& peer
->status
!= Established
)
1317 hook_call(peer_backward_transition
, peer
);
1319 /* Save event that caused status change. */
1320 peer
->last_major_event
= peer
->cur_event
;
1322 /* Operations after status change */
1323 hook_call(peer_status_changed
, peer
);
1325 if (status
== Established
)
1326 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
1328 /* If max-med processing is applicable, do the necessary. */
1329 if (status
== Established
) {
1330 if (bgp_maxmed_onstartup_configured(peer
->bgp
)
1331 && bgp_maxmed_onstartup_applicable(peer
->bgp
))
1332 bgp_maxmed_onstartup_process_status_change(peer
);
1334 peer
->bgp
->maxmed_onstartup_over
= 1;
1337 /* If update-delay processing is applicable, do the necessary. */
1338 if (bgp_update_delay_configured(peer
->bgp
)
1339 && bgp_update_delay_applicable(peer
->bgp
))
1340 bgp_update_delay_process_status_change(peer
);
1342 if (bgp_debug_neighbor_events(peer
))
1343 zlog_debug("%s fd %d went from %s to %s", peer
->host
, peer
->fd
,
1344 lookup_msg(bgp_status_msg
, peer
->ostatus
, NULL
),
1345 lookup_msg(bgp_status_msg
, peer
->status
, NULL
));
1348 /* Flush the event queue and ensure the peer is shut down */
1349 static enum bgp_fsm_state_progress
bgp_clearing_completed(struct peer
*peer
)
1351 enum bgp_fsm_state_progress rc
= bgp_stop(peer
);
1353 if (rc
>= BGP_FSM_SUCCESS
)
1354 BGP_EVENT_FLUSH(peer
);
1359 /* Administrative BGP peer stop event. */
1360 /* May be called multiple times for the same peer */
1361 enum bgp_fsm_state_progress
bgp_stop(struct peer
*peer
)
1365 char orf_name
[BUFSIZ
];
1366 enum bgp_fsm_state_progress ret
= BGP_FSM_SUCCESS
;
1367 struct bgp
*bgp
= peer
->bgp
;
1368 struct graceful_restart_info
*gr_info
= NULL
;
1370 peer
->nsf_af_count
= 0;
1372 /* deregister peer */
1373 if (peer
->bfd_config
1374 && peer
->last_reset
== PEER_DOWN_UPDATE_SOURCE_CHANGE
)
1375 bfd_sess_uninstall(peer
->bfd_config
->session
);
1377 if (peer_dynamic_neighbor_no_nsf(peer
) &&
1378 !(CHECK_FLAG(peer
->flags
, PEER_FLAG_DELETE
))) {
1379 if (bgp_debug_neighbor_events(peer
))
1380 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1381 peer
->host
, __func__
);
1383 return BGP_FSM_FAILURE_AND_DELETE
;
1386 /* Can't do this in Clearing; events are used for state transitions */
1387 if (peer
->status
!= Clearing
) {
1388 /* Delete all existing events of the peer */
1389 BGP_EVENT_FLUSH(peer
);
1392 /* Increment Dropped count. */
1393 if (peer_established(peer
)) {
1396 /* Notify BGP conditional advertisement process */
1397 peer
->advmap_table_change
= true;
1399 /* bgp log-neighbor-changes of neighbor Down */
1400 if (CHECK_FLAG(peer
->bgp
->flags
,
1401 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)) {
1402 struct vrf
*vrf
= vrf_lookup_by_id(peer
->bgp
->vrf_id
);
1405 "%%ADJCHANGE: neighbor %pBP in vrf %s Down %s",
1407 vrf
? ((vrf
->vrf_id
!= VRF_DEFAULT
)
1411 peer_down_str
[(int)peer
->last_reset
]);
1414 /* graceful restart */
1415 if (peer
->t_gr_stale
) {
1416 THREAD_OFF(peer
->t_gr_stale
);
1417 if (bgp_debug_neighbor_events(peer
))
1419 "%pBP graceful restart stalepath timer stopped",
1422 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)) {
1423 if (bgp_debug_neighbor_events(peer
)) {
1425 "%pBP graceful restart timer started for %d sec",
1426 peer
, peer
->v_gr_restart
);
1428 "%pBP graceful restart stalepath timer started for %d sec",
1429 peer
, peer
->bgp
->stalepath_time
);
1431 BGP_TIMER_ON(peer
->t_gr_restart
,
1432 bgp_graceful_restart_timer_expire
,
1433 peer
->v_gr_restart
);
1434 BGP_TIMER_ON(peer
->t_gr_stale
,
1435 bgp_graceful_stale_timer_expire
,
1436 peer
->bgp
->stalepath_time
);
1438 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
1440 FOREACH_AFI_SAFI_NSF (afi
, safi
)
1441 peer
->nsf
[afi
][safi
] = 0;
1444 /* Stop route-refresh stalepath timer */
1445 if (peer
->t_refresh_stalepath
) {
1446 THREAD_OFF(peer
->t_refresh_stalepath
);
1448 if (bgp_debug_neighbor_events(peer
))
1450 "%pBP route-refresh restart stalepath timer stopped",
1454 /* If peer reset before receiving EOR, decrement EOR count and
1455 * cancel the selection deferral timer if there are no
1456 * pending EOR messages to be received
1458 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer
)) {
1459 FOREACH_AFI_SAFI (afi
, safi
) {
1460 if (!peer
->afc_nego
[afi
][safi
]
1461 || CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
1462 PEER_STATUS_EOR_RECEIVED
))
1465 gr_info
= &bgp
->gr_info
[afi
][safi
];
1469 if (gr_info
->eor_required
)
1470 gr_info
->eor_required
--;
1472 if (BGP_DEBUG(update
, UPDATE_OUT
))
1473 zlog_debug("peer %s, EOR_required %d",
1475 gr_info
->eor_required
);
1477 /* There is no pending EOR message */
1478 if (gr_info
->eor_required
== 0) {
1479 if (gr_info
->t_select_deferral
) {
1480 void *info
= THREAD_ARG(
1481 gr_info
->t_select_deferral
);
1482 XFREE(MTYPE_TMP
, info
);
1484 THREAD_OFF(gr_info
->t_select_deferral
);
1485 gr_info
->eor_received
= 0;
1490 /* set last reset time */
1491 peer
->resettime
= peer
->uptime
= monotime(NULL
);
1493 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
1494 zlog_debug("%s remove from all update group",
1496 update_group_remove_peer_afs(peer
);
1498 /* Reset peer synctime */
1502 /* stop keepalives */
1503 bgp_keepalives_off(peer
);
1505 /* Stop read and write threads. */
1506 bgp_writes_off(peer
);
1507 bgp_reads_off(peer
);
1509 THREAD_OFF(peer
->t_connect_check_r
);
1510 THREAD_OFF(peer
->t_connect_check_w
);
1512 /* Stop all timers. */
1513 THREAD_OFF(peer
->t_start
);
1514 THREAD_OFF(peer
->t_connect
);
1515 THREAD_OFF(peer
->t_holdtime
);
1516 THREAD_OFF(peer
->t_routeadv
);
1517 THREAD_OFF(peer
->t_delayopen
);
1519 /* Clear input and output buffer. */
1520 frr_with_mutex (&peer
->io_mtx
) {
1522 stream_fifo_clean(peer
->ibuf
);
1524 stream_fifo_clean(peer
->obuf
);
1526 if (peer
->ibuf_work
)
1527 ringbuf_wipe(peer
->ibuf_work
);
1528 if (peer
->obuf_work
)
1529 stream_reset(peer
->obuf_work
);
1532 stream_free(peer
->curr
);
1537 /* Close of file descriptor. */
1538 if (peer
->fd
>= 0) {
1543 /* Reset capabilities. */
1546 /* Resetting neighbor role to the default value */
1547 peer
->remote_role
= ROLE_UNDEFINED
;
1549 FOREACH_AFI_SAFI (afi
, safi
) {
1550 /* Reset all negotiated variables */
1551 peer
->afc_nego
[afi
][safi
] = 0;
1552 peer
->afc_adv
[afi
][safi
] = 0;
1553 peer
->afc_recv
[afi
][safi
] = 0;
1555 /* peer address family capability flags*/
1556 peer
->af_cap
[afi
][safi
] = 0;
1558 /* peer address family status flags*/
1559 peer
->af_sflags
[afi
][safi
] = 0;
1561 /* Received ORF prefix-filter */
1562 peer
->orf_plist
[afi
][safi
] = NULL
;
1564 if ((peer
->status
== OpenConfirm
) || (peer_established(peer
))) {
1565 /* ORF received prefix-filter pnt */
1566 snprintf(orf_name
, sizeof(orf_name
), "%s.%d.%d",
1567 peer
->host
, afi
, safi
);
1568 prefix_bgp_orf_remove_all(afi
, orf_name
);
1572 /* Reset keepalive and holdtime */
1573 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
)) {
1574 peer
->v_keepalive
= peer
->keepalive
;
1575 peer
->v_holdtime
= peer
->holdtime
;
1577 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
1578 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
1581 /* Reset DelayOpenTime */
1582 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER_DELAYOPEN
))
1583 peer
->v_delayopen
= peer
->delayopen
;
1585 peer
->v_delayopen
= peer
->bgp
->default_delayopen
;
1587 peer
->update_time
= 0;
1589 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1590 && !(CHECK_FLAG(peer
->flags
, PEER_FLAG_DELETE
))) {
1592 ret
= BGP_FSM_FAILURE_AND_DELETE
;
1594 bgp_peer_conf_if_to_su_update(peer
);
1599 /* BGP peer is stoped by the error. */
1600 static enum bgp_fsm_state_progress
bgp_stop_with_error(struct peer
*peer
)
1602 /* Double start timer. */
1605 /* Overflow check. */
1606 if (peer
->v_start
>= (60 * 2))
1607 peer
->v_start
= (60 * 2);
1609 if (peer_dynamic_neighbor_no_nsf(peer
)) {
1610 if (bgp_debug_neighbor_events(peer
))
1611 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1612 peer
->host
, __func__
);
1614 return BGP_FSM_FAILURE
;
1617 return bgp_stop(peer
);
1621 /* something went wrong, send notify and tear down */
1622 static enum bgp_fsm_state_progress
1623 bgp_stop_with_notify(struct peer
*peer
, uint8_t code
, uint8_t sub_code
)
1625 /* Send notify to remote peer */
1626 bgp_notify_send(peer
, code
, sub_code
);
1628 if (peer_dynamic_neighbor_no_nsf(peer
)) {
1629 if (bgp_debug_neighbor_events(peer
))
1630 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1631 peer
->host
, __func__
);
1633 return BGP_FSM_FAILURE
;
1636 /* Clear start timer value to default. */
1637 peer
->v_start
= BGP_INIT_START_TIMER
;
1639 return bgp_stop(peer
);
1643 * Determines whether a TCP session has successfully established for a peer and
1644 * events as appropriate.
1646 * This function is called when setting up a new session. After connect() is
1647 * called on the peer's socket (in bgp_start()), the fd is passed to poll()
1648 * to wait for connection success or failure. When poll() returns, this
1649 * function is called to evaluate the result.
1651 * Due to differences in behavior of poll() on Linux and BSD - specifically,
1652 * the value of .revents in the case of a closed connection - this function is
1653 * scheduled both for a read and a write event. The write event is triggered
1654 * when the connection is established. A read event is triggered when the
1655 * connection is closed. Thus we need to cancel whichever one did not occur.
1657 static void bgp_connect_check(struct thread
*thread
)
1664 peer
= THREAD_ARG(thread
);
1665 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
1666 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
1667 assert(!peer
->t_read
);
1668 assert(!peer
->t_write
);
1670 THREAD_OFF(peer
->t_connect_check_r
);
1671 THREAD_OFF(peer
->t_connect_check_w
);
1673 /* Check file descriptor. */
1674 slen
= sizeof(status
);
1675 ret
= getsockopt(peer
->fd
, SOL_SOCKET
, SO_ERROR
, (void *)&status
,
1678 /* If getsockopt is fail, this is fatal error. */
1680 zlog_err("can't get sockopt for nonblocking connect: %d(%s)",
1681 errno
, safe_strerror(errno
));
1682 BGP_EVENT_ADD(peer
, TCP_fatal_error
);
1686 /* When status is 0 then TCP connection is established. */
1688 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER_DELAYOPEN
))
1689 BGP_EVENT_ADD(peer
, TCP_connection_open_w_delay
);
1691 BGP_EVENT_ADD(peer
, TCP_connection_open
);
1694 if (bgp_debug_neighbor_events(peer
))
1695 zlog_debug("%s [Event] Connect failed %d(%s)",
1696 peer
->host
, status
, safe_strerror(status
));
1697 BGP_EVENT_ADD(peer
, TCP_connection_open_failed
);
1702 /* TCP connection open. Next we send open message to remote peer. And
1703 add read thread for reading open message. */
1704 static enum bgp_fsm_state_progress
bgp_connect_success(struct peer
*peer
)
1707 flog_err(EC_BGP_CONNECT
, "%s peer's fd is negative value %d",
1708 __func__
, peer
->fd
);
1709 return bgp_stop(peer
);
1712 if (bgp_getsockname(peer
) < 0) {
1713 flog_err_sys(EC_LIB_SOCKET
,
1714 "%s: bgp_getsockname(): failed for peer %s, fd %d",
1715 __func__
, peer
->host
, peer
->fd
);
1716 bgp_notify_send(peer
, BGP_NOTIFY_FSM_ERR
,
1717 bgp_fsm_error_subcode(peer
->status
));
1718 bgp_writes_on(peer
);
1719 return BGP_FSM_FAILURE
;
1723 * If we are doing nht for a peer that ls v6 LL based
1724 * massage the event system to make things happy
1726 bgp_nht_interface_events(peer
);
1730 if (bgp_debug_neighbor_events(peer
)) {
1731 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
))
1732 zlog_debug("%s open active, local address %pSU",
1733 peer
->host
, peer
->su_local
);
1735 zlog_debug("%s passive open", peer
->host
);
1738 /* Send an open message */
1739 bgp_open_send(peer
);
1741 return BGP_FSM_SUCCESS
;
1744 /* TCP connection open with RFC 4271 optional session attribute DelayOpen flag
1747 static enum bgp_fsm_state_progress
1748 bgp_connect_success_w_delayopen(struct peer
*peer
)
1751 flog_err(EC_BGP_CONNECT
, "%s: peer's fd is negative value %d",
1752 __func__
, peer
->fd
);
1753 return bgp_stop(peer
);
1756 if (bgp_getsockname(peer
) < 0) {
1757 flog_err_sys(EC_LIB_SOCKET
,
1758 "%s: bgp_getsockname(): failed for peer %s, fd %d",
1759 __func__
, peer
->host
, peer
->fd
);
1760 bgp_notify_send(peer
, BGP_NOTIFY_FSM_ERR
,
1761 bgp_fsm_error_subcode(peer
->status
));
1762 bgp_writes_on(peer
);
1763 return BGP_FSM_FAILURE
;
1767 * If we are doing nht for a peer that ls v6 LL based
1768 * massage the event system to make things happy
1770 bgp_nht_interface_events(peer
);
1774 if (bgp_debug_neighbor_events(peer
)) {
1775 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
))
1776 zlog_debug("%s open active, local address %pSU",
1777 peer
->host
, peer
->su_local
);
1779 zlog_debug("%s passive open", peer
->host
);
1782 /* set the DelayOpenTime to the inital value */
1783 peer
->v_delayopen
= peer
->delayopen
;
1785 /* Start the DelayOpenTimer if it is not already running */
1786 if (!peer
->t_delayopen
)
1787 BGP_TIMER_ON(peer
->t_delayopen
, bgp_delayopen_timer
,
1790 if (bgp_debug_neighbor_events(peer
))
1791 zlog_debug("%s [FSM] BGP OPEN message delayed for %d seconds",
1792 peer
->host
, peer
->delayopen
);
1794 return BGP_FSM_SUCCESS
;
1797 /* TCP connect fail */
1798 static enum bgp_fsm_state_progress
bgp_connect_fail(struct peer
*peer
)
1800 if (peer_dynamic_neighbor_no_nsf(peer
)) {
1801 if (bgp_debug_neighbor_events(peer
))
1802 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1803 peer
->host
, __func__
);
1805 return BGP_FSM_FAILURE_AND_DELETE
;
1809 * If we are doing nht for a peer that ls v6 LL based
1810 * massage the event system to make things happy
1812 bgp_nht_interface_events(peer
);
1814 return bgp_stop(peer
);
1817 /* This function is the first starting point of all BGP connection. It
1818 * try to connect to remote peer with non-blocking IO.
1820 enum bgp_fsm_state_progress
bgp_start(struct peer
*peer
)
1824 bgp_peer_conf_if_to_su_update(peer
);
1826 if (peer
->su
.sa
.sa_family
== AF_UNSPEC
) {
1827 if (bgp_debug_neighbor_events(peer
))
1829 "%s [FSM] Unable to get neighbor's IP address, waiting...",
1831 peer
->last_reset
= PEER_DOWN_NBR_ADDR
;
1832 return BGP_FSM_FAILURE
;
1835 if (BGP_PEER_START_SUPPRESSED(peer
)) {
1836 if (bgp_debug_neighbor_events(peer
))
1837 flog_err(EC_BGP_FSM
,
1838 "%s [FSM] Trying to start suppressed peer - this is never supposed to happen!",
1840 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_RTT_SHUTDOWN
))
1841 peer
->last_reset
= PEER_DOWN_RTT_SHUTDOWN
;
1842 else if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
))
1843 peer
->last_reset
= PEER_DOWN_USER_SHUTDOWN
;
1844 else if (CHECK_FLAG(peer
->bgp
->flags
, BGP_FLAG_SHUTDOWN
))
1845 peer
->last_reset
= PEER_DOWN_USER_SHUTDOWN
;
1846 else if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
))
1847 peer
->last_reset
= PEER_DOWN_PFX_COUNT
;
1848 return BGP_FSM_FAILURE
;
1851 /* Scrub some information that might be left over from a previous,
1854 /* Connection information. */
1855 if (peer
->su_local
) {
1856 sockunion_free(peer
->su_local
);
1857 peer
->su_local
= NULL
;
1860 if (peer
->su_remote
) {
1861 sockunion_free(peer
->su_remote
);
1862 peer
->su_remote
= NULL
;
1865 /* Clear remote router-id. */
1866 peer
->remote_id
.s_addr
= INADDR_ANY
;
1868 /* Clear peer capability flag. */
1871 /* If the peer is passive mode, force to move to Active mode. */
1872 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)) {
1873 BGP_EVENT_ADD(peer
, TCP_connection_open_failed
);
1874 return BGP_FSM_SUCCESS
;
1877 if (peer
->bgp
->vrf_id
== VRF_UNKNOWN
) {
1878 if (bgp_debug_neighbor_events(peer
))
1881 "%s [FSM] In a VRF that is not initialised yet",
1883 peer
->last_reset
= PEER_DOWN_VRF_UNINIT
;
1884 return BGP_FSM_FAILURE
;
1887 /* Register peer for NHT. If next hop is already resolved, proceed
1888 * with connection setup, else wait.
1890 if (!bgp_peer_reg_with_nht(peer
)) {
1891 if (bgp_zebra_num_connects()) {
1892 if (bgp_debug_neighbor_events(peer
))
1894 "%s [FSM] Waiting for NHT, no path to neighbor present",
1896 peer
->last_reset
= PEER_DOWN_WAITING_NHT
;
1897 BGP_EVENT_ADD(peer
, TCP_connection_open_failed
);
1898 return BGP_FSM_SUCCESS
;
1902 assert(!peer
->t_write
);
1903 assert(!peer
->t_read
);
1904 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
1905 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
1906 status
= bgp_connect(peer
);
1910 if (bgp_debug_neighbor_events(peer
))
1911 zlog_debug("%s [FSM] Connect error", peer
->host
);
1912 BGP_EVENT_ADD(peer
, TCP_connection_open_failed
);
1914 case connect_success
:
1915 if (bgp_debug_neighbor_events(peer
))
1917 "%s [FSM] Connect immediately success, fd %d",
1918 peer
->host
, peer
->fd
);
1920 BGP_EVENT_ADD(peer
, TCP_connection_open
);
1922 case connect_in_progress
:
1923 /* To check nonblocking connect, we wait until socket is
1924 readable or writable. */
1925 if (bgp_debug_neighbor_events(peer
))
1927 "%s [FSM] Non blocking connect waiting result, fd %d",
1928 peer
->host
, peer
->fd
);
1930 flog_err(EC_BGP_FSM
,
1931 "%s peer's fd is negative value %d", __func__
,
1933 return BGP_FSM_FAILURE
;
1936 * - when the socket becomes ready, poll() will signify POLLOUT
1937 * - if it fails to connect, poll() will signify POLLHUP
1938 * - POLLHUP is handled as a 'read' event by thread.c
1940 * therefore, we schedule both a read and a write event with
1941 * bgp_connect_check() as the handler for each and cancel the
1942 * unused event in that function.
1944 thread_add_read(bm
->master
, bgp_connect_check
, peer
, peer
->fd
,
1945 &peer
->t_connect_check_r
);
1946 thread_add_write(bm
->master
, bgp_connect_check
, peer
, peer
->fd
,
1947 &peer
->t_connect_check_w
);
1950 return BGP_FSM_SUCCESS
;
1953 /* Connect retry timer is expired when the peer status is Connect. */
1954 static enum bgp_fsm_state_progress
bgp_reconnect(struct peer
*peer
)
1956 enum bgp_fsm_state_progress ret
;
1958 ret
= bgp_stop(peer
);
1959 if (ret
< BGP_FSM_SUCCESS
)
1962 /* Send graceful restart capabilty */
1963 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer
->bgp
,
1966 return bgp_start(peer
);
1969 static enum bgp_fsm_state_progress
bgp_fsm_open(struct peer
*peer
)
1971 /* If DelayOpen is active, we may still need to send an open message */
1972 if ((peer
->status
== Connect
) || (peer
->status
== Active
))
1973 bgp_open_send(peer
);
1975 /* Send keepalive and make keepalive timer */
1976 bgp_keepalive_send(peer
);
1978 return BGP_FSM_SUCCESS
;
1981 /* FSM error, unexpected event. This is error of BGP connection. So cut the
1982 peer and change to Idle status. */
1983 static enum bgp_fsm_state_progress
bgp_fsm_event_error(struct peer
*peer
)
1985 flog_err(EC_BGP_FSM
, "%s [FSM] unexpected packet received in state %s",
1986 peer
->host
, lookup_msg(bgp_status_msg
, peer
->status
, NULL
));
1988 return bgp_stop_with_notify(peer
, BGP_NOTIFY_FSM_ERR
,
1989 bgp_fsm_error_subcode(peer
->status
));
1992 /* Hold timer expire. This is error of BGP connection. So cut the
1993 peer and change to Idle status. */
1994 static enum bgp_fsm_state_progress
bgp_fsm_holdtime_expire(struct peer
*peer
)
1996 if (bgp_debug_neighbor_events(peer
))
1997 zlog_debug("%s [FSM] Hold timer expire", peer
->host
);
1999 /* RFC8538 updates RFC 4724 by defining an extension that permits
2000 * the Graceful Restart procedures to be performed when the BGP
2001 * speaker receives a BGP NOTIFICATION message or the Hold Time expires.
2003 if (peer_established(peer
) &&
2004 bgp_has_graceful_restart_notification(peer
))
2005 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
))
2006 SET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2008 return bgp_stop_with_notify(peer
, BGP_NOTIFY_HOLD_ERR
, 0);
2011 /* RFC 4271 DelayOpenTimer_Expires event */
2012 static enum bgp_fsm_state_progress
2013 bgp_fsm_delayopen_timer_expire(struct peer
*peer
)
2015 /* Stop the DelayOpenTimer */
2016 THREAD_OFF(peer
->t_delayopen
);
2018 /* Send open message to peer */
2019 bgp_open_send(peer
);
2021 /* Set the HoldTimer to a large value (4 minutes) */
2022 peer
->v_holdtime
= 245;
2024 return BGP_FSM_SUCCESS
;
2027 /* Start the selection deferral timer thread for the specified AFI, SAFI */
2028 static int bgp_start_deferral_timer(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2029 struct graceful_restart_info
*gr_info
)
2031 struct afi_safi_info
*thread_info
;
2033 /* If the deferral timer is active, then increment eor count */
2034 if (gr_info
->t_select_deferral
) {
2035 gr_info
->eor_required
++;
2039 /* Start the deferral timer when the first peer enabled for the graceful
2040 * restart is established
2042 if (gr_info
->eor_required
== 0) {
2043 thread_info
= XMALLOC(MTYPE_TMP
, sizeof(struct afi_safi_info
));
2045 thread_info
->afi
= afi
;
2046 thread_info
->safi
= safi
;
2047 thread_info
->bgp
= bgp
;
2049 thread_add_timer(bm
->master
, bgp_graceful_deferral_timer_expire
,
2050 thread_info
, bgp
->select_defer_time
,
2051 &gr_info
->t_select_deferral
);
2053 gr_info
->eor_required
++;
2054 /* Send message to RIB indicating route update pending */
2055 if (gr_info
->af_enabled
[afi
][safi
] == false) {
2056 gr_info
->af_enabled
[afi
][safi
] = true;
2057 /* Send message to RIB */
2058 bgp_zebra_update(bgp
, afi
, safi
,
2059 ZEBRA_CLIENT_ROUTE_UPDATE_PENDING
);
2061 if (BGP_DEBUG(update
, UPDATE_OUT
))
2062 zlog_debug("Started the deferral timer for %s eor_required %d",
2063 get_afi_safi_str(afi
, safi
, false),
2064 gr_info
->eor_required
);
2068 /* Update the graceful restart information for the specified AFI, SAFI */
2069 static int bgp_update_gr_info(struct peer
*peer
, afi_t afi
, safi_t safi
)
2071 struct graceful_restart_info
*gr_info
;
2072 struct bgp
*bgp
= peer
->bgp
;
2075 if ((afi
< AFI_IP
) || (afi
>= AFI_MAX
)) {
2076 if (BGP_DEBUG(update
, UPDATE_OUT
))
2077 zlog_debug("%s : invalid afi %d", __func__
, afi
);
2081 if ((safi
< SAFI_UNICAST
) || (safi
> SAFI_MPLS_VPN
)) {
2082 if (BGP_DEBUG(update
, UPDATE_OUT
))
2083 zlog_debug("%s : invalid safi %d", __func__
, safi
);
2087 /* Restarting router */
2088 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer
)
2089 && BGP_PEER_RESTARTING_MODE(peer
)) {
2090 /* Check if the forwarding state is preserved */
2091 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_GR_PRESERVE_FWD
)) {
2092 gr_info
= &(bgp
->gr_info
[afi
][safi
]);
2093 ret
= bgp_start_deferral_timer(bgp
, afi
, safi
, gr_info
);
2100 * Transition to Established state.
2102 * Convert peer from stub to full fledged peer, set some timers, and generate
2105 static enum bgp_fsm_state_progress
bgp_establish(struct peer
*peer
)
2109 int nsf_af_count
= 0;
2110 enum bgp_fsm_state_progress ret
= BGP_FSM_SUCCESS
;
2114 other
= peer
->doppelganger
;
2115 hash_release(peer
->bgp
->peerhash
, peer
);
2117 hash_release(peer
->bgp
->peerhash
, other
);
2119 peer
= peer_xfer_conn(peer
);
2121 flog_err(EC_BGP_CONNECT
, "%%Neighbor failed in xfer_conn");
2122 return BGP_FSM_FAILURE
;
2126 ret
= BGP_FSM_SUCCESS_STATE_TRANSFER
;
2128 /* Reset capability open status flag. */
2129 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
))
2130 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
2132 /* Clear start timer value to default. */
2133 peer
->v_start
= BGP_INIT_START_TIMER
;
2135 /* Increment established count. */
2136 peer
->established
++;
2137 bgp_fsm_change_status(peer
, Established
);
2139 /* bgp log-neighbor-changes of neighbor Up */
2140 if (CHECK_FLAG(peer
->bgp
->flags
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)) {
2141 struct vrf
*vrf
= vrf_lookup_by_id(peer
->bgp
->vrf_id
);
2142 zlog_info("%%ADJCHANGE: neighbor %pBP in vrf %s Up", peer
,
2143 vrf
? ((vrf
->vrf_id
!= VRF_DEFAULT
)
2148 /* assign update-group/subgroup */
2149 update_group_adjust_peer_afs(peer
);
2151 /* graceful restart */
2152 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2153 if (bgp_debug_neighbor_events(peer
)) {
2154 if (BGP_PEER_RESTARTING_MODE(peer
))
2155 zlog_debug("%pBP BGP_RESTARTING_MODE", peer
);
2156 else if (BGP_PEER_HELPER_MODE(peer
))
2157 zlog_debug("%pBP BGP_HELPER_MODE", peer
);
2160 FOREACH_AFI_SAFI_NSF (afi
, safi
) {
2161 if (peer
->afc_nego
[afi
][safi
] &&
2162 CHECK_FLAG(peer
->cap
, PEER_CAP_RESTART_ADV
) &&
2163 CHECK_FLAG(peer
->af_cap
[afi
][safi
],
2164 PEER_CAP_RESTART_AF_RCV
)) {
2165 if (peer
->nsf
[afi
][safi
] &&
2166 !CHECK_FLAG(peer
->af_cap
[afi
][safi
],
2167 PEER_CAP_RESTART_AF_PRESERVE_RCV
))
2168 bgp_clear_stale_route(peer
, afi
, safi
);
2170 peer
->nsf
[afi
][safi
] = 1;
2173 if (peer
->nsf
[afi
][safi
])
2174 bgp_clear_stale_route(peer
, afi
, safi
);
2175 peer
->nsf
[afi
][safi
] = 0;
2177 /* Update the graceful restart information */
2178 if (peer
->afc_nego
[afi
][safi
]) {
2179 if (!BGP_SELECT_DEFER_DISABLE(peer
->bgp
)) {
2180 status
= bgp_update_gr_info(peer
, afi
, safi
);
2183 "Error in updating graceful restart for %s",
2184 get_afi_safi_str(afi
, safi
,
2187 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer
) &&
2188 BGP_PEER_RESTARTING_MODE(peer
) &&
2189 CHECK_FLAG(peer
->bgp
->flags
,
2190 BGP_FLAG_GR_PRESERVE_FWD
))
2191 peer
->bgp
->gr_info
[afi
][safi
]
2197 if (!CHECK_FLAG(peer
->cap
, PEER_CAP_RESTART_RCV
)) {
2198 if ((bgp_peer_gr_mode_get(peer
) == PEER_GR
)
2199 || ((bgp_peer_gr_mode_get(peer
) == PEER_GLOBAL_INHERIT
)
2200 && (bgp_global_gr_mode_get(peer
->bgp
) == GLOBAL_GR
))) {
2201 FOREACH_AFI_SAFI (afi
, safi
)
2202 /* Send route processing complete
2205 peer
->bgp
, afi
, safi
,
2206 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE
);
2209 /* Peer sends R-bit. In this case, we need to send
2210 * ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE to Zebra. */
2211 if (CHECK_FLAG(peer
->cap
,
2212 PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV
)) {
2213 FOREACH_AFI_SAFI (afi
, safi
)
2214 /* Send route processing complete
2217 peer
->bgp
, afi
, safi
,
2218 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE
);
2222 peer
->nsf_af_count
= nsf_af_count
;
2225 SET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2227 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2228 if (peer
->t_gr_stale
) {
2229 THREAD_OFF(peer
->t_gr_stale
);
2230 if (bgp_debug_neighbor_events(peer
))
2232 "%pBP graceful restart stalepath timer stopped",
2237 if (peer
->t_gr_restart
) {
2238 THREAD_OFF(peer
->t_gr_restart
);
2239 if (bgp_debug_neighbor_events(peer
))
2240 zlog_debug("%pBP graceful restart timer stopped", peer
);
2243 /* Reset uptime, turn on keepalives, send current table. */
2244 if (!peer
->v_holdtime
)
2245 bgp_keepalives_on(peer
);
2247 peer
->uptime
= monotime(NULL
);
2249 /* Send route-refresh when ORF is enabled.
2250 * Stop Long-lived Graceful Restart timers.
2252 FOREACH_AFI_SAFI (afi
, safi
) {
2253 if (peer
->t_llgr_stale
[afi
][safi
]) {
2254 THREAD_OFF(peer
->t_llgr_stale
[afi
][safi
]);
2255 if (bgp_debug_neighbor_events(peer
))
2257 "%pBP Long-lived stale timer stopped for afi/safi: %d/%d",
2261 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
2262 PEER_CAP_ORF_PREFIX_SM_ADV
)) {
2263 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
2264 PEER_CAP_ORF_PREFIX_RM_RCV
))
2265 bgp_route_refresh_send(
2266 peer
, afi
, safi
, ORF_TYPE_PREFIX
,
2267 REFRESH_IMMEDIATE
, 0,
2268 BGP_ROUTE_REFRESH_NORMAL
);
2269 else if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
2270 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))
2271 bgp_route_refresh_send(
2272 peer
, afi
, safi
, ORF_TYPE_PREFIX_OLD
,
2273 REFRESH_IMMEDIATE
, 0,
2274 BGP_ROUTE_REFRESH_NORMAL
);
2278 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2279 FOREACH_AFI_SAFI (afi
, safi
) {
2280 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
2281 PEER_CAP_ORF_PREFIX_RM_ADV
))
2282 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
2283 PEER_CAP_ORF_PREFIX_SM_RCV
)
2284 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
2285 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
))
2286 SET_FLAG(peer
->af_sflags
[afi
][safi
],
2287 PEER_STATUS_ORF_WAIT_REFRESH
);
2290 bgp_announce_peer(peer
);
2292 /* Start the route advertisement timer to send updates to the peer - if
2294 * is not in read-only mode. If it is, the timer will be started at the
2296 * of read-only mode.
2298 if (!bgp_update_delay_active(peer
->bgp
)) {
2299 THREAD_OFF(peer
->t_routeadv
);
2300 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, 0);
2303 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)) {
2304 if (bgp_debug_neighbor_events(peer
))
2306 "[Event] Deleting stub connection for peer %s",
2309 if (peer
->doppelganger
->status
> Active
)
2310 bgp_notify_send(peer
->doppelganger
, BGP_NOTIFY_CEASE
,
2311 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION
);
2313 peer_delete(peer
->doppelganger
);
2317 * If we are replacing the old peer for a doppelganger
2318 * then switch it around in the bgp->peerhash
2319 * the doppelgangers su and this peer's su are the same
2320 * so the hash_release is the same for either.
2322 (void)hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
2324 /* Start BFD peer if not already running. */
2325 if (peer
->bfd_config
)
2326 bgp_peer_bfd_update_source(peer
);
2331 /* Keepalive packet is received. */
2332 static enum bgp_fsm_state_progress
bgp_fsm_keepalive(struct peer
*peer
)
2334 THREAD_OFF(peer
->t_holdtime
);
2335 return BGP_FSM_SUCCESS
;
2338 /* Update packet is received. */
2339 static enum bgp_fsm_state_progress
bgp_fsm_update(struct peer
*peer
)
2341 THREAD_OFF(peer
->t_holdtime
);
2342 return BGP_FSM_SUCCESS
;
2345 /* This is empty event. */
2346 static enum bgp_fsm_state_progress
bgp_ignore(struct peer
*peer
)
2350 "%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d",
2351 peer
->host
, bgp_event_str
[peer
->cur_event
],
2352 lookup_msg(bgp_status_msg
, peer
->status
, NULL
),
2353 bgp_event_str
[peer
->last_event
],
2354 bgp_event_str
[peer
->last_major_event
], peer
->fd
);
2355 return BGP_FSM_SUCCESS
;
2358 /* This is to handle unexpected events.. */
2359 static enum bgp_fsm_state_progress
bgp_fsm_exception(struct peer
*peer
)
2363 "%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d",
2364 peer
->host
, bgp_event_str
[peer
->cur_event
],
2365 lookup_msg(bgp_status_msg
, peer
->status
, NULL
),
2366 bgp_event_str
[peer
->last_event
],
2367 bgp_event_str
[peer
->last_major_event
], peer
->fd
);
2368 return bgp_stop(peer
);
2371 void bgp_fsm_nht_update(struct peer
*peer
, bool has_valid_nexthops
)
2376 switch (peer
->status
) {
2378 if (has_valid_nexthops
)
2379 BGP_EVENT_ADD(peer
, BGP_Start
);
2382 if (!has_valid_nexthops
) {
2383 THREAD_OFF(peer
->t_connect
);
2384 BGP_EVENT_ADD(peer
, TCP_fatal_error
);
2388 if (has_valid_nexthops
) {
2389 THREAD_OFF(peer
->t_connect
);
2390 BGP_EVENT_ADD(peer
, ConnectRetry_timer_expired
);
2396 if (!has_valid_nexthops
2397 && (peer
->gtsm_hops
== BGP_GTSM_HOPS_CONNECTED
2398 || peer
->bgp
->fast_convergence
))
2399 BGP_EVENT_ADD(peer
, TCP_fatal_error
);
2402 case BGP_STATUS_MAX
:
2407 /* Finite State Machine structure */
2408 static const struct {
2409 enum bgp_fsm_state_progress (*func
)(struct peer
*);
2410 enum bgp_fsm_status next_state
;
2411 } FSM
[BGP_STATUS_MAX
- 1][BGP_EVENTS_MAX
- 1] = {
2413 /* Idle state: In Idle state, all events other than BGP_Start is
2414 ignored. With BGP_Start event, finite state machine calls
2416 {bgp_start
, Connect
}, /* BGP_Start */
2417 {bgp_stop
, Idle
}, /* BGP_Stop */
2418 {bgp_stop
, Idle
}, /* TCP_connection_open */
2419 {bgp_stop
, Idle
}, /* TCP_connection_open_w_delay */
2420 {bgp_stop
, Idle
}, /* TCP_connection_closed */
2421 {bgp_ignore
, Idle
}, /* TCP_connection_open_failed */
2422 {bgp_stop
, Idle
}, /* TCP_fatal_error */
2423 {bgp_ignore
, Idle
}, /* ConnectRetry_timer_expired */
2424 {bgp_ignore
, Idle
}, /* Hold_Timer_expired */
2425 {bgp_ignore
, Idle
}, /* KeepAlive_timer_expired */
2426 {bgp_ignore
, Idle
}, /* DelayOpen_timer_expired */
2427 {bgp_ignore
, Idle
}, /* Receive_OPEN_message */
2428 {bgp_ignore
, Idle
}, /* Receive_KEEPALIVE_message */
2429 {bgp_ignore
, Idle
}, /* Receive_UPDATE_message */
2430 {bgp_ignore
, Idle
}, /* Receive_NOTIFICATION_message */
2431 {bgp_ignore
, Idle
}, /* Clearing_Completed */
2435 {bgp_ignore
, Connect
}, /* BGP_Start */
2436 {bgp_stop
, Idle
}, /* BGP_Stop */
2437 {bgp_connect_success
, OpenSent
}, /* TCP_connection_open */
2438 {bgp_connect_success_w_delayopen
,
2439 Connect
}, /* TCP_connection_open_w_delay */
2440 {bgp_stop
, Idle
}, /* TCP_connection_closed */
2441 {bgp_connect_fail
, Active
}, /* TCP_connection_open_failed */
2442 {bgp_connect_fail
, Idle
}, /* TCP_fatal_error */
2443 {bgp_reconnect
, Connect
}, /* ConnectRetry_timer_expired */
2444 {bgp_fsm_exception
, Idle
}, /* Hold_Timer_expired */
2445 {bgp_fsm_exception
, Idle
}, /* KeepAlive_timer_expired */
2446 {bgp_fsm_delayopen_timer_expire
,
2447 OpenSent
}, /* DelayOpen_timer_expired */
2448 {bgp_fsm_open
, OpenConfirm
}, /* Receive_OPEN_message */
2449 {bgp_fsm_exception
, Idle
}, /* Receive_KEEPALIVE_message */
2450 {bgp_fsm_exception
, Idle
}, /* Receive_UPDATE_message */
2451 {bgp_stop
, Idle
}, /* Receive_NOTIFICATION_message */
2452 {bgp_fsm_exception
, Idle
}, /* Clearing_Completed */
2456 {bgp_ignore
, Active
}, /* BGP_Start */
2457 {bgp_stop
, Idle
}, /* BGP_Stop */
2458 {bgp_connect_success
, OpenSent
}, /* TCP_connection_open */
2459 {bgp_connect_success_w_delayopen
,
2460 Active
}, /* TCP_connection_open_w_delay */
2461 {bgp_stop
, Idle
}, /* TCP_connection_closed */
2462 {bgp_ignore
, Active
}, /* TCP_connection_open_failed */
2463 {bgp_fsm_exception
, Idle
}, /* TCP_fatal_error */
2464 {bgp_start
, Connect
}, /* ConnectRetry_timer_expired */
2465 {bgp_fsm_exception
, Idle
}, /* Hold_Timer_expired */
2466 {bgp_fsm_exception
, Idle
}, /* KeepAlive_timer_expired */
2467 {bgp_fsm_delayopen_timer_expire
,
2468 OpenSent
}, /* DelayOpen_timer_expired */
2469 {bgp_fsm_open
, OpenConfirm
}, /* Receive_OPEN_message */
2470 {bgp_fsm_exception
, Idle
}, /* Receive_KEEPALIVE_message */
2471 {bgp_fsm_exception
, Idle
}, /* Receive_UPDATE_message */
2472 {bgp_fsm_exception
, Idle
}, /* Receive_NOTIFICATION_message */
2473 {bgp_fsm_exception
, Idle
}, /* Clearing_Completed */
2477 {bgp_ignore
, OpenSent
}, /* BGP_Start */
2478 {bgp_stop
, Idle
}, /* BGP_Stop */
2479 {bgp_stop
, Active
}, /* TCP_connection_open */
2480 {bgp_fsm_exception
, Idle
}, /* TCP_connection_open_w_delay */
2481 {bgp_stop
, Active
}, /* TCP_connection_closed */
2482 {bgp_stop
, Active
}, /* TCP_connection_open_failed */
2483 {bgp_stop
, Active
}, /* TCP_fatal_error */
2484 {bgp_fsm_exception
, Idle
}, /* ConnectRetry_timer_expired */
2485 {bgp_fsm_holdtime_expire
, Idle
}, /* Hold_Timer_expired */
2486 {bgp_fsm_exception
, Idle
}, /* KeepAlive_timer_expired */
2487 {bgp_fsm_exception
, Idle
}, /* DelayOpen_timer_expired */
2488 {bgp_fsm_open
, OpenConfirm
}, /* Receive_OPEN_message */
2489 {bgp_fsm_event_error
, Idle
}, /* Receive_KEEPALIVE_message */
2490 {bgp_fsm_event_error
, Idle
}, /* Receive_UPDATE_message */
2491 {bgp_fsm_event_error
, Idle
}, /* Receive_NOTIFICATION_message */
2492 {bgp_fsm_exception
, Idle
}, /* Clearing_Completed */
2496 {bgp_ignore
, OpenConfirm
}, /* BGP_Start */
2497 {bgp_stop
, Idle
}, /* BGP_Stop */
2498 {bgp_stop
, Idle
}, /* TCP_connection_open */
2499 {bgp_fsm_exception
, Idle
}, /* TCP_connection_open_w_delay */
2500 {bgp_stop
, Idle
}, /* TCP_connection_closed */
2501 {bgp_stop
, Idle
}, /* TCP_connection_open_failed */
2502 {bgp_stop
, Idle
}, /* TCP_fatal_error */
2503 {bgp_fsm_exception
, Idle
}, /* ConnectRetry_timer_expired */
2504 {bgp_fsm_holdtime_expire
, Idle
}, /* Hold_Timer_expired */
2505 {bgp_ignore
, OpenConfirm
}, /* KeepAlive_timer_expired */
2506 {bgp_fsm_exception
, Idle
}, /* DelayOpen_timer_expired */
2507 {bgp_fsm_exception
, Idle
}, /* Receive_OPEN_message */
2508 {bgp_establish
, Established
}, /* Receive_KEEPALIVE_message */
2509 {bgp_fsm_exception
, Idle
}, /* Receive_UPDATE_message */
2510 {bgp_stop_with_error
, Idle
}, /* Receive_NOTIFICATION_message */
2511 {bgp_fsm_exception
, Idle
}, /* Clearing_Completed */
2515 {bgp_ignore
, Established
}, /* BGP_Start */
2516 {bgp_stop
, Clearing
}, /* BGP_Stop */
2517 {bgp_stop
, Clearing
}, /* TCP_connection_open */
2518 {bgp_fsm_exception
, Idle
}, /* TCP_connection_open_w_delay */
2519 {bgp_stop
, Clearing
}, /* TCP_connection_closed */
2520 {bgp_stop
, Clearing
}, /* TCP_connection_open_failed */
2521 {bgp_stop
, Clearing
}, /* TCP_fatal_error */
2522 {bgp_stop
, Clearing
}, /* ConnectRetry_timer_expired */
2523 {bgp_fsm_holdtime_expire
, Clearing
}, /* Hold_Timer_expired */
2524 {bgp_ignore
, Established
}, /* KeepAlive_timer_expired */
2525 {bgp_fsm_exception
, Idle
}, /* DelayOpen_timer_expired */
2526 {bgp_stop
, Clearing
}, /* Receive_OPEN_message */
2528 Established
}, /* Receive_KEEPALIVE_message */
2529 {bgp_fsm_update
, Established
}, /* Receive_UPDATE_message */
2530 {bgp_stop_with_error
,
2531 Clearing
}, /* Receive_NOTIFICATION_message */
2532 {bgp_fsm_exception
, Idle
}, /* Clearing_Completed */
2536 {bgp_ignore
, Clearing
}, /* BGP_Start */
2537 {bgp_stop
, Clearing
}, /* BGP_Stop */
2538 {bgp_stop
, Clearing
}, /* TCP_connection_open */
2539 {bgp_stop
, Clearing
}, /* TCP_connection_open_w_delay */
2540 {bgp_stop
, Clearing
}, /* TCP_connection_closed */
2541 {bgp_stop
, Clearing
}, /* TCP_connection_open_failed */
2542 {bgp_stop
, Clearing
}, /* TCP_fatal_error */
2543 {bgp_stop
, Clearing
}, /* ConnectRetry_timer_expired */
2544 {bgp_stop
, Clearing
}, /* Hold_Timer_expired */
2545 {bgp_stop
, Clearing
}, /* KeepAlive_timer_expired */
2546 {bgp_stop
, Clearing
}, /* DelayOpen_timer_expired */
2547 {bgp_stop
, Clearing
}, /* Receive_OPEN_message */
2548 {bgp_stop
, Clearing
}, /* Receive_KEEPALIVE_message */
2549 {bgp_stop
, Clearing
}, /* Receive_UPDATE_message */
2550 {bgp_stop
, Clearing
}, /* Receive_NOTIFICATION_message */
2551 {bgp_clearing_completed
, Idle
}, /* Clearing_Completed */
2555 {bgp_ignore
, Deleted
}, /* BGP_Start */
2556 {bgp_ignore
, Deleted
}, /* BGP_Stop */
2557 {bgp_ignore
, Deleted
}, /* TCP_connection_open */
2558 {bgp_ignore
, Deleted
}, /* TCP_connection_open_w_delay */
2559 {bgp_ignore
, Deleted
}, /* TCP_connection_closed */
2560 {bgp_ignore
, Deleted
}, /* TCP_connection_open_failed */
2561 {bgp_ignore
, Deleted
}, /* TCP_fatal_error */
2562 {bgp_ignore
, Deleted
}, /* ConnectRetry_timer_expired */
2563 {bgp_ignore
, Deleted
}, /* Hold_Timer_expired */
2564 {bgp_ignore
, Deleted
}, /* KeepAlive_timer_expired */
2565 {bgp_ignore
, Deleted
}, /* DelayOpen_timer_expired */
2566 {bgp_ignore
, Deleted
}, /* Receive_OPEN_message */
2567 {bgp_ignore
, Deleted
}, /* Receive_KEEPALIVE_message */
2568 {bgp_ignore
, Deleted
}, /* Receive_UPDATE_message */
2569 {bgp_ignore
, Deleted
}, /* Receive_NOTIFICATION_message */
2570 {bgp_ignore
, Deleted
}, /* Clearing_Completed */
2574 /* Execute event process. */
2575 void bgp_event(struct thread
*thread
)
2577 enum bgp_fsm_events event
;
2580 peer
= THREAD_ARG(thread
);
2581 event
= THREAD_VAL(thread
);
2584 bgp_event_update(peer
, event
);
2588 int bgp_event_update(struct peer
*peer
, enum bgp_fsm_events event
)
2590 enum bgp_fsm_status next
;
2591 enum bgp_fsm_state_progress ret
= 0;
2593 int passive_conn
= 0;
2596 /* default return code */
2597 ret
= FSM_PEER_NOOP
;
2599 other
= peer
->doppelganger
;
2601 (CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
)) ? 1 : 0;
2602 dyn_nbr
= peer_dynamic_neighbor(peer
);
2604 /* Logging this event. */
2605 next
= FSM
[peer
->status
- 1][event
- 1].next_state
;
2607 if (bgp_debug_neighbor_events(peer
) && peer
->status
!= next
)
2608 zlog_debug("%s [FSM] %s (%s->%s), fd %d", peer
->host
,
2609 bgp_event_str
[event
],
2610 lookup_msg(bgp_status_msg
, peer
->status
, NULL
),
2611 lookup_msg(bgp_status_msg
, next
, NULL
), peer
->fd
);
2613 peer
->last_event
= peer
->cur_event
;
2614 peer
->cur_event
= event
;
2616 /* Call function. */
2617 if (FSM
[peer
->status
- 1][event
- 1].func
)
2618 ret
= (*(FSM
[peer
->status
- 1][event
- 1].func
))(peer
);
2620 if (ret
>= BGP_FSM_SUCCESS
) {
2621 if (ret
== BGP_FSM_SUCCESS_STATE_TRANSFER
&&
2622 next
== Established
) {
2623 /* The case when doppelganger swap accurred in
2625 Update the peer pointer accordingly */
2626 ret
= FSM_PEER_TRANSFERRED
;
2630 /* If status is changed. */
2631 if (next
!= peer
->status
) {
2632 bgp_fsm_change_status(peer
, next
);
2635 * If we're going to ESTABLISHED then we executed a
2636 * peer transfer. In this case we can either return
2637 * FSM_PEER_TRANSITIONED or FSM_PEER_TRANSFERRED.
2638 * Opting for TRANSFERRED since transfer implies
2639 * session establishment.
2641 if (ret
!= FSM_PEER_TRANSFERRED
)
2642 ret
= FSM_PEER_TRANSITIONED
;
2645 /* Make sure timer is set. */
2646 bgp_timer_set(peer
);
2650 * If we got a return value of -1, that means there was an
2651 * error, restart the FSM. Since bgp_stop() was called on the
2652 * peer. only a few fields are safe to access here. In any case
2653 * we need to indicate that the peer was stopped in the return
2656 if (!dyn_nbr
&& !passive_conn
&& peer
->bgp
&&
2657 ret
!= BGP_FSM_FAILURE_AND_DELETE
) {
2660 "%s [FSM] Failure handling event %s in state %s, prior events %s, %s, fd %d",
2661 peer
->host
, bgp_event_str
[peer
->cur_event
],
2662 lookup_msg(bgp_status_msg
, peer
->status
, NULL
),
2663 bgp_event_str
[peer
->last_event
],
2664 bgp_event_str
[peer
->last_major_event
],
2667 bgp_fsm_change_status(peer
, Idle
);
2668 bgp_timer_set(peer
);
2670 ret
= FSM_PEER_STOPPED
;
2677 int bgp_gr_lookup_n_update_all_peer(struct bgp
*bgp
,
2678 enum global_mode global_new_state
,
2679 enum global_mode global_old_state
)
2681 struct peer
*peer
= {0};
2682 struct listnode
*node
= {0};
2683 struct listnode
*nnode
= {0};
2684 enum peer_mode peer_old_state
= PEER_INVALID
;
2686 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
2688 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2689 zlog_debug("%s [BGP_GR] Peer: (%s) :", __func__
,
2692 peer_old_state
= bgp_peer_gr_mode_get(peer
);
2694 if (peer_old_state
== PEER_GLOBAL_INHERIT
) {
2697 *Reset only these peers and send a
2698 *new open message with the change capabilities.
2699 *Considering the mode to be "global_new_state" and
2700 *do all operation accordingly
2703 switch (global_new_state
) {
2705 BGP_PEER_GR_HELPER_ENABLE(peer
);
2708 BGP_PEER_GR_ENABLE(peer
);
2710 case GLOBAL_DISABLE
:
2711 BGP_PEER_GR_DISABLE(peer
);
2713 case GLOBAL_INVALID
:
2714 zlog_debug("%s [BGP_GR] GLOBAL_INVALID",
2716 return BGP_ERR_GR_OPERATION_FAILED
;
2721 bgp
->global_gr_present_state
= global_new_state
;
2723 return BGP_GR_SUCCESS
;
2726 int bgp_gr_update_all(struct bgp
*bgp
, int global_gr_cmd
)
2728 enum global_mode global_new_state
= GLOBAL_INVALID
;
2729 enum global_mode global_old_state
= GLOBAL_INVALID
;
2731 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2732 zlog_debug("%s [BGP_GR]START: global_gr_cmd :%s:", __func__
,
2733 print_global_gr_cmd(global_gr_cmd
));
2735 global_old_state
= bgp_global_gr_mode_get(bgp
);
2737 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2738 zlog_debug("[BGP_GR] global_old_gr_state :%s:",
2739 print_global_gr_mode(global_old_state
));
2741 if (global_old_state
!= GLOBAL_INVALID
) {
2743 bgp
->GLOBAL_GR_FSM
[global_old_state
][global_gr_cmd
];
2745 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2746 zlog_debug("[BGP_GR] global_new_gr_state :%s:",
2747 print_global_gr_mode(global_new_state
));
2749 zlog_err("%s [BGP_GR] global_old_state == GLOBAL_INVALID",
2751 return BGP_ERR_GR_OPERATION_FAILED
;
2754 if (global_new_state
== GLOBAL_INVALID
) {
2755 zlog_err("%s [BGP_GR] global_new_state == GLOBAL_INVALID",
2757 return BGP_ERR_GR_INVALID_CMD
;
2759 if (global_new_state
== global_old_state
) {
2761 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2763 "%s [BGP_GR] global_new_state == global_old_state :%s",
2765 print_global_gr_mode(global_new_state
));
2766 return BGP_GR_NO_OPERATION
;
2769 return bgp_gr_lookup_n_update_all_peer(bgp
, global_new_state
,
2773 const char *print_peer_gr_mode(enum peer_mode pr_mode
)
2775 const char *peer_gr_mode
= NULL
;
2779 peer_gr_mode
= "PEER_HELPER";
2782 peer_gr_mode
= "PEER_GR";
2785 peer_gr_mode
= "PEER_DISABLE";
2788 peer_gr_mode
= "PEER_INVALID";
2790 case PEER_GLOBAL_INHERIT
:
2791 peer_gr_mode
= "PEER_GLOBAL_INHERIT";
2795 return peer_gr_mode
;
2798 const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd
)
2800 const char *peer_gr_cmd
= NULL
;
2802 switch (pr_gr_cmd
) {
2804 peer_gr_cmd
= "PEER_GR_CMD";
2806 case NO_PEER_GR_CMD
:
2807 peer_gr_cmd
= "NO_PEER_GR_CMD";
2809 case PEER_DISABLE_CMD
:
2810 peer_gr_cmd
= "PEER_DISABLE_GR_CMD";
2812 case NO_PEER_DISABLE_CMD
:
2813 peer_gr_cmd
= "NO_PEER_DISABLE_GR_CMD";
2815 case PEER_HELPER_CMD
:
2816 peer_gr_cmd
= "PEER_HELPER_CMD";
2818 case NO_PEER_HELPER_CMD
:
2819 peer_gr_cmd
= "NO_PEER_HELPER_CMD";
2826 const char *print_global_gr_mode(enum global_mode gl_mode
)
2828 const char *global_gr_mode
= "???";
2832 global_gr_mode
= "GLOBAL_HELPER";
2835 global_gr_mode
= "GLOBAL_GR";
2837 case GLOBAL_DISABLE
:
2838 global_gr_mode
= "GLOBAL_DISABLE";
2840 case GLOBAL_INVALID
:
2841 global_gr_mode
= "GLOBAL_INVALID";
2845 return global_gr_mode
;
2848 const char *print_global_gr_cmd(enum global_gr_command gl_gr_cmd
)
2850 const char *global_gr_cmd
= NULL
;
2852 switch (gl_gr_cmd
) {
2854 global_gr_cmd
= "GLOBAL_GR_CMD";
2856 case NO_GLOBAL_GR_CMD
:
2857 global_gr_cmd
= "NO_GLOBAL_GR_CMD";
2859 case GLOBAL_DISABLE_CMD
:
2860 global_gr_cmd
= "GLOBAL_DISABLE_CMD";
2862 case NO_GLOBAL_DISABLE_CMD
:
2863 global_gr_cmd
= "NO_GLOBAL_DISABLE_CMD";
2867 return global_gr_cmd
;
2870 enum global_mode
bgp_global_gr_mode_get(struct bgp
*bgp
)
2872 return bgp
->global_gr_present_state
;
2875 enum peer_mode
bgp_peer_gr_mode_get(struct peer
*peer
)
2877 return peer
->peer_gr_present_state
;
2880 int bgp_neighbor_graceful_restart(struct peer
*peer
, int peer_gr_cmd
)
2882 enum peer_mode peer_new_state
= PEER_INVALID
;
2883 enum peer_mode peer_old_state
= PEER_INVALID
;
2884 struct bgp_peer_gr peer_state
;
2885 int result
= BGP_GR_FAILURE
;
2888 * fetch peer_old_state from peer structure also
2889 * fetch global_old_state from bgp structure,
2890 * peer had a back pointer to bgpo struct ;
2893 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2894 zlog_debug("%s [BGP_GR] START:Peer: (%s) : peer_gr_cmd :%s:",
2895 __func__
, peer
->host
,
2896 print_peer_gr_cmd(peer_gr_cmd
));
2898 peer_old_state
= bgp_peer_gr_mode_get(peer
);
2900 if (peer_old_state
== PEER_INVALID
) {
2901 zlog_debug("[BGP_GR] peer_old_state == Invalid state !");
2902 return BGP_ERR_GR_OPERATION_FAILED
;
2905 peer_state
= peer
->PEER_GR_FSM
[peer_old_state
][peer_gr_cmd
];
2906 peer_new_state
= peer_state
.next_state
;
2908 if (peer_new_state
== PEER_INVALID
) {
2910 "[BGP_GR] Invalid bgp graceful restart command used !");
2911 return BGP_ERR_GR_INVALID_CMD
;
2914 if (peer_new_state
!= peer_old_state
) {
2915 result
= peer_state
.action_fun(peer
, peer_old_state
,
2918 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2920 "[BGP_GR] peer_old_state == peer_new_state !");
2921 return BGP_GR_NO_OPERATION
;
2924 if (result
== BGP_GR_SUCCESS
) {
2926 /* Update the mode i.e peer_new_state into the peer structure */
2927 peer
->peer_gr_present_state
= peer_new_state
;
2928 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2930 "[BGP_GR] Successfully change the state of the peer to : %s : !",
2931 print_peer_gr_mode(peer_new_state
));
2933 return BGP_GR_SUCCESS
;
2939 unsigned int bgp_peer_gr_action(struct peer
*peer
, int old_peer_state
,
2942 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2944 "%s [BGP_GR] Move peer from old_peer_state :%s: to new_peer_state :%s: !!!!",
2945 __func__
, print_peer_gr_mode(old_peer_state
),
2946 print_peer_gr_mode(new_peer_state
));
2948 int bgp_gr_global_mode
= GLOBAL_INVALID
;
2949 unsigned int ret
= BGP_GR_FAILURE
;
2951 if (old_peer_state
== new_peer_state
) {
2952 /* Nothing to do over here as the present and old state is the
2954 return BGP_GR_NO_OPERATION
;
2956 if ((old_peer_state
== PEER_INVALID
)
2957 || (new_peer_state
== PEER_INVALID
)) {
2958 /* something bad happend , print error message */
2959 return BGP_ERR_GR_INVALID_CMD
;
2962 bgp_gr_global_mode
= bgp_global_gr_mode_get(peer
->bgp
);
2964 if ((old_peer_state
== PEER_GLOBAL_INHERIT
)
2965 && (new_peer_state
!= PEER_GLOBAL_INHERIT
)) {
2967 /* fetch the Mode running in the Global state machine
2968 *from the bgp structure into a variable called
2972 /* Here we are checking if the
2973 *1. peer_new_state == global_mode == helper_mode
2974 *2. peer_new_state == global_mode == GR_mode
2975 *3. peer_new_state == global_mode == disabled_mode
2978 BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer
);
2980 if (new_peer_state
== bgp_gr_global_mode
) {
2981 /*This is incremental updates i.e no tear down
2982 *of the existing session
2983 *as the peer is already working in the same mode.
2985 ret
= BGP_GR_SUCCESS
;
2987 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2989 "[BGP_GR] Peer state changed from :%s ",
2990 print_peer_gr_mode(old_peer_state
));
2992 bgp_peer_move_to_gr_mode(peer
, new_peer_state
);
2994 ret
= BGP_GR_SUCCESS
;
2997 /* In the case below peer is going into Global inherit mode i.e.
2998 * the peer would work as the mode configured at the global level
3000 else if ((new_peer_state
== PEER_GLOBAL_INHERIT
)
3001 && (old_peer_state
!= PEER_GLOBAL_INHERIT
)) {
3002 /* Here in this case it would be destructive
3003 * in all the cases except one case when,
3004 * Global GR is configured Disabled
3005 * and present_peer_state is not disable
3008 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer
);
3010 if (old_peer_state
== bgp_gr_global_mode
) {
3012 /* This is incremental updates
3013 *i.e no tear down of the existing session
3014 *as the peer is already working in the same mode.
3016 ret
= BGP_GR_SUCCESS
;
3018 /* Destructive always */
3019 /* Tear down the old session
3020 * and send the new capability
3021 * as per the bgp_gr_global_mode
3024 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3026 "[BGP_GR] Peer state changed from :%s",
3027 print_peer_gr_mode(old_peer_state
));
3029 bgp_peer_move_to_gr_mode(peer
, bgp_gr_global_mode
);
3031 ret
= BGP_GR_SUCCESS
;
3035 *This else case, it include all the cases except -->
3036 *(new_peer_state != Peer_Global) &&
3037 *( old_peer_state != Peer_Global )
3039 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3040 zlog_debug("[BGP_GR] Peer state changed from :%s",
3041 print_peer_gr_mode(old_peer_state
));
3043 bgp_peer_move_to_gr_mode(peer
, new_peer_state
);
3045 ret
= BGP_GR_SUCCESS
;
3051 inline void bgp_peer_move_to_gr_mode(struct peer
*peer
, int new_state
)
3054 int bgp_global_gr_mode
= bgp_global_gr_mode_get(peer
->bgp
);
3056 switch (new_state
) {
3058 BGP_PEER_GR_HELPER_ENABLE(peer
);
3061 BGP_PEER_GR_ENABLE(peer
);
3064 BGP_PEER_GR_DISABLE(peer
);
3066 case PEER_GLOBAL_INHERIT
:
3067 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer
);
3069 if (bgp_global_gr_mode
== GLOBAL_HELPER
) {
3070 BGP_PEER_GR_HELPER_ENABLE(peer
);
3071 } else if (bgp_global_gr_mode
== GLOBAL_GR
) {
3072 BGP_PEER_GR_ENABLE(peer
);
3073 } else if (bgp_global_gr_mode
== GLOBAL_DISABLE
) {
3074 BGP_PEER_GR_DISABLE(peer
);
3077 "[BGP_GR] Default switch inherit mode ::: SOMETHING IS WRONG !!!");
3082 "[BGP_GR] Default switch mode ::: SOMETHING IS WRONG !!!");
3085 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3086 zlog_debug("[BGP_GR] Peer state changed --to--> : %d : !",
3090 void bgp_peer_gr_flags_update(struct peer
*peer
)
3092 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3093 zlog_debug("%s [BGP_GR] called !", __func__
);
3094 if (CHECK_FLAG(peer
->peer_gr_new_status_flag
,
3095 PEER_GRACEFUL_RESTART_NEW_STATE_HELPER
))
3096 SET_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART_HELPER
);
3098 UNSET_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART_HELPER
);
3099 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3101 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !",
3103 (CHECK_FLAG(peer
->flags
,
3104 PEER_FLAG_GRACEFUL_RESTART_HELPER
)
3107 if (CHECK_FLAG(peer
->peer_gr_new_status_flag
,
3108 PEER_GRACEFUL_RESTART_NEW_STATE_RESTART
))
3109 SET_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART
);
3111 UNSET_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART
);
3112 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3114 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !",
3116 (CHECK_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART
)
3119 if (CHECK_FLAG(peer
->peer_gr_new_status_flag
,
3120 PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT
))
3121 SET_FLAG(peer
->flags
,
3122 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
);
3124 UNSET_FLAG(peer
->flags
,
3125 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
);
3126 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3128 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !",
3130 (CHECK_FLAG(peer
->flags
,
3131 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
)
3135 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART
)
3136 && !CHECK_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART_HELPER
)) {
3137 zlog_debug("[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_MODE!",
3140 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
3142 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)) {
3144 peer_nsf_stop(peer
);
3146 "[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_WAIT!",