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 event
*event
);
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
);
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 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
);
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 event_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 EVENT_OFF(peer
->t_start
);
369 BGP_TIMER_ON(peer
->t_start
, bgp_start_timer
,
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
);
380 /* After start timer is expired, the peer moves to Connect
381 status. Make sure start timer is off and connect timer is
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
));
388 BGP_TIMER_ON(peer
->t_connect
, bgp_connect_timer
,
391 EVENT_OFF(peer
->t_holdtime
);
392 bgp_keepalives_off(peer
);
393 EVENT_OFF(peer
->t_routeadv
);
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
);
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 EVENT_OFF(peer
->t_holdtime
);
414 bgp_keepalives_off(peer
);
415 EVENT_OFF(peer
->t_routeadv
);
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
,
426 EVENT_OFF(peer
->t_holdtime
);
428 bgp_keepalives_off(peer
);
429 EVENT_OFF(peer
->t_routeadv
);
430 EVENT_OFF(peer
->t_delayopen
);
434 /* OpenConfirm status. */
435 EVENT_OFF(peer
->t_start
);
436 EVENT_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 EVENT_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 EVENT_OFF(peer
->t_routeadv
);
453 EVENT_OFF(peer
->t_delayopen
);
457 /* In Established status start and connect timer is turned
459 EVENT_OFF(peer
->t_start
);
460 EVENT_OFF(peer
->t_connect
);
461 EVENT_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 EVENT_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 EVENT_OFF(peer
->t_gr_restart
);
480 EVENT_OFF(peer
->t_gr_stale
);
482 FOREACH_AFI_SAFI (afi
, safi
)
483 EVENT_OFF(peer
->t_llgr_stale
[afi
][safi
]);
485 EVENT_OFF(peer
->t_pmax_restart
);
486 EVENT_OFF(peer
->t_refresh_stalepath
);
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
);
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 event
*thread
)
509 peer
= EVENT_ARG(thread
);
511 if (bgp_debug_neighbor_events(peer
))
512 zlog_debug("%s [FSM] Timer (start timer expire).", peer
->host
);
514 EVENT_VAL(thread
) = BGP_Start
;
515 bgp_event(thread
); /* bgp_event unlocks peer */
518 /* BGP connect retry timer. */
519 static void bgp_connect_timer(struct event
*thread
)
523 peer
= EVENT_ARG(thread
);
525 /* stop the DelayOpenTimer if it is running */
526 EVENT_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 EVENT_VAL(thread
) = ConnectRetry_timer_expired
;
538 bgp_event(thread
); /* bgp_event unlocks peer */
542 /* BGP holdtime timer. */
543 static void bgp_holdtime_timer(struct event
*thread
)
545 atomic_size_t inq_count
;
548 peer
= EVENT_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 EVENT_VAL(thread
) = Hold_Timer_expired
;
571 bgp_event(thread
); /* bgp_event unlocks peer */
574 void bgp_routeadv_timer(struct event
*thread
)
578 peer
= EVENT_ARG(thread
);
580 if (bgp_debug_neighbor_events(peer
))
581 zlog_debug("%s [FSM] Timer (routeadv timer expire)",
584 peer
->synctime
= monotime(NULL
);
586 event_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 event
*thread
)
599 peer
= EVENT_ARG(thread
);
601 if (bgp_debug_neighbor_events(peer
))
602 zlog_debug("%s [FSM] Timer (DelayOpentimer expire)",
605 EVENT_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 EVENT_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 event
*thread
)
678 paf
= EVENT_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 event
*thread
)
775 struct peer
*peer
, *tmp_peer
;
776 struct listnode
*node
, *nnode
;
781 peer
= EVENT_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 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
]);
827 for (ALL_LIST_ELEMENTS(peer
->bgp
->peer
, node
, nnode
,
829 bgp_announce_route(tmp_peer
, afi
, safi
, false);
831 bgp_clear_stale_route(peer
, afi
, safi
);
835 bgp_graceful_restart_timer_off(peer
);
838 static void bgp_graceful_stale_timer_expire(struct event
*thread
)
844 peer
= EVENT_ARG(thread
);
846 if (bgp_debug_neighbor_events(peer
))
847 zlog_debug("%pBP graceful restart stalepath timer expired",
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
);
856 /* Selection deferral timer processing function */
857 static void bgp_graceful_deferral_timer_expire(struct event
*thread
)
859 struct afi_safi_info
*info
;
864 info
= EVENT_ARG(thread
);
869 if (BGP_DEBUG(update
, UPDATE_OUT
))
871 "afi %d, safi %d : graceful restart deferral timer expired",
874 bgp
->gr_info
[afi
][safi
].eor_required
= 0;
875 bgp
->gr_info
[afi
][safi
].eor_received
= 0;
876 XFREE(MTYPE_TMP
, info
);
878 /* Best path selection */
879 bgp_best_path_select_defer(bgp
, afi
, safi
);
882 static bool bgp_update_delay_applicable(struct bgp
*bgp
)
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
888 if (!bgp
->update_delay_over
)
893 bool bgp_update_delay_active(struct bgp
*bgp
)
895 if (bgp
->t_update_delay
)
900 bool bgp_update_delay_configured(struct bgp
*bgp
)
902 if (bgp
->v_update_delay
)
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
)
911 EVENT_OFF(bgp
->t_update_delay
);
912 EVENT_OFF(bgp
->t_establish_wait
);
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;
921 frr_timestamp(3, bgp
->update_delay_end_time
,
922 sizeof(bgp
->update_delay_end_time
));
925 * Add an end-of-initial-update marker to the main process queues so
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
932 * (routes in BGP are updated, and peers sync queues are populated
934 * 2. As the eoiu mark is reached in the bgp process routine, ship all
936 * routes to zebra. With that zebra should see updates from BGP
939 * 3. Unblock the peer update writes. With that peer update packing
941 * the prefixes should be at its maximum.
943 bgp_add_eoiu_mark(bgp
);
944 bgp
->main_zebra_update_hold
= 1;
945 bgp
->main_peers_update_hold
= 1;
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
952 work_queue_unplug(bgp
->process_queue
);
958 void bgp_start_routeadv(struct bgp
*bgp
)
960 struct listnode
*node
, *nnode
;
963 zlog_info("%s, update hold status %d", __func__
,
964 bgp
->main_peers_update_hold
);
966 if (bgp
->main_peers_update_hold
)
969 frr_timestamp(3, bgp
->update_delay_peers_resume_time
,
970 sizeof(bgp
->update_delay_peers_resume_time
));
972 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
973 if (!peer_established(peer
))
975 EVENT_OFF(peer
->t_routeadv
);
976 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, 0);
983 void bgp_adjust_routeadv(struct peer
*peer
)
985 time_t nowtime
= monotime(NULL
);
987 unsigned long remain
;
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
993 * duration and schedule write thread immediately.
995 EVENT_OFF(peer
->t_routeadv
);
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
1003 BGP_UPDATE_GROUP_TIMER_ON(&peer
->t_generate_updgrp_packets
,
1004 bgp_generate_updgrp_packets
);
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.
1014 * <------- MRAI --------->
1015 * |-----------------|-----------------------|
1016 * <------------- m ------------>
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);
1034 * - Find when to expire the MRAI timer.
1035 * If MRAI timer is not active, assume we can start it now.
1037 * <------- MRAI --------->
1038 * |------------|-----------------------|
1039 * <-------- m ----------><----- r ----->
1048 if (peer
->t_routeadv
)
1049 remain
= event_timer_remain_second(peer
->t_routeadv
);
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
);
1059 static bool bgp_maxmed_onstartup_applicable(struct bgp
*bgp
)
1061 if (!bgp
->maxmed_onstartup_over
)
1066 bool bgp_maxmed_onstartup_configured(struct bgp
*bgp
)
1068 if (bgp
->v_maxmed_onstartup
!= BGP_MAXMED_ONSTARTUP_UNCONFIGURED
)
1073 bool bgp_maxmed_onstartup_active(struct bgp
*bgp
)
1075 if (bgp
->t_maxmed_onstartup
)
1080 void bgp_maxmed_update(struct bgp
*bgp
)
1082 uint8_t maxmed_active
;
1083 uint32_t maxmed_value
;
1085 if (bgp
->v_maxmed_admin
) {
1087 maxmed_value
= bgp
->maxmed_admin_value
;
1088 } else if (bgp
->t_maxmed_onstartup
) {
1090 maxmed_value
= bgp
->maxmed_onstartup_value
;
1093 maxmed_value
= BGP_MAXMED_VALUE_DEFAULT
;
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
;
1101 update_group_announce(bgp
);
1105 int bgp_fsm_error_subcode(int status
)
1107 int fsm_err_subcode
= BGP_NOTIFY_FSM_ERR_SUBCODE_UNSPECIFIC
;
1111 fsm_err_subcode
= BGP_NOTIFY_FSM_ERR_SUBCODE_OPENSENT
;
1114 fsm_err_subcode
= BGP_NOTIFY_FSM_ERR_SUBCODE_OPENCONFIRM
;
1117 fsm_err_subcode
= BGP_NOTIFY_FSM_ERR_SUBCODE_ESTABLISHED
;
1123 return fsm_err_subcode
;
1126 /* The maxmed onstartup timer expiry callback. */
1127 static void bgp_maxmed_onstartup_timer(struct event
*thread
)
1131 zlog_info("Max med on startup ended - timer expired.");
1133 bgp
= EVENT_ARG(thread
);
1134 EVENT_OFF(bgp
->t_maxmed_onstartup
);
1135 bgp
->maxmed_onstartup_over
= 1;
1137 bgp_maxmed_update(bgp
);
1140 static void bgp_maxmed_onstartup_begin(struct bgp
*bgp
)
1142 /* Applicable only once in the process lifetime on the startup */
1143 if (bgp
->maxmed_onstartup_over
)
1146 zlog_info("Begin maxmed onstartup mode - timer %d seconds",
1147 bgp
->v_maxmed_onstartup
);
1149 event_add_timer(bm
->master
, bgp_maxmed_onstartup_timer
, bgp
,
1150 bgp
->v_maxmed_onstartup
, &bgp
->t_maxmed_onstartup
);
1152 if (!bgp
->v_maxmed_admin
) {
1153 bgp
->maxmed_active
= 1;
1154 bgp
->maxmed_value
= bgp
->maxmed_onstartup_value
;
1157 /* Route announce to all peers should happen after this in
1158 * bgp_establish() */
1161 static void bgp_maxmed_onstartup_process_status_change(struct peer
*peer
)
1163 if (peer_established(peer
) && !peer
->bgp
->established
) {
1164 bgp_maxmed_onstartup_begin(peer
->bgp
);
1168 /* The update delay timer expiry callback. */
1169 static void bgp_update_delay_timer(struct event
*thread
)
1173 zlog_info("Update delay ended - timer expired.");
1175 bgp
= EVENT_ARG(thread
);
1176 EVENT_OFF(bgp
->t_update_delay
);
1177 bgp_update_delay_end(bgp
);
1180 /* The establish wait timer expiry callback. */
1181 static void bgp_establish_wait_timer(struct event
*thread
)
1185 zlog_info("Establish wait - timer expired.");
1187 bgp
= EVENT_ARG(thread
);
1188 EVENT_OFF(bgp
->t_establish_wait
);
1189 bgp_check_update_delay(bgp
);
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
)
1198 struct listnode
*node
, *nnode
;
1201 /* Stop the processing of queued work. Enqueue shall continue */
1202 work_queue_plug(bgp
->process_queue
);
1204 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
1205 peer
->update_delay_over
= 0;
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
);
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
);
1215 frr_timestamp(3, bgp
->update_delay_begin_time
,
1216 sizeof(bgp
->update_delay_begin_time
));
1219 static void bgp_update_delay_process_status_change(struct peer
*peer
)
1221 if (peer_established(peer
)) {
1222 if (!peer
->bgp
->established
++) {
1223 bgp_update_delay_begin(peer
->bgp
);
1225 "Begin read-only mode - update-delay timer %d seconds",
1226 peer
->bgp
->v_update_delay
);
1228 if (CHECK_FLAG(peer
->cap
, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV
))
1229 bgp_update_restarted_peers(peer
);
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
1236 counters. Extra sanity check in bgp_check_update_delay()
1238 be enough to take care of any additive discrepancy in bgp eor
1240 peer
->bgp
->established
--;
1241 peer
->update_delay_over
= 0;
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
)
1250 uint32_t peer_count
;
1253 peer_count
= bgp
->established_peers
;
1255 if (status
== Established
)
1256 bgp
->established_peers
++;
1257 else if ((peer_established(peer
)) && (status
!= Established
))
1258 bgp
->established_peers
--;
1260 if (bgp_debug_neighbor_events(peer
)) {
1261 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
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
);
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
1272 if ((peer_count
!= bgp
->established_peers
) &&
1273 (bgp
->established_peers
== 0))
1274 bgp_router_id_zebra_bump(bgp
->vrf_id
, NULL
);
1276 /* Transition into Clearing or Deleted must /always/ clear all routes..
1277 * (and must do so before actually changing into Deleted..
1279 if (status
>= Clearing
) {
1280 bgp_clear_route_all(peer
);
1282 /* If no route was queued for the clear-node processing,
1284 * completion event here. This is needed because if there are no
1286 * to trigger the background clear-node thread, the event won't
1288 * generated and the peer would be stuck in Clearing. Note that
1290 * event is for the peer and helps the peer transition out of
1292 * state; it should not be generated per (AFI,SAFI). The event
1294 * directly posted here without calling clear_node_complete() as
1296 * shouldn't do an extra unlock. This event will get processed
1298 * the state change that happens below, so peer will be in
1302 if (!work_queue_is_scheduled(peer
->clear_node_queue
) &&
1304 BGP_EVENT_ADD(peer
, Clearing_Completed
);
1307 /* Preserve old status and change into new status. */
1308 peer
->ostatus
= peer
->status
;
1309 peer
->status
= status
;
1311 /* Reset received keepalives counter on every FSM change */
1312 peer
->rtt_keepalive_rcv
= 0;
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
);
1318 /* Save event that caused status change. */
1319 peer
->last_major_event
= peer
->cur_event
;
1321 /* Operations after status change */
1322 hook_call(peer_status_changed
, peer
);
1324 if (status
== Established
)
1325 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
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
);
1333 peer
->bgp
->maxmed_onstartup_over
= 1;
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
);
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
));
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
)
1350 enum bgp_fsm_state_progress rc
= bgp_stop(peer
);
1352 if (rc
>= BGP_FSM_SUCCESS
)
1353 BGP_EVENT_FLUSH(peer
);
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
)
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
;
1369 peer
->nsf_af_count
= 0;
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
);
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__
);
1382 return BGP_FSM_FAILURE_AND_DELETE
;
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
);
1391 /* Increment Dropped count. */
1392 if (peer_established(peer
)) {
1395 /* Notify BGP conditional advertisement process */
1396 peer
->advmap_table_change
= true;
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
);
1404 "%%ADJCHANGE: neighbor %pBP in vrf %s Down %s",
1406 vrf
? ((vrf
->vrf_id
!= VRF_DEFAULT
)
1410 peer_down_str
[(int)peer
->last_reset
]);
1413 /* graceful restart */
1414 if (peer
->t_gr_stale
) {
1415 EVENT_OFF(peer
->t_gr_stale
);
1416 if (bgp_debug_neighbor_events(peer
))
1418 "%pBP graceful restart stalepath timer stopped",
1421 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)) {
1422 if (bgp_debug_neighbor_events(peer
)) {
1424 "%pBP graceful restart timer started for %d sec",
1425 peer
, peer
->v_gr_restart
);
1427 "%pBP graceful restart stalepath timer started for %d sec",
1428 peer
, peer
->bgp
->stalepath_time
);
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
);
1437 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
1439 FOREACH_AFI_SAFI_NSF (afi
, safi
)
1440 peer
->nsf
[afi
][safi
] = 0;
1443 /* Stop route-refresh stalepath timer */
1444 if (peer
->t_refresh_stalepath
) {
1445 EVENT_OFF(peer
->t_refresh_stalepath
);
1447 if (bgp_debug_neighbor_events(peer
))
1449 "%pBP route-refresh restart stalepath timer stopped",
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
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
))
1464 gr_info
= &bgp
->gr_info
[afi
][safi
];
1468 if (gr_info
->eor_required
)
1469 gr_info
->eor_required
--;
1471 if (BGP_DEBUG(update
, UPDATE_OUT
))
1472 zlog_debug("peer %s, EOR_required %d",
1474 gr_info
->eor_required
);
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
);
1483 EVENT_OFF(gr_info
->t_select_deferral
);
1484 gr_info
->eor_received
= 0;
1489 /* set last reset time */
1490 peer
->resettime
= peer
->uptime
= monotime(NULL
);
1492 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
1493 zlog_debug("%s remove from all update group",
1495 update_group_remove_peer_afs(peer
);
1497 /* Reset peer synctime */
1501 /* stop keepalives */
1502 bgp_keepalives_off(peer
);
1504 /* Stop read and write threads. */
1505 bgp_writes_off(peer
);
1506 bgp_reads_off(peer
);
1508 EVENT_OFF(peer
->t_connect_check_r
);
1509 EVENT_OFF(peer
->t_connect_check_w
);
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
);
1518 /* Clear input and output buffer. */
1519 frr_with_mutex (&peer
->io_mtx
) {
1521 stream_fifo_clean(peer
->ibuf
);
1523 stream_fifo_clean(peer
->obuf
);
1525 if (peer
->ibuf_work
)
1526 ringbuf_wipe(peer
->ibuf_work
);
1527 if (peer
->obuf_work
)
1528 stream_reset(peer
->obuf_work
);
1531 stream_free(peer
->curr
);
1536 /* Close of file descriptor. */
1537 if (peer
->fd
>= 0) {
1542 /* Reset capabilities. */
1545 /* Resetting neighbor role to the default value */
1546 peer
->remote_role
= ROLE_UNDEFINED
;
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;
1554 /* peer address family capability flags*/
1555 peer
->af_cap
[afi
][safi
] = 0;
1557 /* peer address family status flags*/
1558 peer
->af_sflags
[afi
][safi
] = 0;
1560 /* Received ORF prefix-filter */
1561 peer
->orf_plist
[afi
][safi
] = NULL
;
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
);
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
;
1576 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
1577 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
1580 /* Reset DelayOpenTime */
1581 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER_DELAYOPEN
))
1582 peer
->v_delayopen
= peer
->delayopen
;
1584 peer
->v_delayopen
= peer
->bgp
->default_delayopen
;
1586 peer
->update_time
= 0;
1588 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1589 && !(CHECK_FLAG(peer
->flags
, PEER_FLAG_DELETE
))) {
1591 ret
= BGP_FSM_FAILURE_AND_DELETE
;
1593 bgp_peer_conf_if_to_su_update(peer
);
1598 /* BGP peer is stoped by the error. */
1599 static enum bgp_fsm_state_progress
bgp_stop_with_error(struct peer
*peer
)
1601 /* Double start timer. */
1604 /* Overflow check. */
1605 if (peer
->v_start
>= (60 * 2))
1606 peer
->v_start
= (60 * 2);
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__
);
1613 return BGP_FSM_FAILURE
;
1616 return bgp_stop(peer
);
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
)
1624 /* Send notify to remote peer */
1625 bgp_notify_send(peer
, code
, sub_code
);
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__
);
1632 return BGP_FSM_FAILURE
;
1635 /* Clear start timer value to default. */
1636 peer
->v_start
= BGP_INIT_START_TIMER
;
1638 return bgp_stop(peer
);
1642 * Determines whether a TCP session has successfully established for a peer and
1643 * events as appropriate.
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.
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.
1656 static void bgp_connect_check(struct event
*thread
)
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
);
1669 EVENT_OFF(peer
->t_connect_check_r
);
1670 EVENT_OFF(peer
->t_connect_check_w
);
1672 /* Check file descriptor. */
1673 slen
= sizeof(status
);
1674 ret
= getsockopt(peer
->fd
, SOL_SOCKET
, SO_ERROR
, (void *)&status
,
1677 /* If getsockopt is fail, this is fatal error. */
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
);
1685 /* When status is 0 then TCP connection is established. */
1687 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER_DELAYOPEN
))
1688 BGP_EVENT_ADD(peer
, TCP_connection_open_w_delay
);
1690 BGP_EVENT_ADD(peer
, TCP_connection_open
);
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
);
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
)
1706 flog_err(EC_BGP_CONNECT
, "%s peer's fd is negative value %d",
1707 __func__
, peer
->fd
);
1708 return bgp_stop(peer
);
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
;
1722 * If we are doing nht for a peer that ls v6 LL based
1723 * massage the event system to make things happy
1725 bgp_nht_interface_events(peer
);
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
);
1734 zlog_debug("%s passive open", peer
->host
);
1737 /* Send an open message */
1738 bgp_open_send(peer
);
1740 return BGP_FSM_SUCCESS
;
1743 /* TCP connection open with RFC 4271 optional session attribute DelayOpen flag
1746 static enum bgp_fsm_state_progress
1747 bgp_connect_success_w_delayopen(struct peer
*peer
)
1750 flog_err(EC_BGP_CONNECT
, "%s: peer's fd is negative value %d",
1751 __func__
, peer
->fd
);
1752 return bgp_stop(peer
);
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
;
1766 * If we are doing nht for a peer that ls v6 LL based
1767 * massage the event system to make things happy
1769 bgp_nht_interface_events(peer
);
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
);
1778 zlog_debug("%s passive open", peer
->host
);
1781 /* set the DelayOpenTime to the inital value */
1782 peer
->v_delayopen
= peer
->delayopen
;
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
,
1789 if (bgp_debug_neighbor_events(peer
))
1790 zlog_debug("%s [FSM] BGP OPEN message delayed for %d seconds",
1791 peer
->host
, peer
->delayopen
);
1793 return BGP_FSM_SUCCESS
;
1796 /* TCP connect fail */
1797 static enum bgp_fsm_state_progress
bgp_connect_fail(struct peer
*peer
)
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__
);
1804 return BGP_FSM_FAILURE_AND_DELETE
;
1808 * If we are doing nht for a peer that ls v6 LL based
1809 * massage the event system to make things happy
1811 bgp_nht_interface_events(peer
);
1813 return bgp_stop(peer
);
1816 /* This function is the first starting point of all BGP connection. It
1817 * try to connect to remote peer with non-blocking IO.
1819 enum bgp_fsm_state_progress
bgp_start(struct peer
*peer
)
1823 bgp_peer_conf_if_to_su_update(peer
);
1825 if (peer
->su
.sa
.sa_family
== AF_UNSPEC
) {
1826 if (bgp_debug_neighbor_events(peer
))
1828 "%s [FSM] Unable to get neighbor's IP address, waiting...",
1830 peer
->last_reset
= PEER_DOWN_NBR_ADDR
;
1831 return BGP_FSM_FAILURE
;
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!",
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
;
1850 /* Scrub some information that might be left over from a previous,
1853 /* Connection information. */
1854 if (peer
->su_local
) {
1855 sockunion_free(peer
->su_local
);
1856 peer
->su_local
= NULL
;
1859 if (peer
->su_remote
) {
1860 sockunion_free(peer
->su_remote
);
1861 peer
->su_remote
= NULL
;
1864 /* Clear remote router-id. */
1865 peer
->remote_id
.s_addr
= INADDR_ANY
;
1867 /* Clear peer capability flag. */
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
;
1876 if (peer
->bgp
->vrf_id
== VRF_UNKNOWN
) {
1877 if (bgp_debug_neighbor_events(peer
))
1880 "%s [FSM] In a VRF that is not initialised yet",
1882 peer
->last_reset
= PEER_DOWN_VRF_UNINIT
;
1883 return BGP_FSM_FAILURE
;
1886 /* Register peer for NHT. If next hop is already resolved, proceed
1887 * with connection setup, else wait.
1889 if (!bgp_peer_reg_with_nht(peer
)) {
1890 if (bgp_zebra_num_connects()) {
1891 if (bgp_debug_neighbor_events(peer
))
1893 "%s [FSM] Waiting for NHT, no path to neighbor present",
1895 peer
->last_reset
= PEER_DOWN_WAITING_NHT
;
1896 BGP_EVENT_ADD(peer
, TCP_connection_open_failed
);
1897 return BGP_FSM_SUCCESS
;
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
);
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
);
1913 case connect_success
:
1914 if (bgp_debug_neighbor_events(peer
))
1916 "%s [FSM] Connect immediately success, fd %d",
1917 peer
->host
, peer
->fd
);
1919 BGP_EVENT_ADD(peer
, TCP_connection_open
);
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
))
1926 "%s [FSM] Non blocking connect waiting result, fd %d",
1927 peer
->host
, peer
->fd
);
1929 flog_err(EC_BGP_FSM
,
1930 "%s peer's fd is negative value %d", __func__
,
1932 return BGP_FSM_FAILURE
;
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
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.
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
);
1949 return BGP_FSM_SUCCESS
;
1952 /* Connect retry timer is expired when the peer status is Connect. */
1953 static enum bgp_fsm_state_progress
bgp_reconnect(struct peer
*peer
)
1955 enum bgp_fsm_state_progress ret
;
1957 ret
= bgp_stop(peer
);
1958 if (ret
< BGP_FSM_SUCCESS
)
1961 /* Send graceful restart capabilty */
1962 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer
->bgp
,
1965 return bgp_start(peer
);
1968 static enum bgp_fsm_state_progress
bgp_fsm_open(struct peer
*peer
)
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
);
1974 /* Send keepalive and make keepalive timer */
1975 bgp_keepalive_send(peer
);
1977 return BGP_FSM_SUCCESS
;
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
)
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
));
1987 return bgp_stop_with_notify(peer
, BGP_NOTIFY_FSM_ERR
,
1988 bgp_fsm_error_subcode(peer
->status
));
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
)
1995 if (bgp_debug_neighbor_events(peer
))
1996 zlog_debug("%s [FSM] Hold timer expire", peer
->host
);
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.
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
);
2007 return bgp_stop_with_notify(peer
, BGP_NOTIFY_HOLD_ERR
, 0);
2010 /* RFC 4271 DelayOpenTimer_Expires event */
2011 static enum bgp_fsm_state_progress
2012 bgp_fsm_delayopen_timer_expire(struct peer
*peer
)
2014 /* Stop the DelayOpenTimer */
2015 EVENT_OFF(peer
->t_delayopen
);
2017 /* Send open message to peer */
2018 bgp_open_send(peer
);
2020 /* Set the HoldTimer to a large value (4 minutes) */
2021 peer
->v_holdtime
= 245;
2023 return BGP_FSM_SUCCESS
;
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
)
2030 struct afi_safi_info
*thread_info
;
2032 /* If the deferral timer is active, then increment eor count */
2033 if (gr_info
->t_select_deferral
) {
2034 gr_info
->eor_required
++;
2038 /* Start the deferral timer when the first peer enabled for the graceful
2039 * restart is established
2041 if (gr_info
->eor_required
== 0) {
2042 thread_info
= XMALLOC(MTYPE_TMP
, sizeof(struct afi_safi_info
));
2044 thread_info
->afi
= afi
;
2045 thread_info
->safi
= safi
;
2046 thread_info
->bgp
= bgp
;
2048 event_add_timer(bm
->master
, bgp_graceful_deferral_timer_expire
,
2049 thread_info
, bgp
->select_defer_time
,
2050 &gr_info
->t_select_deferral
);
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
);
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
);
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
)
2070 struct graceful_restart_info
*gr_info
;
2071 struct bgp
*bgp
= peer
->bgp
;
2074 if ((afi
< AFI_IP
) || (afi
>= AFI_MAX
)) {
2075 if (BGP_DEBUG(update
, UPDATE_OUT
))
2076 zlog_debug("%s : invalid afi %d", __func__
, afi
);
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
);
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
);
2099 * Transition to Established state.
2101 * Convert peer from stub to full fledged peer, set some timers, and generate
2104 static enum bgp_fsm_state_progress
bgp_establish(struct peer
*peer
)
2108 int nsf_af_count
= 0;
2109 enum bgp_fsm_state_progress ret
= BGP_FSM_SUCCESS
;
2113 other
= peer
->doppelganger
;
2114 hash_release(peer
->bgp
->peerhash
, peer
);
2116 hash_release(peer
->bgp
->peerhash
, other
);
2118 peer
= peer_xfer_conn(peer
);
2120 flog_err(EC_BGP_CONNECT
, "%%Neighbor failed in xfer_conn");
2121 return BGP_FSM_FAILURE
;
2125 ret
= BGP_FSM_SUCCESS_STATE_TRANSFER
;
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
);
2131 /* Clear start timer value to default. */
2132 peer
->v_start
= BGP_INIT_START_TIMER
;
2134 /* Increment established count. */
2135 peer
->established
++;
2136 bgp_fsm_change_status(peer
, Established
);
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
)
2147 /* assign update-group/subgroup */
2148 update_group_adjust_peer_afs(peer
);
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
);
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
);
2169 peer
->nsf
[afi
][safi
] = 1;
2172 if (peer
->nsf
[afi
][safi
])
2173 bgp_clear_stale_route(peer
, afi
, safi
);
2174 peer
->nsf
[afi
][safi
] = 0;
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
);
2182 "Error in updating graceful restart for %s",
2183 get_afi_safi_str(afi
, safi
,
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
]
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
2204 peer
->bgp
, afi
, safi
,
2205 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE
);
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
2216 peer
->bgp
, afi
, safi
,
2217 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE
);
2221 peer
->nsf_af_count
= nsf_af_count
;
2224 SET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
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
))
2231 "%pBP graceful restart stalepath timer stopped",
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
);
2242 /* Reset uptime, turn on keepalives, send current table. */
2243 if (!peer
->v_holdtime
)
2244 bgp_keepalives_on(peer
);
2246 peer
->uptime
= monotime(NULL
);
2248 /* Send route-refresh when ORF is enabled.
2249 * Stop Long-lived Graceful Restart timers.
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
))
2256 "%pBP Long-lived stale timer stopped for afi/safi: %d/%d",
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
);
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
);
2289 bgp_announce_peer(peer
);
2291 /* Start the route advertisement timer to send updates to the peer - if
2293 * is not in read-only mode. If it is, the timer will be started at the
2295 * of read-only mode.
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);
2302 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)) {
2303 if (bgp_debug_neighbor_events(peer
))
2305 "[Event] Deleting stub connection for peer %s",
2308 if (peer
->doppelganger
->status
> Active
)
2309 bgp_notify_send(peer
->doppelganger
, BGP_NOTIFY_CEASE
,
2310 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION
);
2312 peer_delete(peer
->doppelganger
);
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.
2321 (void)hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
2323 /* Start BFD peer if not already running. */
2324 if (peer
->bfd_config
)
2325 bgp_peer_bfd_update_source(peer
);
2330 /* Keepalive packet is received. */
2331 static enum bgp_fsm_state_progress
bgp_fsm_keepalive(struct peer
*peer
)
2333 EVENT_OFF(peer
->t_holdtime
);
2334 return BGP_FSM_SUCCESS
;
2337 /* Update packet is received. */
2338 static enum bgp_fsm_state_progress
bgp_fsm_update(struct peer
*peer
)
2340 EVENT_OFF(peer
->t_holdtime
);
2341 return BGP_FSM_SUCCESS
;
2344 /* This is empty event. */
2345 static enum bgp_fsm_state_progress
bgp_ignore(struct peer
*peer
)
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
;
2357 /* This is to handle unexpected events.. */
2358 static enum bgp_fsm_state_progress
bgp_fsm_exception(struct peer
*peer
)
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
);
2370 void bgp_fsm_nht_update(struct peer
*peer
, bool has_valid_nexthops
)
2375 switch (peer
->status
) {
2377 if (has_valid_nexthops
)
2378 BGP_EVENT_ADD(peer
, BGP_Start
);
2381 if (!has_valid_nexthops
) {
2382 EVENT_OFF(peer
->t_connect
);
2383 BGP_EVENT_ADD(peer
, TCP_fatal_error
);
2387 if (has_valid_nexthops
) {
2388 EVENT_OFF(peer
->t_connect
);
2389 BGP_EVENT_ADD(peer
, ConnectRetry_timer_expired
);
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
);
2401 case BGP_STATUS_MAX
:
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] = {
2412 /* Idle state: In Idle state, all events other than BGP_Start is
2413 ignored. With BGP_Start event, finite state machine calls
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
2573 /* Execute event process. */
2574 void bgp_event(struct event
*thread
)
2576 enum bgp_fsm_events event
;
2579 peer
= EVENT_ARG(thread
);
2580 event
= EVENT_VAL(thread
);
2583 bgp_event_update(peer
, event
);
2587 int bgp_event_update(struct peer
*peer
, enum bgp_fsm_events event
)
2589 enum bgp_fsm_status next
;
2590 enum bgp_fsm_state_progress ret
= 0;
2592 int passive_conn
= 0;
2595 /* default return code */
2596 ret
= FSM_PEER_NOOP
;
2598 other
= peer
->doppelganger
;
2600 (CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
)) ? 1 : 0;
2601 dyn_nbr
= peer_dynamic_neighbor(peer
);
2603 /* Logging this event. */
2604 next
= FSM
[peer
->status
- 1][event
- 1].next_state
;
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
);
2612 peer
->last_event
= peer
->cur_event
;
2613 peer
->cur_event
= event
;
2615 /* Call function. */
2616 if (FSM
[peer
->status
- 1][event
- 1].func
)
2617 ret
= (*(FSM
[peer
->status
- 1][event
- 1].func
))(peer
);
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
2624 Update the peer pointer accordingly */
2625 ret
= FSM_PEER_TRANSFERRED
;
2629 /* If status is changed. */
2630 if (next
!= peer
->status
) {
2631 bgp_fsm_change_status(peer
, next
);
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.
2640 if (ret
!= FSM_PEER_TRANSFERRED
)
2641 ret
= FSM_PEER_TRANSITIONED
;
2644 /* Make sure timer is set. */
2645 bgp_timer_set(peer
);
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
2655 if (!dyn_nbr
&& !passive_conn
&& peer
->bgp
&&
2656 ret
!= BGP_FSM_FAILURE_AND_DELETE
) {
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
],
2666 bgp_fsm_change_status(peer
, Idle
);
2667 bgp_timer_set(peer
);
2669 ret
= FSM_PEER_STOPPED
;
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
)
2680 struct peer
*peer
= {0};
2681 struct listnode
*node
= {0};
2682 struct listnode
*nnode
= {0};
2683 enum peer_mode peer_old_state
= PEER_INVALID
;
2685 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
2687 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2688 zlog_debug("%s [BGP_GR] Peer: (%s) :", __func__
,
2691 peer_old_state
= bgp_peer_gr_mode_get(peer
);
2693 if (peer_old_state
== PEER_GLOBAL_INHERIT
) {
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
2702 switch (global_new_state
) {
2704 BGP_PEER_GR_HELPER_ENABLE(peer
);
2707 BGP_PEER_GR_ENABLE(peer
);
2709 case GLOBAL_DISABLE
:
2710 BGP_PEER_GR_DISABLE(peer
);
2712 case GLOBAL_INVALID
:
2713 zlog_debug("%s [BGP_GR] GLOBAL_INVALID",
2715 return BGP_ERR_GR_OPERATION_FAILED
;
2720 bgp
->global_gr_present_state
= global_new_state
;
2722 return BGP_GR_SUCCESS
;
2725 int bgp_gr_update_all(struct bgp
*bgp
, int global_gr_cmd
)
2727 enum global_mode global_new_state
= GLOBAL_INVALID
;
2728 enum global_mode global_old_state
= GLOBAL_INVALID
;
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
));
2734 global_old_state
= bgp_global_gr_mode_get(bgp
);
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
));
2740 if (global_old_state
!= GLOBAL_INVALID
) {
2742 bgp
->GLOBAL_GR_FSM
[global_old_state
][global_gr_cmd
];
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
));
2748 zlog_err("%s [BGP_GR] global_old_state == GLOBAL_INVALID",
2750 return BGP_ERR_GR_OPERATION_FAILED
;
2753 if (global_new_state
== GLOBAL_INVALID
) {
2754 zlog_err("%s [BGP_GR] global_new_state == GLOBAL_INVALID",
2756 return BGP_ERR_GR_INVALID_CMD
;
2758 if (global_new_state
== global_old_state
) {
2760 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2762 "%s [BGP_GR] global_new_state == global_old_state :%s",
2764 print_global_gr_mode(global_new_state
));
2765 return BGP_GR_NO_OPERATION
;
2768 return bgp_gr_lookup_n_update_all_peer(bgp
, global_new_state
,
2772 const char *print_peer_gr_mode(enum peer_mode pr_mode
)
2774 const char *peer_gr_mode
= NULL
;
2778 peer_gr_mode
= "PEER_HELPER";
2781 peer_gr_mode
= "PEER_GR";
2784 peer_gr_mode
= "PEER_DISABLE";
2787 peer_gr_mode
= "PEER_INVALID";
2789 case PEER_GLOBAL_INHERIT
:
2790 peer_gr_mode
= "PEER_GLOBAL_INHERIT";
2794 return peer_gr_mode
;
2797 const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd
)
2799 const char *peer_gr_cmd
= NULL
;
2801 switch (pr_gr_cmd
) {
2803 peer_gr_cmd
= "PEER_GR_CMD";
2805 case NO_PEER_GR_CMD
:
2806 peer_gr_cmd
= "NO_PEER_GR_CMD";
2808 case PEER_DISABLE_CMD
:
2809 peer_gr_cmd
= "PEER_DISABLE_GR_CMD";
2811 case NO_PEER_DISABLE_CMD
:
2812 peer_gr_cmd
= "NO_PEER_DISABLE_GR_CMD";
2814 case PEER_HELPER_CMD
:
2815 peer_gr_cmd
= "PEER_HELPER_CMD";
2817 case NO_PEER_HELPER_CMD
:
2818 peer_gr_cmd
= "NO_PEER_HELPER_CMD";
2825 const char *print_global_gr_mode(enum global_mode gl_mode
)
2827 const char *global_gr_mode
= "???";
2831 global_gr_mode
= "GLOBAL_HELPER";
2834 global_gr_mode
= "GLOBAL_GR";
2836 case GLOBAL_DISABLE
:
2837 global_gr_mode
= "GLOBAL_DISABLE";
2839 case GLOBAL_INVALID
:
2840 global_gr_mode
= "GLOBAL_INVALID";
2844 return global_gr_mode
;
2847 const char *print_global_gr_cmd(enum global_gr_command gl_gr_cmd
)
2849 const char *global_gr_cmd
= NULL
;
2851 switch (gl_gr_cmd
) {
2853 global_gr_cmd
= "GLOBAL_GR_CMD";
2855 case NO_GLOBAL_GR_CMD
:
2856 global_gr_cmd
= "NO_GLOBAL_GR_CMD";
2858 case GLOBAL_DISABLE_CMD
:
2859 global_gr_cmd
= "GLOBAL_DISABLE_CMD";
2861 case NO_GLOBAL_DISABLE_CMD
:
2862 global_gr_cmd
= "NO_GLOBAL_DISABLE_CMD";
2866 return global_gr_cmd
;
2869 enum global_mode
bgp_global_gr_mode_get(struct bgp
*bgp
)
2871 return bgp
->global_gr_present_state
;
2874 enum peer_mode
bgp_peer_gr_mode_get(struct peer
*peer
)
2876 return peer
->peer_gr_present_state
;
2879 int bgp_neighbor_graceful_restart(struct peer
*peer
, int peer_gr_cmd
)
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
;
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 ;
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
));
2897 peer_old_state
= bgp_peer_gr_mode_get(peer
);
2899 if (peer_old_state
== PEER_INVALID
) {
2900 zlog_debug("[BGP_GR] peer_old_state == Invalid state !");
2901 return BGP_ERR_GR_OPERATION_FAILED
;
2904 peer_state
= peer
->PEER_GR_FSM
[peer_old_state
][peer_gr_cmd
];
2905 peer_new_state
= peer_state
.next_state
;
2907 if (peer_new_state
== PEER_INVALID
) {
2909 "[BGP_GR] Invalid bgp graceful restart command used !");
2910 return BGP_ERR_GR_INVALID_CMD
;
2913 if (peer_new_state
!= peer_old_state
) {
2914 result
= peer_state
.action_fun(peer
, peer_old_state
,
2917 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2919 "[BGP_GR] peer_old_state == peer_new_state !");
2920 return BGP_GR_NO_OPERATION
;
2923 if (result
== BGP_GR_SUCCESS
) {
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
))
2929 "[BGP_GR] Successfully change the state of the peer to : %s : !",
2930 print_peer_gr_mode(peer_new_state
));
2932 return BGP_GR_SUCCESS
;
2938 unsigned int bgp_peer_gr_action(struct peer
*peer
, int old_peer_state
,
2941 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
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
));
2947 int bgp_gr_global_mode
= GLOBAL_INVALID
;
2948 unsigned int ret
= BGP_GR_FAILURE
;
2950 if (old_peer_state
== new_peer_state
) {
2951 /* Nothing to do over here as the present and old state is the
2953 return BGP_GR_NO_OPERATION
;
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
;
2961 bgp_gr_global_mode
= bgp_global_gr_mode_get(peer
->bgp
);
2963 if ((old_peer_state
== PEER_GLOBAL_INHERIT
)
2964 && (new_peer_state
!= PEER_GLOBAL_INHERIT
)) {
2966 /* fetch the Mode running in the Global state machine
2967 *from the bgp structure into a variable called
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
2977 BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer
);
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.
2984 ret
= BGP_GR_SUCCESS
;
2986 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2988 "[BGP_GR] Peer state changed from :%s ",
2989 print_peer_gr_mode(old_peer_state
));
2991 bgp_peer_move_to_gr_mode(peer
, new_peer_state
);
2993 ret
= BGP_GR_SUCCESS
;
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
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
3007 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer
);
3009 if (old_peer_state
== bgp_gr_global_mode
) {
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.
3015 ret
= BGP_GR_SUCCESS
;
3017 /* Destructive always */
3018 /* Tear down the old session
3019 * and send the new capability
3020 * as per the bgp_gr_global_mode
3023 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3025 "[BGP_GR] Peer state changed from :%s",
3026 print_peer_gr_mode(old_peer_state
));
3028 bgp_peer_move_to_gr_mode(peer
, bgp_gr_global_mode
);
3030 ret
= BGP_GR_SUCCESS
;
3034 *This else case, it include all the cases except -->
3035 *(new_peer_state != Peer_Global) &&
3036 *( old_peer_state != Peer_Global )
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
));
3042 bgp_peer_move_to_gr_mode(peer
, new_peer_state
);
3044 ret
= BGP_GR_SUCCESS
;
3050 inline void bgp_peer_move_to_gr_mode(struct peer
*peer
, int new_state
)
3053 int bgp_global_gr_mode
= bgp_global_gr_mode_get(peer
->bgp
);
3055 switch (new_state
) {
3057 BGP_PEER_GR_HELPER_ENABLE(peer
);
3060 BGP_PEER_GR_ENABLE(peer
);
3063 BGP_PEER_GR_DISABLE(peer
);
3065 case PEER_GLOBAL_INHERIT
:
3066 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer
);
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
);
3076 "[BGP_GR] Default switch inherit mode ::: SOMETHING IS WRONG !!!");
3081 "[BGP_GR] Default switch mode ::: SOMETHING IS WRONG !!!");
3084 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3085 zlog_debug("[BGP_GR] Peer state changed --to--> : %d : !",
3089 void bgp_peer_gr_flags_update(struct peer
*peer
)
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
);
3097 UNSET_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART_HELPER
);
3098 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3100 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !",
3102 (CHECK_FLAG(peer
->flags
,
3103 PEER_FLAG_GRACEFUL_RESTART_HELPER
)
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
);
3110 UNSET_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART
);
3111 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3113 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !",
3115 (CHECK_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART
)
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
);
3123 UNSET_FLAG(peer
->flags
,
3124 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
);
3125 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
3127 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !",
3129 (CHECK_FLAG(peer
->flags
,
3130 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
)
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!",
3139 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
3141 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)) {
3143 peer_nsf_stop(peer
);
3145 "[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_WAIT!",