1 /* BGP-4 Finite State Machine
2 * From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
3 * Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "sockunion.h"
33 #include "workqueue.h"
37 #include "lib_errors.h"
40 #include "bgpd/bgpd.h"
41 #include "bgpd/bgp_attr.h"
42 #include "bgpd/bgp_debug.h"
43 #include "bgpd/bgp_errors.h"
44 #include "bgpd/bgp_fsm.h"
45 #include "bgpd/bgp_packet.h"
46 #include "bgpd/bgp_network.h"
47 #include "bgpd/bgp_route.h"
48 #include "bgpd/bgp_dump.h"
49 #include "bgpd/bgp_open.h"
50 #include "bgpd/bgp_advertise.h"
51 #include "bgpd/bgp_updgrp.h"
52 #include "bgpd/bgp_nht.h"
53 #include "bgpd/bgp_bfd.h"
54 #include "bgpd/bgp_memory.h"
55 #include "bgpd/bgp_keepalives.h"
56 #include "bgpd/bgp_io.h"
57 #include "bgpd/bgp_zebra.h"
59 DEFINE_HOOK(peer_backward_transition
, (struct peer
* peer
), (peer
))
60 DEFINE_HOOK(peer_status_changed
, (struct peer
* peer
), (peer
))
61 extern const char *get_afi_safi_str(afi_t afi
,
62 safi_t safi
, bool for_json
);
63 /* Definition of display strings corresponding to FSM events. This should be
64 * kept consistent with the events defined in bgpd.h
66 static const char *const bgp_event_str
[] = {
70 "TCP_connection_open",
71 "TCP_connection_closed",
72 "TCP_connection_open_failed",
74 "ConnectRetry_timer_expired",
76 "KeepAlive_timer_expired",
77 "Receive_OPEN_message",
78 "Receive_KEEPALIVE_message",
79 "Receive_UPDATE_message",
80 "Receive_NOTIFICATION_message",
84 /* BGP FSM (finite state machine) has three types of functions. Type
85 one is thread functions. Type two is event functions. Type three
86 is FSM functions. Timer functions are set by bgp_timer_set
89 /* BGP event function. */
90 int bgp_event(struct thread
*);
92 /* BGP thread functions. */
93 static int bgp_start_timer(struct thread
*);
94 static int bgp_connect_timer(struct thread
*);
95 static int bgp_holdtime_timer(struct thread
*);
97 /* BGP FSM functions. */
98 static int bgp_start(struct peer
*);
100 /* Register peer with NHT */
101 static int bgp_peer_reg_with_nht(struct peer
*peer
)
105 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== BGP_DEFAULT_TTL
106 && !CHECK_FLAG(peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
107 && !bgp_flag_check(peer
->bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
110 return bgp_find_or_add_nexthop(
111 peer
->bgp
, peer
->bgp
, family2afi(peer
->su
.sa
.sa_family
),
112 NULL
, peer
, connected
);
115 static void peer_xfer_stats(struct peer
*peer_dst
, struct peer
*peer_src
)
117 /* Copy stats over. These are only the pre-established state stats */
118 peer_dst
->open_in
+= peer_src
->open_in
;
119 peer_dst
->open_out
+= peer_src
->open_out
;
120 peer_dst
->keepalive_in
+= peer_src
->keepalive_in
;
121 peer_dst
->keepalive_out
+= peer_src
->keepalive_out
;
122 peer_dst
->notify_in
+= peer_src
->notify_in
;
123 peer_dst
->notify_out
+= peer_src
->notify_out
;
124 peer_dst
->dynamic_cap_in
+= peer_src
->dynamic_cap_in
;
125 peer_dst
->dynamic_cap_out
+= peer_src
->dynamic_cap_out
;
128 static struct peer
*peer_xfer_conn(struct peer
*from_peer
)
135 unsigned char last_evt
, last_maj_evt
;
137 assert(from_peer
!= NULL
);
139 peer
= from_peer
->doppelganger
;
141 if (!peer
|| !CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
145 * Let's check that we are not going to loose known configuration
146 * state based upon doppelganger rules.
148 FOREACH_AFI_SAFI (afi
, safi
) {
149 if (from_peer
->afc
[afi
][safi
] != peer
->afc
[afi
][safi
]) {
151 EC_BGP_DOPPELGANGER_CONFIG
,
152 "from_peer->afc[%d][%d] is not the same as what we are overwriting",
158 if (bgp_debug_neighbor_events(peer
))
159 zlog_debug("%s: peer transfer %p fd %d -> %p fd %d)",
160 from_peer
->host
, from_peer
, from_peer
->fd
, peer
,
163 bgp_writes_off(peer
);
165 bgp_writes_off(from_peer
);
166 bgp_reads_off(from_peer
);
169 * Before exchanging FD remove doppelganger from
170 * keepalive peer hash. It could be possible conf peer
171 * fd is set to -1. If blocked on lock then keepalive
172 * thread can access peer pointer with fd -1.
174 bgp_keepalives_off(from_peer
);
176 BGP_TIMER_OFF(peer
->t_routeadv
);
177 BGP_TIMER_OFF(peer
->t_connect
);
178 BGP_TIMER_OFF(peer
->t_connect_check_r
);
179 BGP_TIMER_OFF(peer
->t_connect_check_w
);
180 BGP_TIMER_OFF(from_peer
->t_routeadv
);
181 BGP_TIMER_OFF(from_peer
->t_connect
);
182 BGP_TIMER_OFF(from_peer
->t_connect_check_r
);
183 BGP_TIMER_OFF(from_peer
->t_connect_check_w
);
184 BGP_TIMER_OFF(from_peer
->t_process_packet
);
187 * At this point in time, it is possible that there are packets pending
188 * on various buffers. Those need to be transferred or dropped,
189 * otherwise we'll get spurious failures during session establishment.
191 frr_with_mutex(&peer
->io_mtx
, &from_peer
->io_mtx
) {
193 peer
->fd
= from_peer
->fd
;
196 stream_fifo_clean(peer
->ibuf
);
197 stream_fifo_clean(peer
->obuf
);
200 * this should never happen, since bgp_process_packet() is the
201 * only task that sets and unsets the current packet and it
202 * runs in our pthread.
207 "[%s] Dropping pending packet on connection transfer:",
209 /* there used to be a bgp_packet_dump call here, but
210 * that's extremely confusing since there's no way to
211 * identify the packet in MRT dumps or BMP as dropped
212 * due to connection transfer.
214 stream_free(peer
->curr
);
218 // copy each packet from old peer's output queue to new peer
219 while (from_peer
->obuf
->head
)
220 stream_fifo_push(peer
->obuf
,
221 stream_fifo_pop(from_peer
->obuf
));
223 // copy each packet from old peer's input queue to new peer
224 while (from_peer
->ibuf
->head
)
225 stream_fifo_push(peer
->ibuf
,
226 stream_fifo_pop(from_peer
->ibuf
));
228 ringbuf_wipe(peer
->ibuf_work
);
229 ringbuf_copy(peer
->ibuf_work
, from_peer
->ibuf_work
,
230 ringbuf_remain(from_peer
->ibuf_work
));
233 peer
->as
= from_peer
->as
;
234 peer
->v_holdtime
= from_peer
->v_holdtime
;
235 peer
->v_keepalive
= from_peer
->v_keepalive
;
236 peer
->v_routeadv
= from_peer
->v_routeadv
;
237 peer
->v_gr_restart
= from_peer
->v_gr_restart
;
238 peer
->cap
= from_peer
->cap
;
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
;
254 peer
->peer_gr_present_state
= from_peer
->peer_gr_present_state
;
255 peer
->peer_gr_new_status_flag
= from_peer
->peer_gr_new_status_flag
;
256 bgp_peer_gr_flags_update(peer
);
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
,
263 PEER_STATUS_NSF_WAIT
)) {
268 if (from_peer
->hostname
!= NULL
) {
269 if (peer
->hostname
) {
270 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
271 peer
->hostname
= NULL
;
274 peer
->hostname
= from_peer
->hostname
;
275 from_peer
->hostname
= NULL
;
278 if (from_peer
->domainname
!= NULL
) {
279 if (peer
->domainname
) {
280 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
281 peer
->domainname
= NULL
;
284 peer
->domainname
= from_peer
->domainname
;
285 from_peer
->domainname
= NULL
;
288 FOREACH_AFI_SAFI (afi
, safi
) {
289 peer
->af_flags
[afi
][safi
] = from_peer
->af_flags
[afi
][safi
];
290 peer
->af_sflags
[afi
][safi
] = from_peer
->af_sflags
[afi
][safi
];
291 peer
->af_cap
[afi
][safi
] = from_peer
->af_cap
[afi
][safi
];
292 peer
->afc_nego
[afi
][safi
] = from_peer
->afc_nego
[afi
][safi
];
293 peer
->afc_adv
[afi
][safi
] = from_peer
->afc_adv
[afi
][safi
];
294 peer
->afc_recv
[afi
][safi
] = from_peer
->afc_recv
[afi
][safi
];
295 peer
->orf_plist
[afi
][safi
] = from_peer
->orf_plist
[afi
][safi
];
298 if (bgp_getsockname(peer
) < 0) {
301 "%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
302 (CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
)
305 peer
->host
, peer
->fd
, from_peer
->fd
);
310 if (from_peer
->status
> Active
) {
311 if (bgp_getsockname(from_peer
) < 0) {
314 "%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
316 (CHECK_FLAG(from_peer
->sflags
,
317 PEER_STATUS_ACCEPT_PEER
)
320 from_peer
->host
, from_peer
->fd
, peer
->fd
);
327 // Note: peer_xfer_stats() must be called with I/O turned OFF
329 peer_xfer_stats(peer
, from_peer
);
331 /* Register peer for NHT. This is to allow RAs to be enabled when
332 * needed, even on a passive connection.
334 bgp_peer_reg_with_nht(peer
);
338 thread_add_timer_msec(bm
->master
, bgp_process_packet
, peer
, 0,
339 &peer
->t_process_packet
);
344 /* Hook function called after bgp event is occered. And vty's
345 neighbor command invoke this function after making neighbor
347 void bgp_timer_set(struct peer
*peer
)
349 switch (peer
->status
) {
351 /* First entry point of peer's finite state machine. In Idle
352 status start timer is on unless peer is shutdown or peer is
353 inactive. All other timer must be turned off */
354 if (BGP_PEER_START_SUPPRESSED(peer
) || !peer_active(peer
)
355 || (peer
->bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
&&
356 peer
->bgp
->vrf_id
== VRF_UNKNOWN
)) {
357 BGP_TIMER_OFF(peer
->t_start
);
359 BGP_TIMER_ON(peer
->t_start
, bgp_start_timer
,
362 BGP_TIMER_OFF(peer
->t_connect
);
363 BGP_TIMER_OFF(peer
->t_holdtime
);
364 bgp_keepalives_off(peer
);
365 BGP_TIMER_OFF(peer
->t_routeadv
);
369 /* After start timer is expired, the peer moves to Connect
370 status. Make sure start timer is off and connect timer is
372 BGP_TIMER_OFF(peer
->t_start
);
373 BGP_TIMER_ON(peer
->t_connect
, bgp_connect_timer
,
375 BGP_TIMER_OFF(peer
->t_holdtime
);
376 bgp_keepalives_off(peer
);
377 BGP_TIMER_OFF(peer
->t_routeadv
);
381 /* Active is waiting connection from remote peer. And if
382 connect timer is expired, change status to Connect. */
383 BGP_TIMER_OFF(peer
->t_start
);
384 /* If peer is passive mode, do not set connect timer. */
385 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)
386 || CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)) {
387 BGP_TIMER_OFF(peer
->t_connect
);
389 BGP_TIMER_ON(peer
->t_connect
, bgp_connect_timer
,
392 BGP_TIMER_OFF(peer
->t_holdtime
);
393 bgp_keepalives_off(peer
);
394 BGP_TIMER_OFF(peer
->t_routeadv
);
398 /* OpenSent status. */
399 BGP_TIMER_OFF(peer
->t_start
);
400 BGP_TIMER_OFF(peer
->t_connect
);
401 if (peer
->v_holdtime
!= 0) {
402 BGP_TIMER_ON(peer
->t_holdtime
, bgp_holdtime_timer
,
405 BGP_TIMER_OFF(peer
->t_holdtime
);
407 bgp_keepalives_off(peer
);
408 BGP_TIMER_OFF(peer
->t_routeadv
);
412 /* OpenConfirm status. */
413 BGP_TIMER_OFF(peer
->t_start
);
414 BGP_TIMER_OFF(peer
->t_connect
);
416 /* If the negotiated Hold Time value is zero, then the Hold Time
417 timer and KeepAlive timers are not started. */
418 if (peer
->v_holdtime
== 0) {
419 BGP_TIMER_OFF(peer
->t_holdtime
);
420 bgp_keepalives_off(peer
);
422 BGP_TIMER_ON(peer
->t_holdtime
, bgp_holdtime_timer
,
424 bgp_keepalives_on(peer
);
426 BGP_TIMER_OFF(peer
->t_routeadv
);
430 /* In Established status start and connect timer is turned
432 BGP_TIMER_OFF(peer
->t_start
);
433 BGP_TIMER_OFF(peer
->t_connect
);
435 /* Same as OpenConfirm, if holdtime is zero then both holdtime
436 and keepalive must be turned off. */
437 if (peer
->v_holdtime
== 0) {
438 BGP_TIMER_OFF(peer
->t_holdtime
);
439 bgp_keepalives_off(peer
);
441 BGP_TIMER_ON(peer
->t_holdtime
, bgp_holdtime_timer
,
443 bgp_keepalives_on(peer
);
447 BGP_TIMER_OFF(peer
->t_gr_restart
);
448 BGP_TIMER_OFF(peer
->t_gr_stale
);
449 BGP_TIMER_OFF(peer
->t_pmax_restart
);
452 BGP_TIMER_OFF(peer
->t_start
);
453 BGP_TIMER_OFF(peer
->t_connect
);
454 BGP_TIMER_OFF(peer
->t_holdtime
);
455 bgp_keepalives_off(peer
);
456 BGP_TIMER_OFF(peer
->t_routeadv
);
461 /* BGP start timer. This function set BGP_Start event to thread value
462 and process event. */
463 static int bgp_start_timer(struct thread
*thread
)
467 peer
= THREAD_ARG(thread
);
468 peer
->t_start
= NULL
;
470 if (bgp_debug_neighbor_events(peer
))
471 zlog_debug("%s [FSM] Timer (start timer expire).", peer
->host
);
473 THREAD_VAL(thread
) = BGP_Start
;
474 bgp_event(thread
); /* bgp_event unlocks peer */
479 /* BGP connect retry timer. */
480 static int bgp_connect_timer(struct thread
*thread
)
485 peer
= THREAD_ARG(thread
);
487 assert(!peer
->t_write
);
488 assert(!peer
->t_read
);
490 peer
->t_connect
= NULL
;
492 if (bgp_debug_neighbor_events(peer
))
493 zlog_debug("%s [FSM] Timer (connect timer expire)", peer
->host
);
495 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
)) {
499 THREAD_VAL(thread
) = ConnectRetry_timer_expired
;
500 bgp_event(thread
); /* bgp_event unlocks peer */
507 /* BGP holdtime timer. */
508 static int bgp_holdtime_timer(struct thread
*thread
)
512 peer
= THREAD_ARG(thread
);
513 peer
->t_holdtime
= NULL
;
515 if (bgp_debug_neighbor_events(peer
))
516 zlog_debug("%s [FSM] Timer (holdtime timer expire)",
519 THREAD_VAL(thread
) = Hold_Timer_expired
;
520 bgp_event(thread
); /* bgp_event unlocks peer */
525 int bgp_routeadv_timer(struct thread
*thread
)
529 peer
= THREAD_ARG(thread
);
530 peer
->t_routeadv
= NULL
;
532 if (bgp_debug_neighbor_events(peer
))
533 zlog_debug("%s [FSM] Timer (routeadv timer expire)",
536 peer
->synctime
= bgp_clock();
538 thread_add_timer_msec(bm
->master
, bgp_generate_updgrp_packets
, peer
, 0,
539 &peer
->t_generate_updgrp_packets
);
541 /* MRAI timer will be started again when FIFO is built, no need to
547 /* BGP Peer Down Cause */
548 const char *const peer_down_str
[] = {"",
552 "Cluster ID changed",
553 "Confederation identifier changed",
554 "Confederation peer changed",
555 "RR client config change",
556 "RS client config change",
557 "Update source change",
558 "Address family activated",
561 "BGP Notification received",
562 "BGP Notification send",
563 "Peer closed the session",
565 "Peer-group add member",
566 "Peer-group delete member",
567 "Capability changed",
568 "Passive config change",
569 "Multihop config change",
570 "NSF peer closed the session",
571 "Intf peering v6only config change",
574 "Neighbor address lost",
576 "Waiting for Peer IPv6 LLA",
577 "Waiting for VRF to be initialized",
578 "No AFI/SAFI activated for peer"};
580 static int bgp_graceful_restart_timer_expire(struct thread
*thread
)
586 peer
= THREAD_ARG(thread
);
587 peer
->t_gr_restart
= NULL
;
589 /* NSF delete stale route */
590 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
591 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
592 if (peer
->nsf
[afi
][safi
])
593 bgp_clear_stale_route(peer
, afi
, safi
);
595 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
596 BGP_TIMER_OFF(peer
->t_gr_stale
);
598 if (bgp_debug_neighbor_events(peer
)) {
599 zlog_debug("%s graceful restart timer expired", peer
->host
);
600 zlog_debug("%s graceful restart stalepath timer stopped",
609 static int bgp_graceful_stale_timer_expire(struct thread
*thread
)
615 peer
= THREAD_ARG(thread
);
616 peer
->t_gr_stale
= NULL
;
618 if (bgp_debug_neighbor_events(peer
))
619 zlog_debug("%s graceful restart stalepath timer expired",
622 /* NSF delete stale route */
623 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
624 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
625 if (peer
->nsf
[afi
][safi
])
626 bgp_clear_stale_route(peer
, afi
, safi
);
631 /* Selection deferral timer processing function */
632 static int bgp_graceful_deferral_timer_expire(struct thread
*thread
)
634 struct afi_safi_info
*info
;
639 info
= THREAD_ARG(thread
);
644 if (BGP_DEBUG(update
, UPDATE_OUT
))
645 zlog_debug("afi %d, safi %d : graceful restart deferral timer expired",
648 bgp
->gr_info
[afi
][safi
].t_select_deferral
= NULL
;
650 bgp
->gr_info
[afi
][safi
].eor_required
= 0;
651 bgp
->gr_info
[afi
][safi
].eor_received
= 0;
652 XFREE(MTYPE_TMP
, info
);
654 /* Best path selection */
655 return bgp_best_path_select_defer(bgp
, afi
, safi
);
658 static int bgp_update_delay_applicable(struct bgp
*bgp
)
660 /* update_delay_over flag should be reset (set to 0) for any new
661 applicability of the update-delay during BGP process lifetime.
662 And it should be set after an occurence of the update-delay is
664 if (!bgp
->update_delay_over
)
670 int bgp_update_delay_active(struct bgp
*bgp
)
672 if (bgp
->t_update_delay
)
678 int bgp_update_delay_configured(struct bgp
*bgp
)
680 if (bgp
->v_update_delay
)
686 /* Do the post-processing needed when bgp comes out of the read-only mode
687 on ending the update delay. */
688 void bgp_update_delay_end(struct bgp
*bgp
)
690 THREAD_TIMER_OFF(bgp
->t_update_delay
);
691 THREAD_TIMER_OFF(bgp
->t_establish_wait
);
693 /* Reset update-delay related state */
694 bgp
->update_delay_over
= 1;
695 bgp
->established
= 0;
696 bgp
->restarted_peers
= 0;
697 bgp
->implicit_eors
= 0;
698 bgp
->explicit_eors
= 0;
700 quagga_timestamp(3, bgp
->update_delay_end_time
,
701 sizeof(bgp
->update_delay_end_time
));
704 * Add an end-of-initial-update marker to the main process queues so
706 * the route advertisement timer for the peers can be started. Also set
707 * the zebra and peer update hold flags. These flags are used to achieve
708 * three stages in the update-delay post processing:
709 * 1. Finish best-path selection for all the prefixes held on the
711 * (routes in BGP are updated, and peers sync queues are populated
713 * 2. As the eoiu mark is reached in the bgp process routine, ship all
715 * routes to zebra. With that zebra should see updates from BGP
718 * 3. Unblock the peer update writes. With that peer update packing
720 * the prefixes should be at its maximum.
722 bgp_add_eoiu_mark(bgp
);
723 bgp
->main_zebra_update_hold
= 1;
724 bgp
->main_peers_update_hold
= 1;
726 /* Resume the queue processing. This should trigger the event that would
728 care of processing any work that was queued during the read-only
730 work_queue_unplug(bm
->process_main_queue
);
736 void bgp_start_routeadv(struct bgp
*bgp
)
738 struct listnode
*node
, *nnode
;
741 zlog_info("bgp_start_routeadv(), update hold status %d",
742 bgp
->main_peers_update_hold
);
744 if (bgp
->main_peers_update_hold
)
747 quagga_timestamp(3, bgp
->update_delay_peers_resume_time
,
748 sizeof(bgp
->update_delay_peers_resume_time
));
750 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
751 if (peer
->status
!= Established
)
753 BGP_TIMER_OFF(peer
->t_routeadv
);
754 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, 0);
761 void bgp_adjust_routeadv(struct peer
*peer
)
763 time_t nowtime
= bgp_clock();
765 unsigned long remain
;
767 /* Bypass checks for special case of MRAI being 0 */
768 if (peer
->v_routeadv
== 0) {
769 /* Stop existing timer, just in case it is running for a
771 * duration and schedule write thread immediately.
773 if (peer
->t_routeadv
)
774 BGP_TIMER_OFF(peer
->t_routeadv
);
776 peer
->synctime
= bgp_clock();
777 thread_add_timer_msec(bm
->master
, bgp_generate_updgrp_packets
,
779 &peer
->t_generate_updgrp_packets
);
786 * If the last update was written more than MRAI back, expire the timer
787 * instantly so that we can send the update out sooner.
789 * <------- MRAI --------->
790 * |-----------------|-----------------------|
791 * <------------- m ------------>
800 diff
= difftime(nowtime
, peer
->last_update
);
801 if (diff
> (double)peer
->v_routeadv
) {
802 BGP_TIMER_OFF(peer
->t_routeadv
);
803 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, 0);
809 * - Find when to expire the MRAI timer.
810 * If MRAI timer is not active, assume we can start it now.
812 * <------- MRAI --------->
813 * |------------|-----------------------|
814 * <-------- m ----------><----- r ----->
823 if (peer
->t_routeadv
)
824 remain
= thread_timer_remain_second(peer
->t_routeadv
);
826 remain
= peer
->v_routeadv
;
827 diff
= peer
->v_routeadv
- diff
;
828 if (diff
<= (double)remain
) {
829 BGP_TIMER_OFF(peer
->t_routeadv
);
830 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, diff
);
834 static int bgp_maxmed_onstartup_applicable(struct bgp
*bgp
)
836 if (!bgp
->maxmed_onstartup_over
)
842 int bgp_maxmed_onstartup_configured(struct bgp
*bgp
)
844 if (bgp
->v_maxmed_onstartup
!= BGP_MAXMED_ONSTARTUP_UNCONFIGURED
)
850 int bgp_maxmed_onstartup_active(struct bgp
*bgp
)
852 if (bgp
->t_maxmed_onstartup
)
858 void bgp_maxmed_update(struct bgp
*bgp
)
860 uint8_t maxmed_active
;
861 uint32_t maxmed_value
;
863 if (bgp
->v_maxmed_admin
) {
865 maxmed_value
= bgp
->maxmed_admin_value
;
866 } else if (bgp
->t_maxmed_onstartup
) {
868 maxmed_value
= bgp
->maxmed_onstartup_value
;
871 maxmed_value
= BGP_MAXMED_VALUE_DEFAULT
;
874 if (bgp
->maxmed_active
!= maxmed_active
875 || bgp
->maxmed_value
!= maxmed_value
) {
876 bgp
->maxmed_active
= maxmed_active
;
877 bgp
->maxmed_value
= maxmed_value
;
879 update_group_announce(bgp
);
883 /* The maxmed onstartup timer expiry callback. */
884 static int bgp_maxmed_onstartup_timer(struct thread
*thread
)
888 zlog_info("Max med on startup ended - timer expired.");
890 bgp
= THREAD_ARG(thread
);
891 THREAD_TIMER_OFF(bgp
->t_maxmed_onstartup
);
892 bgp
->maxmed_onstartup_over
= 1;
894 bgp_maxmed_update(bgp
);
899 static void bgp_maxmed_onstartup_begin(struct bgp
*bgp
)
901 /* Applicable only once in the process lifetime on the startup */
902 if (bgp
->maxmed_onstartup_over
)
905 zlog_info("Begin maxmed onstartup mode - timer %d seconds",
906 bgp
->v_maxmed_onstartup
);
908 thread_add_timer(bm
->master
, bgp_maxmed_onstartup_timer
, bgp
,
909 bgp
->v_maxmed_onstartup
, &bgp
->t_maxmed_onstartup
);
911 if (!bgp
->v_maxmed_admin
) {
912 bgp
->maxmed_active
= 1;
913 bgp
->maxmed_value
= bgp
->maxmed_onstartup_value
;
916 /* Route announce to all peers should happen after this in
920 static void bgp_maxmed_onstartup_process_status_change(struct peer
*peer
)
922 if (peer
->status
== Established
&& !peer
->bgp
->established
) {
923 bgp_maxmed_onstartup_begin(peer
->bgp
);
927 /* The update delay timer expiry callback. */
928 static int bgp_update_delay_timer(struct thread
*thread
)
932 zlog_info("Update delay ended - timer expired.");
934 bgp
= THREAD_ARG(thread
);
935 THREAD_TIMER_OFF(bgp
->t_update_delay
);
936 bgp_update_delay_end(bgp
);
941 /* The establish wait timer expiry callback. */
942 static int bgp_establish_wait_timer(struct thread
*thread
)
946 zlog_info("Establish wait - timer expired.");
948 bgp
= THREAD_ARG(thread
);
949 THREAD_TIMER_OFF(bgp
->t_establish_wait
);
950 bgp_check_update_delay(bgp
);
955 /* Steps to begin the update delay:
956 - initialize queues if needed
957 - stop the queue processing
959 static void bgp_update_delay_begin(struct bgp
*bgp
)
961 struct listnode
*node
, *nnode
;
964 /* Stop the processing of queued work. Enqueue shall continue */
965 work_queue_plug(bm
->process_main_queue
);
967 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
968 peer
->update_delay_over
= 0;
970 /* Start the update-delay timer */
971 thread_add_timer(bm
->master
, bgp_update_delay_timer
, bgp
,
972 bgp
->v_update_delay
, &bgp
->t_update_delay
);
974 if (bgp
->v_establish_wait
!= bgp
->v_update_delay
)
975 thread_add_timer(bm
->master
, bgp_establish_wait_timer
, bgp
,
976 bgp
->v_establish_wait
, &bgp
->t_establish_wait
);
978 quagga_timestamp(3, bgp
->update_delay_begin_time
,
979 sizeof(bgp
->update_delay_begin_time
));
982 static void bgp_update_delay_process_status_change(struct peer
*peer
)
984 if (peer
->status
== Established
) {
985 if (!peer
->bgp
->established
++) {
986 bgp_update_delay_begin(peer
->bgp
);
988 "Begin read-only mode - update-delay timer %d seconds",
989 peer
->bgp
->v_update_delay
);
991 if (CHECK_FLAG(peer
->cap
, PEER_CAP_RESTART_BIT_RCV
))
992 bgp_update_restarted_peers(peer
);
994 if (peer
->ostatus
== Established
995 && bgp_update_delay_active(peer
->bgp
)) {
996 /* Adjust the update-delay state to account for this flap.
997 NOTE: Intentionally skipping adjusting implicit_eors or
999 counters. Extra sanity check in bgp_check_update_delay()
1001 be enough to take care of any additive discrepancy in bgp eor
1003 peer
->bgp
->established
--;
1004 peer
->update_delay_over
= 0;
1008 /* Called after event occurred, this function change status and reset
1009 read/write and timer thread. */
1010 void bgp_fsm_change_status(struct peer
*peer
, int status
)
1013 uint32_t peer_count
;
1016 peer_count
= bgp
->established_peers
;
1018 if (status
== Established
)
1019 bgp
->established_peers
++;
1020 else if ((peer
->status
== Established
) && (status
!= Established
))
1021 bgp
->established_peers
--;
1023 if (bgp_debug_neighbor_events(peer
)) {
1024 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
1026 zlog_debug("%s : vrf %s(%u), Status: %s established_peers %u", __func__
,
1027 vrf
? vrf
->name
: "Unknown", bgp
->vrf_id
,
1028 lookup_msg(bgp_status_msg
, status
, NULL
),
1029 bgp
->established_peers
);
1032 /* Set to router ID to the value provided by RIB if there are no peers
1033 * in the established state and peer count did not change
1035 if ((peer_count
!= bgp
->established_peers
) &&
1036 (bgp
->established_peers
== 0))
1037 bgp_router_id_zebra_bump(bgp
->vrf_id
, NULL
);
1039 /* Transition into Clearing or Deleted must /always/ clear all routes..
1040 * (and must do so before actually changing into Deleted..
1042 if (status
>= Clearing
) {
1043 bgp_clear_route_all(peer
);
1045 /* If no route was queued for the clear-node processing,
1047 * completion event here. This is needed because if there are no
1049 * to trigger the background clear-node thread, the event won't
1051 * generated and the peer would be stuck in Clearing. Note that
1053 * event is for the peer and helps the peer transition out of
1055 * state; it should not be generated per (AFI,SAFI). The event
1057 * directly posted here without calling clear_node_complete() as
1059 * shouldn't do an extra unlock. This event will get processed
1061 * the state change that happens below, so peer will be in
1065 if (!work_queue_is_scheduled(peer
->clear_node_queue
))
1066 BGP_EVENT_ADD(peer
, Clearing_Completed
);
1069 /* Preserve old status and change into new status. */
1070 peer
->ostatus
= peer
->status
;
1071 peer
->status
= status
;
1073 /* Save event that caused status change. */
1074 peer
->last_major_event
= peer
->cur_event
;
1076 /* Operations after status change */
1077 hook_call(peer_status_changed
, peer
);
1079 if (status
== Established
)
1080 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
1082 /* If max-med processing is applicable, do the necessary. */
1083 if (status
== Established
) {
1084 if (bgp_maxmed_onstartup_configured(peer
->bgp
)
1085 && bgp_maxmed_onstartup_applicable(peer
->bgp
))
1086 bgp_maxmed_onstartup_process_status_change(peer
);
1088 peer
->bgp
->maxmed_onstartup_over
= 1;
1091 /* If update-delay processing is applicable, do the necessary. */
1092 if (bgp_update_delay_configured(peer
->bgp
)
1093 && bgp_update_delay_applicable(peer
->bgp
))
1094 bgp_update_delay_process_status_change(peer
);
1096 if (bgp_debug_neighbor_events(peer
))
1097 zlog_debug("%s went from %s to %s", peer
->host
,
1098 lookup_msg(bgp_status_msg
, peer
->ostatus
, NULL
),
1099 lookup_msg(bgp_status_msg
, peer
->status
, NULL
));
1102 /* Flush the event queue and ensure the peer is shut down */
1103 static int bgp_clearing_completed(struct peer
*peer
)
1105 int rc
= bgp_stop(peer
);
1108 BGP_EVENT_FLUSH(peer
);
1113 /* Administrative BGP peer stop event. */
1114 /* May be called multiple times for the same peer */
1115 int bgp_stop(struct peer
*peer
)
1119 char orf_name
[BUFSIZ
];
1121 peer
->nsf_af_count
= 0;
1122 struct bgp
*bgp
= peer
->bgp
;
1123 struct graceful_restart_info
*gr_info
= NULL
;
1125 if (peer_dynamic_neighbor(peer
)
1126 && !(CHECK_FLAG(peer
->flags
, PEER_FLAG_DELETE
))) {
1127 if (bgp_debug_neighbor_events(peer
))
1128 zlog_debug("%s (dynamic neighbor) deleted", peer
->host
);
1133 /* Can't do this in Clearing; events are used for state transitions */
1134 if (peer
->status
!= Clearing
) {
1135 /* Delete all existing events of the peer */
1136 BGP_EVENT_FLUSH(peer
);
1139 /* Increment Dropped count. */
1140 if (peer
->status
== Established
) {
1143 /* bgp log-neighbor-changes of neighbor Down */
1144 if (bgp_flag_check(peer
->bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)) {
1145 struct vrf
*vrf
= vrf_lookup_by_id(peer
->bgp
->vrf_id
);
1148 "%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
1150 (peer
->hostname
) ? peer
->hostname
: "Unknown",
1151 vrf
? ((vrf
->vrf_id
!= VRF_DEFAULT
)
1155 peer_down_str
[(int)peer
->last_reset
]);
1158 /* graceful restart */
1159 if (peer
->t_gr_stale
) {
1160 BGP_TIMER_OFF(peer
->t_gr_stale
);
1161 if (bgp_debug_neighbor_events(peer
))
1163 "%s graceful restart stalepath timer stopped",
1166 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)) {
1167 if (bgp_debug_neighbor_events(peer
)) {
1169 "%s graceful restart timer started for %d sec",
1170 peer
->host
, peer
->v_gr_restart
);
1172 "%s graceful restart stalepath timer started for %d sec",
1173 peer
->host
, peer
->bgp
->stalepath_time
);
1175 BGP_TIMER_ON(peer
->t_gr_restart
,
1176 bgp_graceful_restart_timer_expire
,
1177 peer
->v_gr_restart
);
1178 BGP_TIMER_ON(peer
->t_gr_stale
,
1179 bgp_graceful_stale_timer_expire
,
1180 peer
->bgp
->stalepath_time
);
1182 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
1184 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1185 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
;
1187 peer
->nsf
[afi
][safi
] = 0;
1190 /* If peer reset before receiving EOR, decrement EOR count and
1191 * cancel the selection deferral timer if there are no
1192 * pending EOR messages to be received
1194 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer
)) {
1195 FOREACH_AFI_SAFI (afi
, safi
) {
1196 if (peer
->afc_nego
[afi
][safi
] &&
1197 !CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
1198 PEER_STATUS_EOR_RECEIVED
)) {
1199 gr_info
= &bgp
->gr_info
[afi
][safi
];
1200 if (gr_info
&& gr_info
->eor_required
)
1201 gr_info
->eor_required
--;
1202 if (BGP_DEBUG(update
, UPDATE_OUT
))
1203 zlog_debug("peer %s, EOR %d",
1205 gr_info
->eor_required
);
1207 /* There is no pending EOR message */
1208 if (gr_info
->eor_required
== 0) {
1210 gr_info
->t_select_deferral
);
1211 gr_info
->eor_received
= 0;
1217 /* set last reset time */
1218 peer
->resettime
= peer
->uptime
= bgp_clock();
1220 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
1221 zlog_debug("%s remove from all update group",
1223 update_group_remove_peer_afs(peer
);
1225 hook_call(peer_backward_transition
, peer
);
1227 /* Reset peer synctime */
1231 /* stop keepalives */
1232 bgp_keepalives_off(peer
);
1234 /* Stop read and write threads. */
1235 bgp_writes_off(peer
);
1236 bgp_reads_off(peer
);
1238 THREAD_OFF(peer
->t_connect_check_r
);
1239 THREAD_OFF(peer
->t_connect_check_w
);
1241 /* Stop all timers. */
1242 BGP_TIMER_OFF(peer
->t_start
);
1243 BGP_TIMER_OFF(peer
->t_connect
);
1244 BGP_TIMER_OFF(peer
->t_holdtime
);
1245 BGP_TIMER_OFF(peer
->t_routeadv
);
1247 /* Clear input and output buffer. */
1248 frr_with_mutex(&peer
->io_mtx
) {
1250 stream_fifo_clean(peer
->ibuf
);
1252 stream_fifo_clean(peer
->obuf
);
1254 if (peer
->ibuf_work
)
1255 ringbuf_wipe(peer
->ibuf_work
);
1256 if (peer
->obuf_work
)
1257 stream_reset(peer
->obuf_work
);
1260 stream_free(peer
->curr
);
1265 /* Close of file descriptor. */
1266 if (peer
->fd
>= 0) {
1271 FOREACH_AFI_SAFI (afi
, safi
) {
1272 /* Reset all negotiated variables */
1273 peer
->afc_nego
[afi
][safi
] = 0;
1274 peer
->afc_adv
[afi
][safi
] = 0;
1275 peer
->afc_recv
[afi
][safi
] = 0;
1277 /* peer address family capability flags*/
1278 peer
->af_cap
[afi
][safi
] = 0;
1280 /* peer address family status flags*/
1281 peer
->af_sflags
[afi
][safi
] = 0;
1283 /* Received ORF prefix-filter */
1284 peer
->orf_plist
[afi
][safi
] = NULL
;
1286 if ((peer
->status
== OpenConfirm
)
1287 || (peer
->status
== Established
)) {
1288 /* ORF received prefix-filter pnt */
1289 sprintf(orf_name
, "%s.%d.%d", peer
->host
, afi
, safi
);
1290 prefix_bgp_orf_remove_all(afi
, orf_name
);
1294 /* Reset keepalive and holdtime */
1295 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_TIMER
)) {
1296 peer
->v_keepalive
= peer
->keepalive
;
1297 peer
->v_holdtime
= peer
->holdtime
;
1299 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
1300 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
1303 peer
->update_time
= 0;
1305 /* Until we are sure that there is no problem about prefix count
1306 this should be commented out.*/
1308 /* Reset prefix count */
1309 peer
->pcount
[AFI_IP
][SAFI_UNICAST
] = 0;
1310 peer
->pcount
[AFI_IP
][SAFI_MULTICAST
] = 0;
1311 peer
->pcount
[AFI_IP
][SAFI_LABELED_UNICAST
] = 0;
1312 peer
->pcount
[AFI_IP
][SAFI_MPLS_VPN
] = 0;
1313 peer
->pcount
[AFI_IP6
][SAFI_UNICAST
] = 0;
1314 peer
->pcount
[AFI_IP6
][SAFI_MULTICAST
] = 0;
1315 peer
->pcount
[AFI_IP6
][SAFI_LABELED_UNICAST
] = 0;
1318 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1319 && !(CHECK_FLAG(peer
->flags
, PEER_FLAG_DELETE
))) {
1323 bgp_peer_conf_if_to_su_update(peer
);
1328 /* BGP peer is stoped by the error. */
1329 static int bgp_stop_with_error(struct peer
*peer
)
1331 /* Double start timer. */
1334 /* Overflow check. */
1335 if (peer
->v_start
>= (60 * 2))
1336 peer
->v_start
= (60 * 2);
1338 if (peer_dynamic_neighbor(peer
)) {
1339 if (bgp_debug_neighbor_events(peer
))
1340 zlog_debug("%s (dynamic neighbor) deleted", peer
->host
);
1345 return (bgp_stop(peer
));
1349 /* something went wrong, send notify and tear down */
1350 static int bgp_stop_with_notify(struct peer
*peer
, uint8_t code
,
1353 /* Send notify to remote peer */
1354 bgp_notify_send(peer
, code
, sub_code
);
1356 if (peer_dynamic_neighbor(peer
)) {
1357 if (bgp_debug_neighbor_events(peer
))
1358 zlog_debug("%s (dynamic neighbor) deleted", peer
->host
);
1363 /* Clear start timer value to default. */
1364 peer
->v_start
= BGP_INIT_START_TIMER
;
1366 return (bgp_stop(peer
));
1370 * Determines whether a TCP session has successfully established for a peer and
1371 * events as appropriate.
1373 * This function is called when setting up a new session. After connect() is
1374 * called on the peer's socket (in bgp_start()), the fd is passed to poll()
1375 * to wait for connection success or failure. When poll() returns, this
1376 * function is called to evaluate the result.
1378 * Due to differences in behavior of poll() on Linux and BSD - specifically,
1379 * the value of .revents in the case of a closed connection - this function is
1380 * scheduled both for a read and a write event. The write event is triggered
1381 * when the connection is established. A read event is triggered when the
1382 * connection is closed. Thus we need to cancel whichever one did not occur.
1384 static int bgp_connect_check(struct thread
*thread
)
1391 peer
= THREAD_ARG(thread
);
1392 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
1393 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
1394 assert(!peer
->t_read
);
1395 assert(!peer
->t_write
);
1397 THREAD_OFF(peer
->t_connect_check_r
);
1398 THREAD_OFF(peer
->t_connect_check_w
);
1400 /* Check file descriptor. */
1401 slen
= sizeof(status
);
1402 ret
= getsockopt(peer
->fd
, SOL_SOCKET
, SO_ERROR
, (void *)&status
,
1405 /* If getsockopt is fail, this is fatal error. */
1407 zlog_err("can't get sockopt for nonblocking connect: %d(%s)",
1408 errno
, safe_strerror(errno
));
1409 BGP_EVENT_ADD(peer
, TCP_fatal_error
);
1413 /* When status is 0 then TCP connection is established. */
1415 BGP_EVENT_ADD(peer
, TCP_connection_open
);
1418 if (bgp_debug_neighbor_events(peer
))
1419 zlog_debug("%s [Event] Connect failed %d(%s)",
1420 peer
->host
, status
, safe_strerror(status
));
1421 BGP_EVENT_ADD(peer
, TCP_connection_open_failed
);
1426 /* TCP connection open. Next we send open message to remote peer. And
1427 add read thread for reading open message. */
1428 static int bgp_connect_success(struct peer
*peer
)
1431 flog_err(EC_BGP_CONNECT
,
1432 "bgp_connect_success peer's fd is negative value %d",
1438 if (bgp_getsockname(peer
) < 0) {
1439 flog_err_sys(EC_LIB_SOCKET
,
1440 "%s: bgp_getsockname(): failed for peer %s, fd %d",
1441 __FUNCTION__
, peer
->host
, peer
->fd
);
1443 peer
, BGP_NOTIFY_FSM_ERR
,
1444 BGP_NOTIFY_SUBCODE_UNSPECIFIC
); /* internal error */
1445 bgp_writes_on(peer
);
1451 if (bgp_debug_neighbor_events(peer
)) {
1452 char buf1
[SU_ADDRSTRLEN
];
1454 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
))
1455 zlog_debug("%s open active, local address %s",
1457 sockunion2str(peer
->su_local
, buf1
,
1460 zlog_debug("%s passive open", peer
->host
);
1463 bgp_open_send(peer
);
1468 /* TCP connect fail */
1469 static int bgp_connect_fail(struct peer
*peer
)
1471 if (peer_dynamic_neighbor(peer
)) {
1472 if (bgp_debug_neighbor_events(peer
))
1473 zlog_debug("%s (dynamic neighbor) deleted", peer
->host
);
1478 return (bgp_stop(peer
));
1481 /* This function is the first starting point of all BGP connection. It
1482 try to connect to remote peer with non-blocking IO. */
1483 int bgp_start(struct peer
*peer
)
1487 bgp_peer_conf_if_to_su_update(peer
);
1489 if (peer
->su
.sa
.sa_family
== AF_UNSPEC
) {
1490 if (bgp_debug_neighbor_events(peer
))
1492 "%s [FSM] Unable to get neighbor's IP address, waiting...",
1494 peer
->last_reset
= PEER_DOWN_NBR_ADDR
;
1498 if (BGP_PEER_START_SUPPRESSED(peer
)) {
1499 if (bgp_debug_neighbor_events(peer
))
1500 flog_err(EC_BGP_FSM
,
1501 "%s [FSM] Trying to start suppressed peer"
1502 " - this is never supposed to happen!",
1507 /* Scrub some information that might be left over from a previous,
1510 /* Connection information. */
1511 if (peer
->su_local
) {
1512 sockunion_free(peer
->su_local
);
1513 peer
->su_local
= NULL
;
1516 if (peer
->su_remote
) {
1517 sockunion_free(peer
->su_remote
);
1518 peer
->su_remote
= NULL
;
1521 /* Clear remote router-id. */
1522 peer
->remote_id
.s_addr
= 0;
1524 /* Clear peer capability flag. */
1527 /* If the peer is passive mode, force to move to Active mode. */
1528 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)) {
1529 BGP_EVENT_ADD(peer
, TCP_connection_open_failed
);
1533 if (peer
->bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
&&
1534 peer
->bgp
->vrf_id
== VRF_UNKNOWN
) {
1535 if (bgp_debug_neighbor_events(peer
))
1538 "%s [FSM] In a VRF that is not initialised yet",
1540 peer
->last_reset
= PEER_DOWN_VRF_UNINIT
;
1544 /* Register peer for NHT. If next hop is already resolved, proceed
1545 * with connection setup, else wait.
1547 if (!bgp_peer_reg_with_nht(peer
)) {
1548 if (bgp_zebra_num_connects()) {
1549 if (bgp_debug_neighbor_events(peer
))
1550 zlog_debug("%s [FSM] Waiting for NHT",
1552 peer
->last_reset
= PEER_DOWN_WAITING_NHT
;
1553 BGP_EVENT_ADD(peer
, TCP_connection_open_failed
);
1558 assert(!peer
->t_write
);
1559 assert(!peer
->t_read
);
1560 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
1561 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
1562 status
= bgp_connect(peer
);
1566 if (bgp_debug_neighbor_events(peer
))
1567 zlog_debug("%s [FSM] Connect error", peer
->host
);
1568 BGP_EVENT_ADD(peer
, TCP_connection_open_failed
);
1570 case connect_success
:
1571 if (bgp_debug_neighbor_events(peer
))
1573 "%s [FSM] Connect immediately success, fd %d",
1574 peer
->host
, peer
->fd
);
1575 BGP_EVENT_ADD(peer
, TCP_connection_open
);
1577 case connect_in_progress
:
1578 /* To check nonblocking connect, we wait until socket is
1579 readable or writable. */
1580 if (bgp_debug_neighbor_events(peer
))
1582 "%s [FSM] Non blocking connect waiting result, fd %d",
1583 peer
->host
, peer
->fd
);
1585 flog_err(EC_BGP_FSM
,
1586 "bgp_start peer's fd is negative value %d",
1591 * - when the socket becomes ready, poll() will signify POLLOUT
1592 * - if it fails to connect, poll() will signify POLLHUP
1593 * - POLLHUP is handled as a 'read' event by thread.c
1595 * therefore, we schedule both a read and a write event with
1596 * bgp_connect_check() as the handler for each and cancel the
1597 * unused event in that function.
1599 thread_add_read(bm
->master
, bgp_connect_check
, peer
, peer
->fd
,
1600 &peer
->t_connect_check_r
);
1601 thread_add_write(bm
->master
, bgp_connect_check
, peer
, peer
->fd
,
1602 &peer
->t_connect_check_w
);
1608 /* Connect retry timer is expired when the peer status is Connect. */
1609 static int bgp_reconnect(struct peer
*peer
)
1611 if (bgp_stop(peer
) < 0)
1618 static int bgp_fsm_open(struct peer
*peer
)
1620 /* Send keepalive and make keepalive timer */
1621 bgp_keepalive_send(peer
);
1623 /* Reset holdtimer value. */
1624 BGP_TIMER_OFF(peer
->t_holdtime
);
1629 /* FSM error, unexpected event. This is error of BGP connection. So cut the
1630 peer and change to Idle status. */
1631 static int bgp_fsm_event_error(struct peer
*peer
)
1633 flog_err(EC_BGP_FSM
, "%s [FSM] unexpected packet received in state %s",
1634 peer
->host
, lookup_msg(bgp_status_msg
, peer
->status
, NULL
));
1636 return bgp_stop_with_notify(peer
, BGP_NOTIFY_FSM_ERR
, 0);
1639 /* Hold timer expire. This is error of BGP connection. So cut the
1640 peer and change to Idle status. */
1641 static int bgp_fsm_holdtime_expire(struct peer
*peer
)
1643 if (bgp_debug_neighbor_events(peer
))
1644 zlog_debug("%s [FSM] Hold timer expire", peer
->host
);
1646 return bgp_stop_with_notify(peer
, BGP_NOTIFY_HOLD_ERR
, 0);
1649 /* Start the selection deferral timer thread for the specified AFI, SAFI */
1650 static int bgp_start_deferral_timer(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1651 struct graceful_restart_info
*gr_info
)
1653 struct afi_safi_info
*thread_info
;
1655 /* If the deferral timer is active, then increment eor count */
1656 if (gr_info
->t_select_deferral
) {
1657 gr_info
->eor_required
++;
1661 /* Start the deferral timer when the first peer enabled for the graceful
1662 * restart is established
1664 if (gr_info
->eor_required
== 0) {
1665 thread_info
= XMALLOC(MTYPE_TMP
, sizeof(struct afi_safi_info
));
1666 if (thread_info
== NULL
) {
1667 if (BGP_DEBUG(update
, UPDATE_OUT
))
1668 zlog_debug("%s : Error allocating thread info",
1673 thread_info
->afi
= afi
;
1674 thread_info
->safi
= safi
;
1675 thread_info
->bgp
= bgp
;
1677 thread_add_timer(bm
->master
,
1678 bgp_graceful_deferral_timer_expire
,
1679 thread_info
, bgp
->select_defer_time
,
1680 &gr_info
->t_select_deferral
);
1681 if (gr_info
->t_select_deferral
== NULL
) {
1682 if (BGP_DEBUG(update
, UPDATE_OUT
))
1683 zlog_debug("Error starting deferral timer for %s",
1684 get_afi_safi_str(afi
, safi
, false));
1689 gr_info
->eor_required
++;
1690 if (BGP_DEBUG(update
, UPDATE_OUT
))
1691 zlog_debug("Started the deferral timer for %s eor_required %d",
1692 get_afi_safi_str(afi
, safi
, false),
1693 gr_info
->eor_required
);
1697 /* Update the graceful restart information for the specified AFI, SAFI */
1698 static int bgp_update_gr_info(struct peer
*peer
, afi_t afi
, safi_t safi
)
1700 struct graceful_restart_info
*gr_info
;
1701 struct bgp
*bgp
= peer
->bgp
;
1704 if ((afi
< AFI_IP
) || (afi
>= AFI_MAX
)) {
1705 if (BGP_DEBUG(update
, UPDATE_OUT
))
1706 zlog_debug("%s : invalid afi %d", __func__
, afi
);
1710 if ((safi
< SAFI_UNICAST
) || (safi
> SAFI_MPLS_VPN
)) {
1711 if (BGP_DEBUG(update
, UPDATE_OUT
))
1712 zlog_debug("%s : invalid safi %d", __func__
, safi
);
1716 /* Restarting router */
1717 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer
) &&
1718 BGP_PEER_RESTARTING_MODE(peer
)) {
1719 /* Check if the forwarding state is preserved */
1720 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
)) {
1721 gr_info
= &(bgp
->gr_info
[afi
][safi
]);
1722 ret
= bgp_start_deferral_timer(bgp
, afi
, safi
, gr_info
);
1729 * Transition to Established state.
1731 * Convert peer from stub to full fledged peer, set some timers, and generate
1734 static int bgp_establish(struct peer
*peer
)
1738 int nsf_af_count
= 0;
1743 other
= peer
->doppelganger
;
1744 peer
= peer_xfer_conn(peer
);
1746 flog_err(EC_BGP_CONNECT
, "%%Neighbor failed in xfer_conn");
1751 ret
= 1; /* bgp_establish specific code when xfer_conn
1754 /* Reset capability open status flag. */
1755 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
))
1756 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1758 /* Clear start timer value to default. */
1759 peer
->v_start
= BGP_INIT_START_TIMER
;
1761 /* Increment established count. */
1762 peer
->established
++;
1763 bgp_fsm_change_status(peer
, Established
);
1765 /* bgp log-neighbor-changes of neighbor Up */
1766 if (bgp_flag_check(peer
->bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)) {
1767 struct vrf
*vrf
= vrf_lookup_by_id(peer
->bgp
->vrf_id
);
1768 zlog_info("%%ADJCHANGE: neighbor %s(%s) in vrf %s Up",
1770 (peer
->hostname
) ? peer
->hostname
: "Unknown",
1771 vrf
? ((vrf
->vrf_id
!= VRF_DEFAULT
)
1776 /* assign update-group/subgroup */
1777 update_group_adjust_peer_afs(peer
);
1779 /* graceful restart */
1780 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
1781 if (bgp_debug_neighbor_events(peer
)) {
1782 if (BGP_PEER_RESTARTING_MODE(peer
))
1783 zlog_debug("peer %s BGP_RESTARTING_MODE",
1785 else if (BGP_PEER_HELPER_MODE(peer
))
1786 zlog_debug("peer %s BGP_HELPER_MODE",
1789 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1790 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++) {
1791 if (peer
->afc_nego
[afi
][safi
]
1792 && CHECK_FLAG(peer
->cap
, PEER_CAP_RESTART_ADV
)
1793 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1794 PEER_CAP_RESTART_AF_RCV
)) {
1795 if (peer
->nsf
[afi
][safi
]
1797 peer
->af_cap
[afi
][safi
],
1798 PEER_CAP_RESTART_AF_PRESERVE_RCV
))
1799 bgp_clear_stale_route(peer
, afi
, safi
);
1801 peer
->nsf
[afi
][safi
] = 1;
1804 if (peer
->nsf
[afi
][safi
])
1805 bgp_clear_stale_route(peer
, afi
, safi
);
1806 peer
->nsf
[afi
][safi
] = 0;
1808 /* Update the graceful restart information */
1809 if (peer
->afc_nego
[afi
][safi
]) {
1810 if (!BGP_SELECT_DEFER_DISABLE(peer
->bgp
)) {
1811 status
= bgp_update_gr_info(peer
, afi
,
1814 zlog_debug("Error in updating graceful restart for %s",
1815 get_afi_safi_str(afi
,
1821 peer
->nsf_af_count
= nsf_af_count
;
1824 SET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
1826 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
1827 if (peer
->t_gr_stale
) {
1828 BGP_TIMER_OFF(peer
->t_gr_stale
);
1829 if (bgp_debug_neighbor_events(peer
))
1831 "%s graceful restart stalepath timer stopped",
1836 if (peer
->t_gr_restart
) {
1837 BGP_TIMER_OFF(peer
->t_gr_restart
);
1838 if (bgp_debug_neighbor_events(peer
))
1839 zlog_debug("%s graceful restart timer stopped",
1843 /* Reset uptime, turn on keepalives, send current table. */
1844 if (!peer
->v_holdtime
)
1845 bgp_keepalives_on(peer
);
1847 peer
->uptime
= bgp_clock();
1849 /* Send route-refresh when ORF is enabled */
1850 FOREACH_AFI_SAFI (afi
, safi
) {
1851 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1852 PEER_CAP_ORF_PREFIX_SM_ADV
)) {
1853 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1854 PEER_CAP_ORF_PREFIX_RM_RCV
))
1855 bgp_route_refresh_send(peer
, afi
, safi
,
1857 REFRESH_IMMEDIATE
, 0);
1858 else if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1859 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))
1860 bgp_route_refresh_send(peer
, afi
, safi
,
1861 ORF_TYPE_PREFIX_OLD
,
1862 REFRESH_IMMEDIATE
, 0);
1866 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1867 FOREACH_AFI_SAFI (afi
, safi
) {
1868 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1869 PEER_CAP_ORF_PREFIX_RM_ADV
))
1870 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1871 PEER_CAP_ORF_PREFIX_SM_RCV
)
1872 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1873 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
))
1874 SET_FLAG(peer
->af_sflags
[afi
][safi
],
1875 PEER_STATUS_ORF_WAIT_REFRESH
);
1878 bgp_announce_peer(peer
);
1880 /* Start the route advertisement timer to send updates to the peer - if
1882 * is not in read-only mode. If it is, the timer will be started at the
1884 * of read-only mode.
1886 if (!bgp_update_delay_active(peer
->bgp
)) {
1887 BGP_TIMER_OFF(peer
->t_routeadv
);
1888 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, 0);
1891 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)) {
1892 if (bgp_debug_neighbor_events(peer
))
1894 "[Event] Deleting stub connection for peer %s",
1897 if (peer
->doppelganger
->status
> Active
)
1898 bgp_notify_send(peer
->doppelganger
, BGP_NOTIFY_CEASE
,
1899 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION
);
1901 peer_delete(peer
->doppelganger
);
1905 * If we are replacing the old peer for a doppelganger
1906 * then switch it around in the bgp->peerhash
1907 * the doppelgangers su and this peer's su are the same
1908 * so the hash_release is the same for either.
1910 hash_release(peer
->bgp
->peerhash
, peer
);
1911 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1913 bgp_bfd_register_peer(peer
);
1917 /* Keepalive packet is received. */
1918 static int bgp_fsm_keepalive(struct peer
*peer
)
1920 BGP_TIMER_OFF(peer
->t_holdtime
);
1924 /* Update packet is received. */
1925 static int bgp_fsm_update(struct peer
*peer
)
1927 BGP_TIMER_OFF(peer
->t_holdtime
);
1931 /* This is empty event. */
1932 static int bgp_ignore(struct peer
*peer
)
1936 "%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d",
1937 peer
->host
, bgp_event_str
[peer
->cur_event
],
1938 lookup_msg(bgp_status_msg
, peer
->status
, NULL
),
1939 bgp_event_str
[peer
->last_event
],
1940 bgp_event_str
[peer
->last_major_event
], peer
->fd
);
1944 /* This is to handle unexpected events.. */
1945 static int bgp_fsm_exeption(struct peer
*peer
)
1949 "%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d",
1950 peer
->host
, bgp_event_str
[peer
->cur_event
],
1951 lookup_msg(bgp_status_msg
, peer
->status
, NULL
),
1952 bgp_event_str
[peer
->last_event
],
1953 bgp_event_str
[peer
->last_major_event
], peer
->fd
);
1954 return (bgp_stop(peer
));
1957 void bgp_fsm_event_update(struct peer
*peer
, int valid
)
1962 switch (peer
->status
) {
1965 BGP_EVENT_ADD(peer
, BGP_Start
);
1969 BGP_TIMER_OFF(peer
->t_connect
);
1970 BGP_EVENT_ADD(peer
, TCP_fatal_error
);
1975 BGP_TIMER_OFF(peer
->t_connect
);
1976 BGP_EVENT_ADD(peer
, ConnectRetry_timer_expired
);
1982 if (!valid
&& (peer
->gtsm_hops
== 1))
1983 BGP_EVENT_ADD(peer
, TCP_fatal_error
);
1991 /* Finite State Machine structure */
1992 static const struct {
1993 int (*func
)(struct peer
*);
1995 } FSM
[BGP_STATUS_MAX
- 1][BGP_EVENTS_MAX
- 1] = {
1997 /* Idle state: In Idle state, all events other than BGP_Start is
1998 ignored. With BGP_Start event, finite state machine calls
2000 {bgp_start
, Connect
}, /* BGP_Start */
2001 {bgp_stop
, Idle
}, /* BGP_Stop */
2002 {bgp_stop
, Idle
}, /* TCP_connection_open */
2003 {bgp_stop
, Idle
}, /* TCP_connection_closed */
2004 {bgp_ignore
, Idle
}, /* TCP_connection_open_failed */
2005 {bgp_stop
, Idle
}, /* TCP_fatal_error */
2006 {bgp_ignore
, Idle
}, /* ConnectRetry_timer_expired */
2007 {bgp_ignore
, Idle
}, /* Hold_Timer_expired */
2008 {bgp_ignore
, Idle
}, /* KeepAlive_timer_expired */
2009 {bgp_ignore
, Idle
}, /* Receive_OPEN_message */
2010 {bgp_ignore
, Idle
}, /* Receive_KEEPALIVE_message */
2011 {bgp_ignore
, Idle
}, /* Receive_UPDATE_message */
2012 {bgp_ignore
, Idle
}, /* Receive_NOTIFICATION_message */
2013 {bgp_ignore
, Idle
}, /* Clearing_Completed */
2017 {bgp_ignore
, Connect
}, /* BGP_Start */
2018 {bgp_stop
, Idle
}, /* BGP_Stop */
2019 {bgp_connect_success
, OpenSent
}, /* TCP_connection_open */
2020 {bgp_stop
, Idle
}, /* TCP_connection_closed */
2021 {bgp_connect_fail
, Active
}, /* TCP_connection_open_failed */
2022 {bgp_connect_fail
, Idle
}, /* TCP_fatal_error */
2023 {bgp_reconnect
, Connect
}, /* ConnectRetry_timer_expired */
2024 {bgp_fsm_exeption
, Idle
}, /* Hold_Timer_expired */
2025 {bgp_fsm_exeption
, Idle
}, /* KeepAlive_timer_expired */
2026 {bgp_fsm_exeption
, Idle
}, /* Receive_OPEN_message */
2027 {bgp_fsm_exeption
, Idle
}, /* Receive_KEEPALIVE_message */
2028 {bgp_fsm_exeption
, Idle
}, /* Receive_UPDATE_message */
2029 {bgp_stop
, Idle
}, /* Receive_NOTIFICATION_message */
2030 {bgp_fsm_exeption
, Idle
}, /* Clearing_Completed */
2034 {bgp_ignore
, Active
}, /* BGP_Start */
2035 {bgp_stop
, Idle
}, /* BGP_Stop */
2036 {bgp_connect_success
, OpenSent
}, /* TCP_connection_open */
2037 {bgp_stop
, Idle
}, /* TCP_connection_closed */
2038 {bgp_ignore
, Active
}, /* TCP_connection_open_failed */
2039 {bgp_fsm_exeption
, Idle
}, /* TCP_fatal_error */
2040 {bgp_start
, Connect
}, /* ConnectRetry_timer_expired */
2041 {bgp_fsm_exeption
, Idle
}, /* Hold_Timer_expired */
2042 {bgp_fsm_exeption
, Idle
}, /* KeepAlive_timer_expired */
2043 {bgp_fsm_exeption
, Idle
}, /* Receive_OPEN_message */
2044 {bgp_fsm_exeption
, Idle
}, /* Receive_KEEPALIVE_message */
2045 {bgp_fsm_exeption
, Idle
}, /* Receive_UPDATE_message */
2046 {bgp_fsm_exeption
, Idle
}, /* Receive_NOTIFICATION_message */
2047 {bgp_fsm_exeption
, Idle
}, /* Clearing_Completed */
2051 {bgp_ignore
, OpenSent
}, /* BGP_Start */
2052 {bgp_stop
, Idle
}, /* BGP_Stop */
2053 {bgp_stop
, Active
}, /* TCP_connection_open */
2054 {bgp_stop
, Active
}, /* TCP_connection_closed */
2055 {bgp_stop
, Active
}, /* TCP_connection_open_failed */
2056 {bgp_stop
, Active
}, /* TCP_fatal_error */
2057 {bgp_fsm_exeption
, Idle
}, /* ConnectRetry_timer_expired */
2058 {bgp_fsm_holdtime_expire
, Idle
}, /* Hold_Timer_expired */
2059 {bgp_fsm_exeption
, Idle
}, /* KeepAlive_timer_expired */
2060 {bgp_fsm_open
, OpenConfirm
}, /* Receive_OPEN_message */
2061 {bgp_fsm_event_error
, Idle
}, /* Receive_KEEPALIVE_message */
2062 {bgp_fsm_event_error
, Idle
}, /* Receive_UPDATE_message */
2063 {bgp_fsm_event_error
, Idle
}, /* Receive_NOTIFICATION_message */
2064 {bgp_fsm_exeption
, Idle
}, /* Clearing_Completed */
2068 {bgp_ignore
, OpenConfirm
}, /* BGP_Start */
2069 {bgp_stop
, Idle
}, /* BGP_Stop */
2070 {bgp_stop
, Idle
}, /* TCP_connection_open */
2071 {bgp_stop
, Idle
}, /* TCP_connection_closed */
2072 {bgp_stop
, Idle
}, /* TCP_connection_open_failed */
2073 {bgp_stop
, Idle
}, /* TCP_fatal_error */
2074 {bgp_fsm_exeption
, Idle
}, /* ConnectRetry_timer_expired */
2075 {bgp_fsm_holdtime_expire
, Idle
}, /* Hold_Timer_expired */
2076 {bgp_ignore
, OpenConfirm
}, /* KeepAlive_timer_expired */
2077 {bgp_fsm_exeption
, Idle
}, /* Receive_OPEN_message */
2078 {bgp_establish
, Established
}, /* Receive_KEEPALIVE_message */
2079 {bgp_fsm_exeption
, Idle
}, /* Receive_UPDATE_message */
2080 {bgp_stop_with_error
, Idle
}, /* Receive_NOTIFICATION_message */
2081 {bgp_fsm_exeption
, Idle
}, /* Clearing_Completed */
2085 {bgp_ignore
, Established
}, /* BGP_Start */
2086 {bgp_stop
, Clearing
}, /* BGP_Stop */
2087 {bgp_stop
, Clearing
}, /* TCP_connection_open */
2088 {bgp_stop
, Clearing
}, /* TCP_connection_closed */
2089 {bgp_stop
, Clearing
}, /* TCP_connection_open_failed */
2090 {bgp_stop
, Clearing
}, /* TCP_fatal_error */
2091 {bgp_stop
, Clearing
}, /* ConnectRetry_timer_expired */
2092 {bgp_fsm_holdtime_expire
, Clearing
}, /* Hold_Timer_expired */
2093 {bgp_ignore
, Established
}, /* KeepAlive_timer_expired */
2094 {bgp_stop
, Clearing
}, /* Receive_OPEN_message */
2096 Established
}, /* Receive_KEEPALIVE_message */
2097 {bgp_fsm_update
, Established
}, /* Receive_UPDATE_message */
2098 {bgp_stop_with_error
,
2099 Clearing
}, /* Receive_NOTIFICATION_message */
2100 {bgp_fsm_exeption
, Idle
}, /* Clearing_Completed */
2104 {bgp_ignore
, Clearing
}, /* BGP_Start */
2105 {bgp_stop
, Clearing
}, /* BGP_Stop */
2106 {bgp_stop
, Clearing
}, /* TCP_connection_open */
2107 {bgp_stop
, Clearing
}, /* TCP_connection_closed */
2108 {bgp_stop
, Clearing
}, /* TCP_connection_open_failed */
2109 {bgp_stop
, Clearing
}, /* TCP_fatal_error */
2110 {bgp_stop
, Clearing
}, /* ConnectRetry_timer_expired */
2111 {bgp_stop
, Clearing
}, /* Hold_Timer_expired */
2112 {bgp_stop
, Clearing
}, /* KeepAlive_timer_expired */
2113 {bgp_stop
, Clearing
}, /* Receive_OPEN_message */
2114 {bgp_stop
, Clearing
}, /* Receive_KEEPALIVE_message */
2115 {bgp_stop
, Clearing
}, /* Receive_UPDATE_message */
2116 {bgp_stop
, Clearing
}, /* Receive_NOTIFICATION_message */
2117 {bgp_clearing_completed
, Idle
}, /* Clearing_Completed */
2121 {bgp_ignore
, Deleted
}, /* BGP_Start */
2122 {bgp_ignore
, Deleted
}, /* BGP_Stop */
2123 {bgp_ignore
, Deleted
}, /* TCP_connection_open */
2124 {bgp_ignore
, Deleted
}, /* TCP_connection_closed */
2125 {bgp_ignore
, Deleted
}, /* TCP_connection_open_failed */
2126 {bgp_ignore
, Deleted
}, /* TCP_fatal_error */
2127 {bgp_ignore
, Deleted
}, /* ConnectRetry_timer_expired */
2128 {bgp_ignore
, Deleted
}, /* Hold_Timer_expired */
2129 {bgp_ignore
, Deleted
}, /* KeepAlive_timer_expired */
2130 {bgp_ignore
, Deleted
}, /* Receive_OPEN_message */
2131 {bgp_ignore
, Deleted
}, /* Receive_KEEPALIVE_message */
2132 {bgp_ignore
, Deleted
}, /* Receive_UPDATE_message */
2133 {bgp_ignore
, Deleted
}, /* Receive_NOTIFICATION_message */
2134 {bgp_ignore
, Deleted
}, /* Clearing_Completed */
2138 /* Execute event process. */
2139 int bgp_event(struct thread
*thread
)
2145 peer
= THREAD_ARG(thread
);
2146 event
= THREAD_VAL(thread
);
2148 ret
= bgp_event_update(peer
, event
);
2153 int bgp_event_update(struct peer
*peer
, int event
)
2158 int passive_conn
= 0;
2161 /* default return code */
2162 ret
= FSM_PEER_NOOP
;
2164 other
= peer
->doppelganger
;
2166 (CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
)) ? 1 : 0;
2167 dyn_nbr
= peer_dynamic_neighbor(peer
);
2169 /* Logging this event. */
2170 next
= FSM
[peer
->status
- 1][event
- 1].next_state
;
2172 if (bgp_debug_neighbor_events(peer
) && peer
->status
!= next
)
2173 zlog_debug("%s [FSM] %s (%s->%s), fd %d", peer
->host
,
2174 bgp_event_str
[event
],
2175 lookup_msg(bgp_status_msg
, peer
->status
, NULL
),
2176 lookup_msg(bgp_status_msg
, next
, NULL
), peer
->fd
);
2178 peer
->last_event
= peer
->cur_event
;
2179 peer
->cur_event
= event
;
2181 /* Call function. */
2182 if (FSM
[peer
->status
- 1][event
- 1].func
)
2183 ret
= (*(FSM
[peer
->status
- 1][event
- 1].func
))(peer
);
2186 if (ret
== 1 && next
== Established
) {
2187 /* The case when doppelganger swap accurred in
2189 Update the peer pointer accordingly */
2190 ret
= FSM_PEER_TRANSFERRED
;
2194 /* If status is changed. */
2195 if (next
!= peer
->status
) {
2196 bgp_fsm_change_status(peer
, next
);
2199 * If we're going to ESTABLISHED then we executed a
2200 * peer transfer. In this case we can either return
2201 * FSM_PEER_TRANSITIONED or FSM_PEER_TRANSFERRED.
2202 * Opting for TRANSFERRED since transfer implies
2203 * session establishment.
2205 if (ret
!= FSM_PEER_TRANSFERRED
)
2206 ret
= FSM_PEER_TRANSITIONED
;
2209 /* Make sure timer is set. */
2210 bgp_timer_set(peer
);
2214 * If we got a return value of -1, that means there was an
2215 * error, restart the FSM. Since bgp_stop() was called on the
2216 * peer. only a few fields are safe to access here. In any case
2217 * we need to indicate that the peer was stopped in the return
2220 if (!dyn_nbr
&& !passive_conn
&& peer
->bgp
) {
2223 "%s [FSM] Failure handling event %s in state %s, "
2224 "prior events %s, %s, fd %d",
2225 peer
->host
, bgp_event_str
[peer
->cur_event
],
2226 lookup_msg(bgp_status_msg
, peer
->status
, NULL
),
2227 bgp_event_str
[peer
->last_event
],
2228 bgp_event_str
[peer
->last_major_event
],
2231 bgp_fsm_change_status(peer
, Idle
);
2232 bgp_timer_set(peer
);
2234 ret
= FSM_PEER_STOPPED
;
2241 int bgp_gr_lookup_n_update_all_peer(struct bgp
*bgp
,
2242 enum global_mode global_new_state
,
2243 enum global_mode global_old_state
)
2245 struct peer
*peer
= {0};
2246 struct listnode
*node
= {0};
2247 struct listnode
*nnode
= {0};
2248 enum peer_mode peer_old_state
= PEER_INVALID
;
2250 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
2252 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2254 "BGP_GR:: %s ---> Peer: (%s) :",
2255 __func__
, peer
->host
);
2257 peer_old_state
= bgp_peer_gr_mode_get(peer
);
2259 if (peer_old_state
== PEER_GLOBAL_INHERIT
) {
2262 *Reset only these peers and send a
2263 *new open message with the change capabilities.
2264 *Considering the mode to be "global_new_state" and
2265 *do all operation accordingly
2268 switch (global_new_state
) {
2272 BGP_PEER_GR_HELPER_ENABLE(peer
);
2276 BGP_PEER_GR_ENABLE(peer
);
2278 case GLOBAL_DISABLE
:
2280 BGP_PEER_GR_DISABLE(peer
);
2282 case GLOBAL_INVALID
:
2285 "BGP_GR:: %s :GLOBAL_INVALID",
2287 return BGP_ERR_GR_OPERATION_FAILED
;
2291 "BGP_GR:: %s :Global unknown ERROR",
2293 return BGP_ERR_GR_OPERATION_FAILED
;
2298 bgp
->global_gr_present_state
= global_new_state
;
2300 /* debug Trace msg */
2301 return BGP_GR_SUCCESS
;
2304 int bgp_gr_update_all(struct bgp
*bgp
, int global_GR_Cmd
)
2306 enum global_mode global_new_state
= GLOBAL_INVALID
;
2307 enum global_mode global_old_state
= GLOBAL_INVALID
;
2309 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2311 "BGP_GR::%s:START ---> global_GR_Cmd :%d:",
2312 __func__
, global_GR_Cmd
);
2314 global_old_state
= bgp_global_gr_mode_get(bgp
);
2316 if (global_old_state
!= GLOBAL_INVALID
) {
2319 bgp
->GLOBAL_GR_FSM
[global_old_state
][global_GR_Cmd
];
2322 zlog_debug("BGP_GR::%s:global_old_state == GLOBAL_INVALID",
2324 return BGP_ERR_GR_OPERATION_FAILED
;
2327 if (global_new_state
== GLOBAL_INVALID
) {
2330 "BGP_GR::%s: global_new_state == GLOBAL_INVALID",
2332 return BGP_ERR_GR_INVALID_CMD
;
2334 if (global_new_state
== global_old_state
) {
2337 "BGP_GR::%s : global_new_state == global_old_state",
2339 return BGP_GR_NO_OPERATION
;
2342 return bgp_gr_lookup_n_update_all_peer(bgp
,
2347 enum global_mode
bgp_global_gr_mode_get(struct bgp
*bgp
)
2349 return bgp
->global_gr_present_state
;
2352 enum peer_mode
bgp_peer_gr_mode_get(struct peer
*peer
)
2354 return peer
->peer_gr_present_state
;
2357 int bgp_neighbor_graceful_restart(struct peer
*peer
,
2360 enum peer_mode peer_new_state
= PEER_INVALID
;
2361 enum peer_mode peer_old_state
= PEER_INVALID
;
2362 struct bgp_peer_gr peer_state
;
2363 int result
= BGP_GR_FAILURE
;
2366 * fetch peer_old_state from peer structure also
2367 * fetch global_old_state from bgp structure,
2368 * peer had a back pointer to bgpo struct ;
2371 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2373 "BGP_GR:: %s:START--->Peer: (%s) : peer_GR_Cmd :%d:",
2374 __func__
, peer
->host
, peer_GR_Cmd
);
2376 peer_old_state
= bgp_peer_gr_mode_get(peer
);
2378 if (peer_old_state
== PEER_INVALID
) {
2379 /* debug Trace msg */
2381 "BGP_GR:: peer_old_state ==Invalid state !");
2382 return BGP_ERR_GR_OPERATION_FAILED
;
2385 peer_state
= peer
->PEER_GR_FSM
[peer_old_state
][peer_GR_Cmd
];
2386 peer_new_state
= peer_state
.next_state
;
2388 if (peer_new_state
== PEER_INVALID
) {
2389 /* debug Trace msg */
2391 "BGP_GR:: Invalid bgp graceful restart command used !");
2392 return BGP_ERR_GR_INVALID_CMD
;
2395 if (peer_new_state
!= peer_old_state
) {
2396 result
= peer_state
.action_fun(peer
,
2400 /* debug Trace msg */
2402 "BGP_GR:: peer_old_state == peer_new_state !");
2403 return BGP_GR_NO_OPERATION
;
2406 if (result
== BGP_GR_SUCCESS
) {
2408 /* Update the mode i.e peer_new_state into the peer structure */
2409 peer
->peer_gr_present_state
= peer_new_state
;
2410 /* debug Trace msg */
2411 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2412 zlog_debug("BGP_GR:: Succesfully change the state of the peer to : %d : !",
2415 return BGP_GR_SUCCESS
;
2421 unsigned int bgp_peer_gr_action(struct peer
*peer
,
2422 int old_peer_state
, int new_peer_state
)
2424 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2426 "BGP_GR:: %s : Move peer from old_peer_state :%d: to old_peer_state :%d: !!!!",
2427 __func__
, old_peer_state
, new_peer_state
);
2429 int bgp_gr_global_mode
= GLOBAL_INVALID
;
2430 unsigned int ret
= BGP_GR_FAILURE
;
2432 if (old_peer_state
== new_peer_state
) {
2433 /* Nothing to do over here as the present and old state is the same */
2434 /* debug Trace msg */
2435 return BGP_GR_NO_OPERATION
;
2437 if ((old_peer_state
== PEER_INVALID
) ||
2438 (new_peer_state
== PEER_INVALID
)) {
2439 /* something bad happend , print error message */
2440 return BGP_ERR_GR_INVALID_CMD
;
2443 bgp_gr_global_mode
= bgp_global_gr_mode_get(peer
->bgp
);
2445 if ((old_peer_state
== PEER_GLOBAL_INHERIT
) &&
2446 (new_peer_state
!= PEER_GLOBAL_INHERIT
)) {
2448 /* fetch the Mode running in the Global state machine
2449 *from the bgp structure into a variable called
2453 /* Here we are checking if the
2454 *1. peer_new_state == global_mode == helper_mode
2455 *2. peer_new_state == global_mode == GR_mode
2456 *3. peer_new_state == global_mode == disabled_mode
2459 BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer
);
2461 if (new_peer_state
== bgp_gr_global_mode
) {
2462 /*This is incremental updates i.e no tear down
2463 *of the existing session
2464 *as the peer is already working in the same mode.
2466 /* debug Trace msg */
2467 ret
= BGP_GR_SUCCESS
;
2469 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2471 "BGP_GR:: Peer state changed from :%d =>",
2474 bgp_peer_move_to_gr_mode(peer
, new_peer_state
);
2476 ret
= BGP_GR_SUCCESS
;
2479 /* In the case below peer is going into Global inherit mode i.e.
2480 * the peer would work as the mode configured at the global level
2482 else if ((new_peer_state
== PEER_GLOBAL_INHERIT
) &&
2483 (old_peer_state
!= PEER_GLOBAL_INHERIT
)) {
2484 /* Here in this case it would be destructive
2485 * in all the cases except one case when,
2486 * Global GR is configured Disabled
2487 * and present_peer_state is not disable
2490 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer
);
2492 if (old_peer_state
== bgp_gr_global_mode
) {
2494 /* This is incremental updates
2495 *i.e no tear down of the existing session
2496 *as the peer is already working in the same mode.
2498 ret
= BGP_GR_SUCCESS
;
2500 /* Destructive always */
2501 /* Tear down the old session
2502 * and send the new capability
2503 * as per the bgp_gr_global_mode
2506 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2507 zlog_debug("BGP_GR:: Peer state changed from :%d ==>",
2510 bgp_peer_move_to_gr_mode(peer
, bgp_gr_global_mode
);
2512 ret
= BGP_GR_SUCCESS
;
2516 *This else case, it include all the cases except -->
2517 *(new_peer_state != Peer_Global) &&
2518 *( old_peer_state != Peer_Global )
2520 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2521 zlog_debug("BGP_GR:: Peer state changed from :%d ===>",
2524 bgp_peer_move_to_gr_mode(peer
, new_peer_state
);
2526 ret
= BGP_GR_SUCCESS
;
2532 inline void bgp_peer_move_to_gr_mode(struct peer
*peer
, int new_state
)
2535 int bgp_global_gr_mode
= bgp_global_gr_mode_get(peer
->bgp
);
2537 switch (new_state
) {
2540 BGP_PEER_GR_HELPER_ENABLE(peer
);
2544 BGP_PEER_GR_ENABLE(peer
);
2548 BGP_PEER_GR_DISABLE(peer
);
2551 case PEER_GLOBAL_INHERIT
:
2552 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer
);
2554 if (bgp_global_gr_mode
== GLOBAL_HELPER
) {
2555 BGP_PEER_GR_HELPER_ENABLE(peer
);
2556 } else if (bgp_global_gr_mode
== GLOBAL_GR
) {
2557 BGP_PEER_GR_ENABLE(peer
);
2558 } else if (bgp_global_gr_mode
== GLOBAL_DISABLE
) {
2559 BGP_PEER_GR_DISABLE(peer
);
2562 "BGP_GR:: Default switch inherit mode ::: SOMETHING IS WORONG !!!");
2566 zlog_debug("BGP_GR:: Default switch mode ::: SOMETHING IS WORONG !!!");
2569 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2570 zlog_debug("BGP_GR:: Peer state changed --to--> : %d : !",
2574 void bgp_peer_gr_flags_update(struct peer
*peer
)
2576 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2578 "BGP_GR:: %s called !",
2580 if (CHECK_FLAG(peer
->peer_gr_new_status_flag
,
2581 PEER_GRACEFUL_RESTART_NEW_STATE_HELPER
))
2582 SET_FLAG(peer
->flags
,
2583 PEER_FLAG_GRACEFUL_RESTART_HELPER
);
2585 UNSET_FLAG(peer
->flags
,
2586 PEER_FLAG_GRACEFUL_RESTART_HELPER
);
2587 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2589 "BGP_GR:: Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !",
2591 (CHECK_FLAG(peer
->flags
,
2592 PEER_FLAG_GRACEFUL_RESTART_HELPER
) ?
2594 if (CHECK_FLAG(peer
->peer_gr_new_status_flag
,
2595 PEER_GRACEFUL_RESTART_NEW_STATE_RESTART
))
2596 SET_FLAG(peer
->flags
,
2597 PEER_FLAG_GRACEFUL_RESTART
);
2599 UNSET_FLAG(peer
->flags
,
2600 PEER_FLAG_GRACEFUL_RESTART
);
2601 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2603 "BGP_GR:: Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !",
2605 (CHECK_FLAG(peer
->flags
,
2606 PEER_FLAG_GRACEFUL_RESTART
) ?
2608 if (CHECK_FLAG(peer
->peer_gr_new_status_flag
,
2609 PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT
))
2610 SET_FLAG(peer
->flags
,
2611 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
);
2613 UNSET_FLAG(peer
->flags
,
2614 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
);
2615 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
2617 "BGP_GR:: Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !",
2619 (CHECK_FLAG(peer
->flags
,
2620 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
) ?
2623 if (!CHECK_FLAG(peer
->flags
,
2624 PEER_FLAG_GRACEFUL_RESTART
) &&
2625 !CHECK_FLAG(peer
->flags
,
2626 PEER_FLAG_GRACEFUL_RESTART_HELPER
)){
2628 "BGP_GR:: Peer %s UNSET PEER_STATUS_NSF_MODE!",
2631 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2633 if (CHECK_FLAG(peer
->sflags
,
2634 PEER_STATUS_NSF_WAIT
)) {
2636 peer_nsf_stop(peer
);
2638 "BGP_GR:: Peer %s UNSET PEER_STATUS_NSF_WAIT!",