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
18 along with GNU Zebra; see the file COPYING. If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 #include "sockunion.h"
33 #include "workqueue.h"
36 #include "bgpd/bgpd.h"
37 #include "bgpd/bgp_attr.h"
38 #include "bgpd/bgp_debug.h"
39 #include "bgpd/bgp_fsm.h"
40 #include "bgpd/bgp_packet.h"
41 #include "bgpd/bgp_network.h"
42 #include "bgpd/bgp_route.h"
43 #include "bgpd/bgp_dump.h"
44 #include "bgpd/bgp_open.h"
45 #include "bgpd/bgp_advertise.h"
47 #include "bgpd/bgp_snmp.h"
48 #endif /* HAVE_SNMP */
49 #include "bgpd/bgp_updgrp.h"
51 /* BGP FSM (finite state machine) has three types of functions. Type
52 one is thread functions. Type two is event functions. Type three
53 is FSM functions. Timer functions are set by bgp_timer_set
56 /* BGP event function. */
57 int bgp_event (struct thread
*);
59 /* BGP thread functions. */
60 static int bgp_start_timer (struct thread
*);
61 static int bgp_connect_timer (struct thread
*);
62 static int bgp_holdtime_timer (struct thread
*);
63 static int bgp_keepalive_timer (struct thread
*);
65 /* BGP FSM functions. */
66 static int bgp_start (struct peer
*);
69 peer_xfer_stats (struct peer
*peer_dst
, struct peer
*peer_src
)
71 /* Copy stats over. These are only the pre-established state stats */
72 peer_dst
->open_in
+= peer_src
->open_in
;
73 peer_dst
->open_out
+= peer_src
->open_out
;
74 peer_dst
->keepalive_in
+= peer_src
->keepalive_in
;
75 peer_dst
->keepalive_out
+= peer_src
->keepalive_out
;
76 peer_dst
->notify_in
+= peer_src
->notify_in
;
77 peer_dst
->notify_out
+= peer_src
->notify_out
;
78 peer_dst
->dynamic_cap_in
+= peer_src
->dynamic_cap_in
;
79 peer_dst
->dynamic_cap_out
+= peer_src
->dynamic_cap_out
;
83 peer_xfer_conn(struct peer
*from_peer
)
91 assert(from_peer
!= NULL
);
93 peer
= from_peer
->doppelganger
;
95 if (!peer
|| !CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
98 if (bgp_debug_neighbor_events(peer
))
99 zlog_debug ("peer transfer (%s -> %s)", from_peer
->host
, peer
->host
);
101 BGP_WRITE_OFF(peer
->t_write
);
102 BGP_READ_OFF(peer
->t_read
);
103 BGP_WRITE_OFF(from_peer
->t_write
);
104 BGP_READ_OFF(from_peer
->t_read
);
106 BGP_TIMER_OFF(peer
->t_routeadv
);
107 BGP_TIMER_OFF(from_peer
->t_routeadv
);
110 peer
->fd
= from_peer
->fd
;
112 stream_reset(peer
->ibuf
);
113 stream_fifo_clean(peer
->obuf
);
114 stream_fifo_clean(from_peer
->obuf
);
116 peer
->v_holdtime
= from_peer
->v_holdtime
;
117 peer
->v_keepalive
= from_peer
->v_keepalive
;
118 peer
->v_asorig
= from_peer
->v_asorig
;
119 peer
->routeadv
= from_peer
->routeadv
;
120 peer
->v_routeadv
= from_peer
->v_routeadv
;
121 peer
->v_gr_restart
= from_peer
->v_gr_restart
;
122 peer
->cap
= from_peer
->cap
;
123 status
= peer
->status
;
124 pstatus
= peer
->ostatus
;
125 peer
->status
= from_peer
->status
;
126 peer
->ostatus
= from_peer
->ostatus
;
127 from_peer
->status
= status
;
128 from_peer
->ostatus
= pstatus
;
129 peer
->remote_id
= from_peer
->remote_id
;
131 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
132 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
134 peer
->af_flags
[afi
][safi
] = from_peer
->af_flags
[afi
][safi
];
135 peer
->af_sflags
[afi
][safi
] = from_peer
->af_sflags
[afi
][safi
];
136 peer
->af_cap
[afi
][safi
] = from_peer
->af_cap
[afi
][safi
];
137 peer
->afc_nego
[afi
][safi
] = from_peer
->afc_nego
[afi
][safi
];
138 peer
->afc_adv
[afi
][safi
] = from_peer
->afc_adv
[afi
][safi
];
139 peer
->afc_recv
[afi
][safi
] = from_peer
->afc_recv
[afi
][safi
];
142 if (bgp_getsockname(peer
) < 0)
144 zlog_err ("%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
145 (CHECK_FLAG (peer
->sflags
, PEER_STATUS_ACCEPT_PEER
) ? "accept" : ""),
146 peer
->host
, peer
->fd
, from_peer
->fd
);
151 if (from_peer
->status
> Active
)
153 if (bgp_getsockname(from_peer
) < 0)
155 zlog_err ("%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
156 (CHECK_FLAG (from_peer
->sflags
, PEER_STATUS_ACCEPT_PEER
) ? "accept" : ""),
157 from_peer
->host
, from_peer
->fd
, peer
->fd
);
163 BGP_READ_ON(peer
->t_read
, bgp_read
, peer
->fd
);
164 BGP_WRITE_ON(peer
->t_write
, bgp_write
, peer
->fd
);
167 peer_xfer_stats(peer
, from_peer
);
172 /* Check if suppress start/restart of sessions to peer. */
173 #define BGP_PEER_START_SUPPRESSED(P) \
174 (CHECK_FLAG ((P)->flags, PEER_FLAG_SHUTDOWN) \
175 || CHECK_FLAG ((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW))
177 /* Hook function called after bgp event is occered. And vty's
178 neighbor command invoke this function after making neighbor
181 bgp_timer_set (struct peer
*peer
)
183 switch (peer
->status
)
186 /* First entry point of peer's finite state machine. In Idle
187 status start timer is on unless peer is shutdown or peer is
188 inactive. All other timer must be turned off */
189 if (BGP_PEER_START_SUPPRESSED (peer
) || ! peer_active (peer
))
191 BGP_TIMER_OFF (peer
->t_start
);
195 BGP_TIMER_ON (peer
->t_start
, bgp_start_timer
,
198 BGP_TIMER_OFF (peer
->t_connect
);
199 BGP_TIMER_OFF (peer
->t_holdtime
);
200 BGP_TIMER_OFF (peer
->t_keepalive
);
201 BGP_TIMER_OFF (peer
->t_asorig
);
202 BGP_TIMER_OFF (peer
->t_routeadv
);
206 /* After start timer is expired, the peer moves to Connect
207 status. Make sure start timer is off and connect timer is
209 BGP_TIMER_OFF (peer
->t_start
);
210 BGP_TIMER_ON (peer
->t_connect
, bgp_connect_timer
, peer
->v_connect
);
211 BGP_TIMER_OFF (peer
->t_holdtime
);
212 BGP_TIMER_OFF (peer
->t_keepalive
);
213 BGP_TIMER_OFF (peer
->t_asorig
);
214 BGP_TIMER_OFF (peer
->t_routeadv
);
218 /* Active is waiting connection from remote peer. And if
219 connect timer is expired, change status to Connect. */
220 BGP_TIMER_OFF (peer
->t_start
);
221 /* If peer is passive mode, do not set connect timer. */
222 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_PASSIVE
)
223 || CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
))
225 BGP_TIMER_OFF (peer
->t_connect
);
229 BGP_TIMER_ON (peer
->t_connect
, bgp_connect_timer
, peer
->v_connect
);
231 BGP_TIMER_OFF (peer
->t_holdtime
);
232 BGP_TIMER_OFF (peer
->t_keepalive
);
233 BGP_TIMER_OFF (peer
->t_asorig
);
234 BGP_TIMER_OFF (peer
->t_routeadv
);
238 /* OpenSent status. */
239 BGP_TIMER_OFF (peer
->t_start
);
240 BGP_TIMER_OFF (peer
->t_connect
);
241 if (peer
->v_holdtime
!= 0)
243 BGP_TIMER_ON (peer
->t_holdtime
, bgp_holdtime_timer
,
248 BGP_TIMER_OFF (peer
->t_holdtime
);
250 BGP_TIMER_OFF (peer
->t_keepalive
);
251 BGP_TIMER_OFF (peer
->t_asorig
);
252 BGP_TIMER_OFF (peer
->t_routeadv
);
256 /* OpenConfirm status. */
257 BGP_TIMER_OFF (peer
->t_start
);
258 BGP_TIMER_OFF (peer
->t_connect
);
260 /* If the negotiated Hold Time value is zero, then the Hold Time
261 timer and KeepAlive timers are not started. */
262 if (peer
->v_holdtime
== 0)
264 BGP_TIMER_OFF (peer
->t_holdtime
);
265 BGP_TIMER_OFF (peer
->t_keepalive
);
269 BGP_TIMER_ON (peer
->t_holdtime
, bgp_holdtime_timer
,
271 BGP_TIMER_ON (peer
->t_keepalive
, bgp_keepalive_timer
,
274 BGP_TIMER_OFF (peer
->t_asorig
);
275 BGP_TIMER_OFF (peer
->t_routeadv
);
279 /* In Established status start and connect timer is turned
281 BGP_TIMER_OFF (peer
->t_start
);
282 BGP_TIMER_OFF (peer
->t_connect
);
284 /* Same as OpenConfirm, if holdtime is zero then both holdtime
285 and keepalive must be turned off. */
286 if (peer
->v_holdtime
== 0)
288 BGP_TIMER_OFF (peer
->t_holdtime
);
289 BGP_TIMER_OFF (peer
->t_keepalive
);
293 BGP_TIMER_ON (peer
->t_holdtime
, bgp_holdtime_timer
,
295 BGP_TIMER_ON (peer
->t_keepalive
, bgp_keepalive_timer
,
298 BGP_TIMER_OFF (peer
->t_asorig
);
301 BGP_TIMER_OFF (peer
->t_gr_restart
);
302 BGP_TIMER_OFF (peer
->t_gr_stale
);
303 BGP_TIMER_OFF (peer
->t_pmax_restart
);
305 BGP_TIMER_OFF (peer
->t_start
);
306 BGP_TIMER_OFF (peer
->t_connect
);
307 BGP_TIMER_OFF (peer
->t_holdtime
);
308 BGP_TIMER_OFF (peer
->t_keepalive
);
309 BGP_TIMER_OFF (peer
->t_asorig
);
310 BGP_TIMER_OFF (peer
->t_routeadv
);
315 /* BGP start timer. This function set BGP_Start event to thread value
316 and process event. */
318 bgp_start_timer (struct thread
*thread
)
322 peer
= THREAD_ARG (thread
);
323 peer
->t_start
= NULL
;
325 if (bgp_debug_neighbor_events(peer
))
326 zlog_debug("%s [FSM] Timer (start timer expire).", peer
->host
);
328 THREAD_VAL (thread
) = BGP_Start
;
329 bgp_event (thread
); /* bgp_event unlocks peer */
334 /* BGP connect retry timer. */
336 bgp_connect_timer (struct thread
*thread
)
341 peer
= THREAD_ARG (thread
);
342 peer
->t_connect
= NULL
;
344 if (bgp_debug_neighbor_events(peer
))
345 zlog_debug("%s [FSM] Timer (connect timer expire)", peer
->host
);
347 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
))
354 THREAD_VAL (thread
) = ConnectRetry_timer_expired
;
355 bgp_event (thread
); /* bgp_event unlocks peer */
362 /* BGP holdtime timer. */
364 bgp_holdtime_timer (struct thread
*thread
)
368 peer
= THREAD_ARG (thread
);
369 peer
->t_holdtime
= NULL
;
371 if (bgp_debug_neighbor_events(peer
))
372 zlog_debug ("%s [FSM] Timer (holdtime timer expire)", peer
->host
);
374 THREAD_VAL (thread
) = Hold_Timer_expired
;
375 bgp_event (thread
); /* bgp_event unlocks peer */
380 /* BGP keepalive fire ! */
382 bgp_keepalive_timer (struct thread
*thread
)
386 peer
= THREAD_ARG (thread
);
387 peer
->t_keepalive
= NULL
;
389 if (bgp_debug_neighbor_events(peer
))
390 zlog_debug ("%s [FSM] Timer (keepalive timer expire)", peer
->host
);
392 THREAD_VAL (thread
) = KeepAlive_timer_expired
;
393 bgp_event (thread
); /* bgp_event unlocks peer */
399 bgp_routeq_empty (struct peer
*peer
)
404 PEERAF_FOREACH(peer
, paf
, af
)
406 if (!PAF_SUBGRP(paf
))
408 if (!advertise_list_is_empty(PAF_SUBGRP(paf
)))
415 bgp_routeadv_timer (struct thread
*thread
)
419 peer
= THREAD_ARG (thread
);
420 peer
->t_routeadv
= NULL
;
422 if (bgp_debug_neighbor_events(peer
))
423 zlog_debug ("%s [FSM] Timer (routeadv timer expire)", peer
->host
);
425 peer
->synctime
= bgp_clock ();
427 BGP_WRITE_ON (peer
->t_write
, bgp_write
, peer
->fd
);
429 /* MRAI timer will be started again when FIFO is built, no need to
435 /* BGP Peer Down Cause */
436 const char *peer_down_str
[] =
442 "Cluster ID changed",
443 "Confederation identifier changed",
444 "Confederation peer changed",
445 "RR client config change",
446 "RS client config change",
447 "Update source change",
448 "Address family activated",
451 "BGP Notification received",
452 "BGP Notification send",
453 "Peer closed the session",
455 "Peer-group add member",
456 "Peer-group delete member",
457 "Capability changed",
458 "Passive config change",
459 "Multihop config change",
460 "NSF peer closed the session"
464 bgp_graceful_restart_timer_expire (struct thread
*thread
)
470 peer
= THREAD_ARG (thread
);
471 peer
->t_gr_restart
= NULL
;
473 /* NSF delete stale route */
474 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
475 for (safi
= SAFI_UNICAST
; safi
< SAFI_RESERVED_3
; safi
++)
476 if (peer
->nsf
[afi
][safi
])
477 bgp_clear_stale_route (peer
, afi
, safi
);
479 UNSET_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
);
480 BGP_TIMER_OFF (peer
->t_gr_stale
);
482 if (bgp_debug_neighbor_events(peer
))
484 zlog_debug ("%s graceful restart timer expired", peer
->host
);
485 zlog_debug ("%s graceful restart stalepath timer stopped", peer
->host
);
488 bgp_timer_set (peer
);
494 bgp_graceful_stale_timer_expire (struct thread
*thread
)
500 peer
= THREAD_ARG (thread
);
501 peer
->t_gr_stale
= NULL
;
503 if (bgp_debug_neighbor_events(peer
))
504 zlog_debug ("%s graceful restart stalepath timer expired", peer
->host
);
506 /* NSF delete stale route */
507 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
508 for (safi
= SAFI_UNICAST
; safi
< SAFI_RESERVED_3
; safi
++)
509 if (peer
->nsf
[afi
][safi
])
510 bgp_clear_stale_route (peer
, afi
, safi
);
516 bgp_update_delay_applicable (struct bgp
*bgp
)
518 /* update_delay_over flag should be reset (set to 0) for any new
519 applicability of the update-delay during BGP process lifetime.
520 And it should be set after an occurence of the update-delay is over)*/
521 if (!bgp
->update_delay_over
)
528 bgp_update_delay_active (struct bgp
*bgp
)
530 if (bgp
->t_update_delay
)
537 bgp_update_delay_configured (struct bgp
*bgp
)
539 if (bgp
->v_update_delay
)
545 /* Do the post-processing needed when bgp comes out of the read-only mode
546 on ending the update delay. */
548 bgp_update_delay_end (struct bgp
*bgp
)
550 THREAD_TIMER_OFF (bgp
->t_update_delay
);
551 THREAD_TIMER_OFF (bgp
->t_establish_wait
);
553 /* Reset update-delay related state */
554 bgp
->update_delay_over
= 1;
555 bgp
->established
= 0;
556 bgp
->restarted_peers
= 0;
557 bgp
->implicit_eors
= 0;
558 bgp
->explicit_eors
= 0;
560 quagga_timestamp(3, bgp
->update_delay_end_time
,
561 sizeof(bgp
->update_delay_end_time
));
564 * Add an end-of-initial-update marker to the main process queues so that
565 * the route advertisement timer for the peers can be started. Also set
566 * the zebra and peer update hold flags. These flags are used to achieve
567 * three stages in the update-delay post processing:
568 * 1. Finish best-path selection for all the prefixes held on the queues.
569 * (routes in BGP are updated, and peers sync queues are populated too)
570 * 2. As the eoiu mark is reached in the bgp process routine, ship all the
571 * routes to zebra. With that zebra should see updates from BGP close
573 * 3. Unblock the peer update writes. With that peer update packing with
574 * the prefixes should be at its maximum.
576 bgp_add_eoiu_mark(bgp
, BGP_TABLE_MAIN
);
577 bgp_add_eoiu_mark(bgp
, BGP_TABLE_RSCLIENT
);
578 bgp
->main_zebra_update_hold
= 1;
579 bgp
->main_peers_update_hold
= 1;
580 bgp
->rsclient_peers_update_hold
= 1;
582 /* Resume the queue processing. This should trigger the event that would take
583 care of processing any work that was queued during the read-only mode. */
584 work_queue_unplug(bm
->process_main_queue
);
585 work_queue_unplug(bm
->process_rsclient_queue
);
592 bgp_start_routeadv (struct bgp
*bgp
)
594 struct listnode
*node
, *nnode
;
597 zlog_info("bgp_start_routeadv(), update hold status - main: %d, rsclient: %d",
598 bgp
->main_peers_update_hold
, bgp
->rsclient_peers_update_hold
);
600 if (bgp
->main_peers_update_hold
|| bgp
->rsclient_peers_update_hold
)
603 quagga_timestamp(3, bgp
->update_delay_peers_resume_time
,
604 sizeof(bgp
->update_delay_peers_resume_time
));
606 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
608 if (peer
->status
!= Established
)
610 BGP_TIMER_OFF(peer
->t_routeadv
);
611 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, 0);
619 bgp_adjust_routeadv (struct peer
*peer
)
621 time_t nowtime
= bgp_clock();
623 unsigned long remain
;
625 /* Bypass checks for special case of MRAI being 0 */
626 if (peer
->v_routeadv
== 0)
628 /* Stop existing timer, just in case it is running for a different
629 * duration and schedule write thread immediately.
631 if (peer
->t_routeadv
)
632 BGP_TIMER_OFF(peer
->t_routeadv
);
634 peer
->synctime
= bgp_clock ();
635 BGP_WRITE_ON (peer
->t_write
, bgp_write
, peer
->fd
);
642 * If the last update was written more than MRAI back, expire the timer
643 * instantly so that we can send the update out sooner.
645 * <------- MRAI --------->
646 * |-----------------|-----------------------|
647 * <------------- m ------------>
656 diff
= difftime(nowtime
, peer
->last_write
);
657 if (diff
> (double) peer
->v_routeadv
)
659 BGP_TIMER_OFF(peer
->t_routeadv
);
660 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, 0);
666 * - Find when to expire the MRAI timer.
667 * If MRAI timer is not active, assume we can start it now.
669 * <------- MRAI --------->
670 * |------------|-----------------------|
671 * <-------- m ----------><----- r ----->
680 if (peer
->t_routeadv
)
681 remain
= thread_timer_remain_second(peer
->t_routeadv
);
683 remain
= peer
->v_routeadv
;
684 diff
= peer
->v_routeadv
- diff
;
685 if (diff
<= (double) remain
)
687 BGP_TIMER_OFF(peer
->t_routeadv
);
688 BGP_TIMER_ON(peer
->t_routeadv
, bgp_routeadv_timer
, diff
);
693 bgp_maxmed_onstartup_applicable (struct bgp
*bgp
)
695 if (!bgp
->maxmed_onstartup_over
)
702 bgp_maxmed_onstartup_configured (struct bgp
*bgp
)
704 if (bgp
->v_maxmed_onstartup
!= BGP_MAXMED_ONSTARTUP_UNCONFIGURED
)
711 bgp_maxmed_onstartup_active (struct bgp
*bgp
)
713 if (bgp
->t_maxmed_onstartup
)
720 bgp_maxmed_update (struct bgp
*bgp
)
722 u_char maxmed_active
;
723 u_int32_t maxmed_value
;
725 if (bgp
->v_maxmed_admin
)
728 maxmed_value
= bgp
->maxmed_admin_value
;
730 else if (bgp
->t_maxmed_onstartup
)
733 maxmed_value
= bgp
->maxmed_onstartup_value
;
738 maxmed_value
= BGP_MAXMED_VALUE_DEFAULT
;
741 if (bgp
->maxmed_active
!= maxmed_active
||
742 bgp
->maxmed_value
!= maxmed_value
)
744 bgp
->maxmed_active
= maxmed_active
;
745 bgp
->maxmed_value
= maxmed_value
;
747 update_group_announce(bgp
);
751 /* The maxmed onstartup timer expiry callback. */
753 bgp_maxmed_onstartup_timer (struct thread
*thread
)
757 zlog_info ("Max med on startup ended - timer expired.");
759 bgp
= THREAD_ARG (thread
);
760 THREAD_TIMER_OFF (bgp
->t_maxmed_onstartup
);
761 bgp
->maxmed_onstartup_over
= 1;
763 bgp_maxmed_update(bgp
);
769 bgp_maxmed_onstartup_begin (struct bgp
*bgp
)
771 /* Applicable only once in the process lifetime on the startup */
772 if (bgp
->maxmed_onstartup_over
)
775 zlog_info ("Begin maxmed onstartup mode - timer %d seconds",
776 bgp
->v_maxmed_onstartup
);
778 THREAD_TIMER_ON (master
, bgp
->t_maxmed_onstartup
,
779 bgp_maxmed_onstartup_timer
,
780 bgp
, bgp
->v_maxmed_onstartup
);
782 if (!bgp
->v_maxmed_admin
)
784 bgp
->maxmed_active
= 1;
785 bgp
->maxmed_value
= bgp
->maxmed_onstartup_value
;
788 /* Route announce to all peers should happen after this in bgp_establish() */
792 bgp_maxmed_onstartup_process_status_change(struct peer
*peer
)
794 if (peer
->status
== Established
&& !peer
->bgp
->established
)
796 bgp_maxmed_onstartup_begin(peer
->bgp
);
800 /* The update delay timer expiry callback. */
802 bgp_update_delay_timer (struct thread
*thread
)
806 zlog_info ("Update delay ended - timer expired.");
808 bgp
= THREAD_ARG (thread
);
809 THREAD_TIMER_OFF (bgp
->t_update_delay
);
810 bgp_update_delay_end(bgp
);
815 /* The establish wait timer expiry callback. */
817 bgp_establish_wait_timer (struct thread
*thread
)
821 zlog_info ("Establish wait - timer expired.");
823 bgp
= THREAD_ARG (thread
);
824 THREAD_TIMER_OFF (bgp
->t_establish_wait
);
825 bgp_check_update_delay(bgp
);
830 /* Steps to begin the update delay:
831 - initialize queues if needed
832 - stop the queue processing
835 bgp_update_delay_begin (struct bgp
*bgp
)
837 struct listnode
*node
, *nnode
;
840 if ((bm
->process_main_queue
== NULL
) ||
841 (bm
->process_rsclient_queue
== NULL
))
842 bgp_process_queue_init();
844 /* Stop the processing of queued work. Enqueue shall continue */
845 work_queue_plug(bm
->process_main_queue
);
846 work_queue_plug(bm
->process_rsclient_queue
);
848 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
849 peer
->update_delay_over
= 0;
851 /* Start the update-delay timer */
852 THREAD_TIMER_ON (master
, bgp
->t_update_delay
, bgp_update_delay_timer
,
853 bgp
, bgp
->v_update_delay
);
855 if (bgp
->v_establish_wait
!= bgp
->v_update_delay
)
856 THREAD_TIMER_ON (master
, bgp
->t_establish_wait
, bgp_establish_wait_timer
,
857 bgp
, bgp
->v_establish_wait
);
859 quagga_timestamp(3, bgp
->update_delay_begin_time
,
860 sizeof(bgp
->update_delay_begin_time
));
864 bgp_update_delay_process_status_change(struct peer
*peer
)
866 if (peer
->status
== Established
)
868 if (!peer
->bgp
->established
++)
870 bgp_update_delay_begin(peer
->bgp
);
871 zlog_info ("Begin read-only mode - update-delay timer %d seconds",
872 peer
->bgp
->v_update_delay
);
874 if (CHECK_FLAG (peer
->cap
, PEER_CAP_RESTART_BIT_RCV
))
875 bgp_update_restarted_peers(peer
);
877 if (peer
->ostatus
== Established
&& bgp_update_delay_active(peer
->bgp
))
879 /* Adjust the update-delay state to account for this flap.
880 NOTE: Intentionally skipping adjusting implicit_eors or explicit_eors
881 counters. Extra sanity check in bgp_check_update_delay() should
882 be enough to take care of any additive discrepancy in bgp eor
884 peer
->bgp
->established
--;
885 peer
->update_delay_over
= 0;
889 /* Called after event occured, this function change status and reset
890 read/write and timer thread. */
892 bgp_fsm_change_status (struct peer
*peer
, int status
)
895 bgp_dump_state (peer
, peer
->status
, status
);
897 /* Transition into Clearing or Deleted must /always/ clear all routes..
898 * (and must do so before actually changing into Deleted..
900 if (status
>= Clearing
)
901 bgp_clear_route_all (peer
);
903 /* Preserve old status and change into new status. */
904 peer
->ostatus
= peer
->status
;
905 peer
->status
= status
;
907 if (status
== Established
)
908 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
910 /* If max-med processing is applicable, do the necessary. */
911 if (status
== Established
)
913 if (bgp_maxmed_onstartup_configured(peer
->bgp
) &&
914 bgp_maxmed_onstartup_applicable(peer
->bgp
))
915 bgp_maxmed_onstartup_process_status_change(peer
);
917 peer
->bgp
->maxmed_onstartup_over
= 1;
920 /* If update-delay processing is applicable, do the necessary. */
921 if (bgp_update_delay_configured(peer
->bgp
) &&
922 bgp_update_delay_applicable(peer
->bgp
))
923 bgp_update_delay_process_status_change(peer
);
925 if (bgp_debug_neighbor_events(peer
))
926 zlog_debug ("%s went from %s to %s",
928 LOOKUP (bgp_status_msg
, peer
->ostatus
),
929 LOOKUP (bgp_status_msg
, peer
->status
));
932 /* Flush the event queue and ensure the peer is shut down */
934 bgp_clearing_completed (struct peer
*peer
)
936 int rc
= bgp_stop(peer
);
939 BGP_EVENT_FLUSH (peer
);
944 /* Administrative BGP peer stop event. */
945 /* May be called multiple times for the same peer */
947 bgp_stop (struct peer
*peer
)
951 char orf_name
[BUFSIZ
];
954 /* Can't do this in Clearing; events are used for state transitions */
955 if (peer
->status
!= Clearing
)
957 /* Delete all existing events of the peer */
958 BGP_EVENT_FLUSH (peer
);
961 /* Increment Dropped count. */
962 if (peer
->status
== Established
)
966 /* bgp log-neighbor-changes of neighbor Down */
967 if (bgp_flag_check (peer
->bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
))
968 zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer
->host
,
969 peer_down_str
[(int) peer
->last_reset
]);
971 /* graceful restart */
972 if (peer
->t_gr_stale
)
974 BGP_TIMER_OFF (peer
->t_gr_stale
);
975 if (bgp_debug_neighbor_events(peer
))
976 zlog_debug ("%s graceful restart stalepath timer stopped", peer
->host
);
978 if (CHECK_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
))
980 if (bgp_debug_neighbor_events(peer
))
982 zlog_debug ("%s graceful restart timer started for %d sec",
983 peer
->host
, peer
->v_gr_restart
);
984 zlog_debug ("%s graceful restart stalepath timer started for %d sec",
985 peer
->host
, peer
->bgp
->stalepath_time
);
987 BGP_TIMER_ON (peer
->t_gr_restart
, bgp_graceful_restart_timer_expire
,
989 BGP_TIMER_ON (peer
->t_gr_stale
, bgp_graceful_stale_timer_expire
,
990 peer
->bgp
->stalepath_time
);
994 UNSET_FLAG (peer
->sflags
, PEER_STATUS_NSF_MODE
);
996 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
997 for (safi
= SAFI_UNICAST
; safi
< SAFI_RESERVED_3
; safi
++)
998 peer
->nsf
[afi
][safi
] = 0;
1001 /* set last reset time */
1002 peer
->resettime
= peer
->uptime
= bgp_clock ();
1004 if (BGP_DEBUG (update_groups
, UPDATE_GROUPS
))
1005 zlog_debug ("%s remove from all update group", peer
->host
);
1006 update_group_remove_peer_afs(peer
);
1009 bgpTrapBackwardTransition (peer
);
1010 #endif /* HAVE_SNMP */
1012 /* Reset peer synctime */
1016 /* Stop read and write threads when exists. */
1017 BGP_READ_OFF (peer
->t_read
);
1018 BGP_WRITE_OFF (peer
->t_write
);
1020 /* Stop all timers. */
1021 BGP_TIMER_OFF (peer
->t_start
);
1022 BGP_TIMER_OFF (peer
->t_connect
);
1023 BGP_TIMER_OFF (peer
->t_holdtime
);
1024 BGP_TIMER_OFF (peer
->t_keepalive
);
1025 BGP_TIMER_OFF (peer
->t_asorig
);
1026 BGP_TIMER_OFF (peer
->t_routeadv
);
1029 peer
->packet_size
= 0;
1031 /* Clear input and output buffer. */
1033 stream_reset (peer
->ibuf
);
1035 stream_reset (peer
->work
);
1037 stream_fifo_clean (peer
->obuf
);
1039 /* Close of file descriptor. */
1046 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1047 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1049 /* Reset all negotiated variables */
1050 peer
->afc_nego
[afi
][safi
] = 0;
1051 peer
->afc_adv
[afi
][safi
] = 0;
1052 peer
->afc_recv
[afi
][safi
] = 0;
1054 /* peer address family capability flags*/
1055 peer
->af_cap
[afi
][safi
] = 0;
1057 /* peer address family status flags*/
1058 peer
->af_sflags
[afi
][safi
] = 0;
1060 /* Received ORF prefix-filter */
1061 peer
->orf_plist
[afi
][safi
] = NULL
;
1063 if ((peer
->status
== OpenConfirm
) || (peer
->status
== Established
)) {
1064 /* ORF received prefix-filter pnt */
1065 sprintf (orf_name
, "%s.%d.%d", peer
->host
, afi
, safi
);
1066 prefix_bgp_orf_remove_all (orf_name
);
1070 /* Reset keepalive and holdtime */
1071 if (CHECK_FLAG (peer
->config
, PEER_CONFIG_TIMER
))
1073 peer
->v_keepalive
= peer
->keepalive
;
1074 peer
->v_holdtime
= peer
->holdtime
;
1078 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
1079 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
1082 peer
->update_time
= 0;
1084 /* Until we are sure that there is no problem about prefix count
1085 this should be commented out.*/
1087 /* Reset prefix count */
1088 peer
->pcount
[AFI_IP
][SAFI_UNICAST
] = 0;
1089 peer
->pcount
[AFI_IP
][SAFI_MULTICAST
] = 0;
1090 peer
->pcount
[AFI_IP
][SAFI_MPLS_VPN
] = 0;
1091 peer
->pcount
[AFI_IP6
][SAFI_UNICAST
] = 0;
1092 peer
->pcount
[AFI_IP6
][SAFI_MULTICAST
] = 0;
1095 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
) &&
1096 !(CHECK_FLAG(peer
->flags
, PEER_FLAG_DELETE
)))
1103 bgp_peer_conf_if_to_su_update(peer
);
1109 /* BGP peer is stoped by the error. */
1111 bgp_stop_with_error (struct peer
*peer
)
1113 /* Double start timer. */
1116 /* Overflow check. */
1117 if (peer
->v_start
>= (60 * 2))
1118 peer
->v_start
= (60 * 2);
1120 return(bgp_stop (peer
));
1124 /* something went wrong, send notify and tear down */
1126 bgp_stop_with_notify (struct peer
*peer
, u_char code
, u_char sub_code
)
1128 /* Send notify to remote peer */
1129 bgp_notify_send (peer
, code
, sub_code
);
1131 /* Clear start timer value to default. */
1132 peer
->v_start
= BGP_INIT_START_TIMER
;
1134 return(bgp_stop(peer
));
1138 /* TCP connection open. Next we send open message to remote peer. And
1139 add read thread for reading open message. */
1141 bgp_connect_success (struct peer
*peer
)
1147 zlog_err ("bgp_connect_success peer's fd is negative value %d",
1153 if (bgp_getsockname (peer
) < 0)
1155 zlog_err ("%s: bgp_getsockname(): failed for peer %s", __FUNCTION__
,
1157 bgp_notify_send(peer
, BGP_NOTIFY_FSM_ERR
, 0); /* internal error */
1161 BGP_READ_ON (peer
->t_read
, bgp_read
, peer
->fd
);
1163 if (bgp_debug_neighbor_events(peer
))
1165 char buf1
[SU_ADDRSTRLEN
];
1167 if (! CHECK_FLAG (peer
->sflags
, PEER_STATUS_ACCEPT_PEER
))
1168 zlog_debug ("%s open active, local address %s", peer
->host
,
1169 sockunion2str (peer
->su_local
, buf1
, SU_ADDRSTRLEN
));
1171 zlog_debug ("%s passive open", peer
->host
);
1174 bgp_open_send (peer
);
1179 /* TCP connect fail */
1181 bgp_connect_fail (struct peer
*peer
)
1183 return (bgp_stop (peer
));
1186 /* This function is the first starting point of all BGP connection. It
1187 try to connect to remote peer with non-blocking IO. */
1189 bgp_start (struct peer
*peer
)
1194 bgp_peer_conf_if_to_su_update(peer
);
1196 if (BGP_PEER_START_SUPPRESSED (peer
))
1198 if (bgp_debug_neighbor_events(peer
))
1199 zlog_err ("%s [FSM] Trying to start suppressed peer"
1200 " - this is never supposed to happen!", peer
->host
);
1204 /* Scrub some information that might be left over from a previous,
1207 /* Connection information. */
1210 sockunion_free (peer
->su_local
);
1211 peer
->su_local
= NULL
;
1214 if (peer
->su_remote
)
1216 sockunion_free (peer
->su_remote
);
1217 peer
->su_remote
= NULL
;
1220 /* Clear remote router-id. */
1221 peer
->remote_id
.s_addr
= 0;
1223 /* Clear peer capability flag. */
1226 /* If the peer is passive mode, force to move to Active mode. */
1227 if (CHECK_FLAG (peer
->flags
, PEER_FLAG_PASSIVE
))
1229 BGP_EVENT_ADD (peer
, TCP_connection_open_failed
);
1233 /* Register to be notified on peer up */
1234 if ((peer
->ttl
== 1) || (peer
->gtsm_hops
== 1))
1237 bgp_find_or_add_nexthop(family2afi(peer
->su
.sa
.sa_family
), NULL
, peer
,
1239 status
= bgp_connect (peer
);
1244 if (bgp_debug_neighbor_events(peer
))
1245 zlog_debug ("%s [FSM] Connect error", peer
->host
);
1246 BGP_EVENT_ADD (peer
, TCP_connection_open_failed
);
1248 case connect_success
:
1249 if (bgp_debug_neighbor_events(peer
))
1250 zlog_debug ("%s [FSM] Connect immediately success",
1252 BGP_EVENT_ADD (peer
, TCP_connection_open
);
1254 case connect_in_progress
:
1255 /* To check nonblocking connect, we wait until socket is
1256 readable or writable. */
1257 if (bgp_debug_neighbor_events(peer
))
1258 zlog_debug ("%s [FSM] Non blocking connect waiting result",
1262 zlog_err ("bgp_start peer's fd is negative value %d",
1266 BGP_READ_ON (peer
->t_read
, bgp_read
, peer
->fd
);
1267 BGP_WRITE_ON (peer
->t_write
, bgp_write
, peer
->fd
);
1273 /* Connect retry timer is expired when the peer status is Connect. */
1275 bgp_reconnect (struct peer
*peer
)
1279 if (bgp_stop (peer
) > 0)
1288 bgp_fsm_open (struct peer
*peer
)
1290 /* Send keepalive and make keepalive timer */
1291 bgp_keepalive_send (peer
);
1293 /* Reset holdtimer value. */
1294 BGP_TIMER_OFF (peer
->t_holdtime
);
1299 /* Keepalive send to peer. */
1301 bgp_fsm_keepalive_expire (struct peer
*peer
)
1304 * If there are UPDATE messages to send, no need to send keepalive. The
1305 * peer will note our progress through the UPDATEs.
1307 if (!bgp_routeq_empty(peer
))
1310 bgp_keepalive_send (peer
);
1314 /* FSM error, unexpected event. This is error of BGP connection. So cut the
1315 peer and change to Idle status. */
1317 bgp_fsm_event_error (struct peer
*peer
)
1319 zlog_err ("%s [FSM] unexpected packet received in state %s",
1320 peer
->host
, LOOKUP (bgp_status_msg
, peer
->status
));
1322 return bgp_stop_with_notify (peer
, BGP_NOTIFY_FSM_ERR
, 0);
1325 /* Hold timer expire. This is error of BGP connection. So cut the
1326 peer and change to Idle status. */
1328 bgp_fsm_holdtime_expire (struct peer
*peer
)
1330 if (bgp_debug_neighbor_events(peer
))
1331 zlog_debug ("%s [FSM] Hold timer expire", peer
->host
);
1333 return bgp_stop_with_notify (peer
, BGP_NOTIFY_HOLD_ERR
, 0);
1336 /* Status goes to Established. Send keepalive packet then make first
1337 update information. */
1339 bgp_establish (struct peer
*peer
)
1341 struct bgp_notify
*notify
;
1342 struct peer_af
*paf
;
1345 int nsf_af_count
= 0;
1349 other
= peer
->doppelganger
;
1350 peer
= peer_xfer_conn(peer
);
1353 zlog_err ("%%Neighbor failed in xfer_conn");
1358 ret
= 1; /* bgp_establish specific code when xfer_conn happens. */
1360 /* Reset capability open status flag. */
1361 if (! CHECK_FLAG (peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
))
1362 SET_FLAG (peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1364 /* Clear last notification data. */
1365 notify
= &peer
->notify
;
1367 XFREE (MTYPE_TMP
, notify
->data
);
1368 memset (notify
, 0, sizeof (struct bgp_notify
));
1370 /* Clear start timer value to default. */
1371 peer
->v_start
= BGP_INIT_START_TIMER
;
1373 /* Increment established count. */
1374 peer
->established
++;
1375 bgp_fsm_change_status (peer
, Established
);
1377 /* bgp log-neighbor-changes of neighbor Up */
1378 if (bgp_flag_check (peer
->bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
))
1379 zlog_info ("%%ADJCHANGE: neighbor %s Up", peer
->host
);
1381 /* assign update-group/subgroup */
1382 update_group_adjust_peer_afs(peer
);
1384 /* graceful restart */
1385 UNSET_FLAG (peer
->sflags
, PEER_STATUS_NSF_WAIT
);
1386 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1387 for (safi
= SAFI_UNICAST
; safi
< SAFI_RESERVED_3
; safi
++)
1389 if (peer
->afc_nego
[afi
][safi
]
1390 && CHECK_FLAG (peer
->cap
, PEER_CAP_RESTART_ADV
)
1391 && CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_RESTART_AF_RCV
))
1393 if (peer
->nsf
[afi
][safi
]
1394 && ! CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_RESTART_AF_PRESERVE_RCV
))
1395 bgp_clear_stale_route (peer
, afi
, safi
);
1397 peer
->nsf
[afi
][safi
] = 1;
1402 if (peer
->nsf
[afi
][safi
])
1403 bgp_clear_stale_route (peer
, afi
, safi
);
1404 peer
->nsf
[afi
][safi
] = 0;
1409 SET_FLAG (peer
->sflags
, PEER_STATUS_NSF_MODE
);
1412 UNSET_FLAG (peer
->sflags
, PEER_STATUS_NSF_MODE
);
1413 if (peer
->t_gr_stale
)
1415 BGP_TIMER_OFF (peer
->t_gr_stale
);
1416 if (bgp_debug_neighbor_events(peer
))
1417 zlog_debug ("%s graceful restart stalepath timer stopped", peer
->host
);
1421 if (peer
->t_gr_restart
)
1423 BGP_TIMER_OFF (peer
->t_gr_restart
);
1424 if (bgp_debug_neighbor_events(peer
))
1425 zlog_debug ("%s graceful restart timer stopped", peer
->host
);
1429 bgpTrapEstablished (peer
);
1430 #endif /* HAVE_SNMP */
1432 /* Reset uptime, send keepalive, send current table. */
1433 peer
->uptime
= bgp_clock ();
1435 /* Send route-refresh when ORF is enabled */
1436 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1437 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1438 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_ADV
))
1440 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_RCV
))
1441 bgp_route_refresh_send (peer
, afi
, safi
, ORF_TYPE_PREFIX
,
1442 REFRESH_IMMEDIATE
, 0);
1443 else if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))
1444 bgp_route_refresh_send (peer
, afi
, safi
, ORF_TYPE_PREFIX_OLD
,
1445 REFRESH_IMMEDIATE
, 0);
1448 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1449 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
1450 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
1451 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
))
1452 if (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1453 || CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_OLD_RCV
))
1454 SET_FLAG (peer
->af_sflags
[afi
][safi
], PEER_STATUS_ORF_WAIT_REFRESH
);
1456 bgp_announce_peer (peer
);
1458 /* Start the route advertisement timer to send updates to the peer - if BGP
1459 * is not in read-only mode. If it is, the timer will be started at the end
1460 * of read-only mode.
1462 if (!bgp_update_delay_active(peer
->bgp
))
1464 BGP_TIMER_OFF(peer
->t_routeadv
);
1465 BGP_TIMER_ON (peer
->t_routeadv
, bgp_routeadv_timer
, 0);
1468 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
))
1470 if (bgp_debug_neighbor_events(peer
))
1471 zlog_debug("[Event] Deleting stub connection for peer %s", peer
->host
);
1473 if (peer
->doppelganger
->status
> Active
)
1474 bgp_notify_send (peer
->doppelganger
, BGP_NOTIFY_CEASE
,
1475 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION
);
1477 peer_delete(peer
->doppelganger
);
1483 /* Keepalive packet is received. */
1485 bgp_fsm_keepalive (struct peer
*peer
)
1487 bgp_update_implicit_eors(peer
);
1489 /* peer count update */
1490 peer
->keepalive_in
++;
1492 BGP_TIMER_OFF (peer
->t_holdtime
);
1496 /* Update packet is received. */
1498 bgp_fsm_update (struct peer
*peer
)
1500 BGP_TIMER_OFF (peer
->t_holdtime
);
1504 /* This is empty event. */
1506 bgp_ignore (struct peer
*peer
)
1508 if (bgp_debug_neighbor_events(peer
))
1509 zlog_debug ("%s [FSM] bgp_ignore called", peer
->host
);
1514 bgp_fsm_nht_update(struct peer
*peer
, int valid
)
1521 switch (peer
->status
)
1525 BGP_EVENT_ADD(peer
, BGP_Start
);
1528 ret
= bgp_connect_check(peer
, 0);
1531 BGP_TIMER_OFF(peer
->t_connect
);
1532 BGP_EVENT_ADD(peer
, ConnectRetry_timer_expired
);
1538 BGP_TIMER_OFF(peer
->t_connect
);
1539 BGP_EVENT_ADD(peer
, ConnectRetry_timer_expired
);
1552 /* Finite State Machine structure */
1553 static const struct {
1554 int (*func
) (struct peer
*);
1556 } FSM
[BGP_STATUS_MAX
- 1][BGP_EVENTS_MAX
- 1] =
1559 /* Idle state: In Idle state, all events other than BGP_Start is
1560 ignored. With BGP_Start event, finite state machine calls
1562 {bgp_start
, Connect
}, /* BGP_Start */
1563 {bgp_stop
, Idle
}, /* BGP_Stop */
1564 {bgp_stop
, Idle
}, /* TCP_connection_open */
1565 {bgp_stop
, Idle
}, /* TCP_connection_closed */
1566 {bgp_ignore
, Idle
}, /* TCP_connection_open_failed */
1567 {bgp_stop
, Idle
}, /* TCP_fatal_error */
1568 {bgp_ignore
, Idle
}, /* ConnectRetry_timer_expired */
1569 {bgp_ignore
, Idle
}, /* Hold_Timer_expired */
1570 {bgp_ignore
, Idle
}, /* KeepAlive_timer_expired */
1571 {bgp_ignore
, Idle
}, /* Receive_OPEN_message */
1572 {bgp_ignore
, Idle
}, /* Receive_KEEPALIVE_message */
1573 {bgp_ignore
, Idle
}, /* Receive_UPDATE_message */
1574 {bgp_ignore
, Idle
}, /* Receive_NOTIFICATION_message */
1575 {bgp_ignore
, Idle
}, /* Clearing_Completed */
1579 {bgp_ignore
, Connect
}, /* BGP_Start */
1580 {bgp_stop
, Idle
}, /* BGP_Stop */
1581 {bgp_connect_success
, OpenSent
}, /* TCP_connection_open */
1582 {bgp_stop
, Idle
}, /* TCP_connection_closed */
1583 {bgp_connect_fail
, Active
}, /* TCP_connection_open_failed */
1584 {bgp_connect_fail
, Idle
}, /* TCP_fatal_error */
1585 {bgp_reconnect
, Connect
}, /* ConnectRetry_timer_expired */
1586 {bgp_ignore
, Idle
}, /* Hold_Timer_expired */
1587 {bgp_ignore
, Idle
}, /* KeepAlive_timer_expired */
1588 {bgp_ignore
, Idle
}, /* Receive_OPEN_message */
1589 {bgp_ignore
, Idle
}, /* Receive_KEEPALIVE_message */
1590 {bgp_ignore
, Idle
}, /* Receive_UPDATE_message */
1591 {bgp_stop
, Idle
}, /* Receive_NOTIFICATION_message */
1592 {bgp_ignore
, Idle
}, /* Clearing_Completed */
1596 {bgp_ignore
, Active
}, /* BGP_Start */
1597 {bgp_stop
, Idle
}, /* BGP_Stop */
1598 {bgp_connect_success
, OpenSent
}, /* TCP_connection_open */
1599 {bgp_stop
, Idle
}, /* TCP_connection_closed */
1600 {bgp_ignore
, Active
}, /* TCP_connection_open_failed */
1601 {bgp_ignore
, Idle
}, /* TCP_fatal_error */
1602 {bgp_start
, Connect
}, /* ConnectRetry_timer_expired */
1603 {bgp_ignore
, Idle
}, /* Hold_Timer_expired */
1604 {bgp_ignore
, Idle
}, /* KeepAlive_timer_expired */
1605 {bgp_ignore
, Idle
}, /* Receive_OPEN_message */
1606 {bgp_ignore
, Idle
}, /* Receive_KEEPALIVE_message */
1607 {bgp_ignore
, Idle
}, /* Receive_UPDATE_message */
1608 {bgp_stop_with_error
, Idle
}, /* Receive_NOTIFICATION_message */
1609 {bgp_ignore
, Idle
}, /* Clearing_Completed */
1613 {bgp_ignore
, OpenSent
}, /* BGP_Start */
1614 {bgp_stop
, Idle
}, /* BGP_Stop */
1615 {bgp_stop
, Active
}, /* TCP_connection_open */
1616 {bgp_stop
, Active
}, /* TCP_connection_closed */
1617 {bgp_stop
, Active
}, /* TCP_connection_open_failed */
1618 {bgp_stop
, Active
}, /* TCP_fatal_error */
1619 {bgp_ignore
, Idle
}, /* ConnectRetry_timer_expired */
1620 {bgp_fsm_holdtime_expire
, Idle
}, /* Hold_Timer_expired */
1621 {bgp_ignore
, Idle
}, /* KeepAlive_timer_expired */
1622 {bgp_fsm_open
, OpenConfirm
}, /* Receive_OPEN_message */
1623 {bgp_fsm_event_error
, Idle
}, /* Receive_KEEPALIVE_message */
1624 {bgp_fsm_event_error
, Idle
}, /* Receive_UPDATE_message */
1625 {bgp_stop_with_error
, Idle
}, /* Receive_NOTIFICATION_message */
1626 {bgp_ignore
, Idle
}, /* Clearing_Completed */
1630 {bgp_ignore
, OpenConfirm
}, /* BGP_Start */
1631 {bgp_stop
, Idle
}, /* BGP_Stop */
1632 {bgp_stop
, Idle
}, /* TCP_connection_open */
1633 {bgp_stop
, Idle
}, /* TCP_connection_closed */
1634 {bgp_stop
, Idle
}, /* TCP_connection_open_failed */
1635 {bgp_stop
, Idle
}, /* TCP_fatal_error */
1636 {bgp_ignore
, Idle
}, /* ConnectRetry_timer_expired */
1637 {bgp_fsm_holdtime_expire
, Idle
}, /* Hold_Timer_expired */
1638 {bgp_ignore
, OpenConfirm
}, /* KeepAlive_timer_expired */
1639 {bgp_ignore
, Idle
}, /* Receive_OPEN_message */
1640 {bgp_establish
, Established
}, /* Receive_KEEPALIVE_message */
1641 {bgp_ignore
, Idle
}, /* Receive_UPDATE_message */
1642 {bgp_stop_with_error
, Idle
}, /* Receive_NOTIFICATION_message */
1643 {bgp_ignore
, Idle
}, /* Clearing_Completed */
1647 {bgp_ignore
, Established
}, /* BGP_Start */
1648 {bgp_stop
, Clearing
}, /* BGP_Stop */
1649 {bgp_stop
, Clearing
}, /* TCP_connection_open */
1650 {bgp_stop
, Clearing
}, /* TCP_connection_closed */
1651 {bgp_stop
, Clearing
}, /* TCP_connection_open_failed */
1652 {bgp_stop
, Clearing
}, /* TCP_fatal_error */
1653 {bgp_stop
, Clearing
}, /* ConnectRetry_timer_expired */
1654 {bgp_fsm_holdtime_expire
, Clearing
}, /* Hold_Timer_expired */
1655 {bgp_fsm_keepalive_expire
, Established
}, /* KeepAlive_timer_expired */
1656 {bgp_stop
, Clearing
}, /* Receive_OPEN_message */
1657 {bgp_fsm_keepalive
, Established
}, /* Receive_KEEPALIVE_message */
1658 {bgp_fsm_update
, Established
}, /* Receive_UPDATE_message */
1659 {bgp_stop_with_error
, Clearing
}, /* Receive_NOTIFICATION_message */
1660 {bgp_ignore
, Idle
}, /* Clearing_Completed */
1664 {bgp_ignore
, Clearing
}, /* BGP_Start */
1665 {bgp_stop
, Clearing
}, /* BGP_Stop */
1666 {bgp_stop
, Clearing
}, /* TCP_connection_open */
1667 {bgp_stop
, Clearing
}, /* TCP_connection_closed */
1668 {bgp_stop
, Clearing
}, /* TCP_connection_open_failed */
1669 {bgp_stop
, Clearing
}, /* TCP_fatal_error */
1670 {bgp_stop
, Clearing
}, /* ConnectRetry_timer_expired */
1671 {bgp_stop
, Clearing
}, /* Hold_Timer_expired */
1672 {bgp_stop
, Clearing
}, /* KeepAlive_timer_expired */
1673 {bgp_stop
, Clearing
}, /* Receive_OPEN_message */
1674 {bgp_stop
, Clearing
}, /* Receive_KEEPALIVE_message */
1675 {bgp_stop
, Clearing
}, /* Receive_UPDATE_message */
1676 {bgp_stop
, Clearing
}, /* Receive_NOTIFICATION_message */
1677 {bgp_clearing_completed
, Idle
}, /* Clearing_Completed */
1681 {bgp_ignore
, Deleted
}, /* BGP_Start */
1682 {bgp_ignore
, Deleted
}, /* BGP_Stop */
1683 {bgp_ignore
, Deleted
}, /* TCP_connection_open */
1684 {bgp_ignore
, Deleted
}, /* TCP_connection_closed */
1685 {bgp_ignore
, Deleted
}, /* TCP_connection_open_failed */
1686 {bgp_ignore
, Deleted
}, /* TCP_fatal_error */
1687 {bgp_ignore
, Deleted
}, /* ConnectRetry_timer_expired */
1688 {bgp_ignore
, Deleted
}, /* Hold_Timer_expired */
1689 {bgp_ignore
, Deleted
}, /* KeepAlive_timer_expired */
1690 {bgp_ignore
, Deleted
}, /* Receive_OPEN_message */
1691 {bgp_ignore
, Deleted
}, /* Receive_KEEPALIVE_message */
1692 {bgp_ignore
, Deleted
}, /* Receive_UPDATE_message */
1693 {bgp_ignore
, Deleted
}, /* Receive_NOTIFICATION_message */
1694 {bgp_ignore
, Deleted
}, /* Clearing_Completed */
1698 static const char *bgp_event_str
[] =
1703 "TCP_connection_open",
1704 "TCP_connection_closed",
1705 "TCP_connection_open_failed",
1707 "ConnectRetry_timer_expired",
1708 "Hold_Timer_expired",
1709 "KeepAlive_timer_expired",
1710 "Receive_OPEN_message",
1711 "Receive_KEEPALIVE_message",
1712 "Receive_UPDATE_message",
1713 "Receive_NOTIFICATION_message",
1714 "Clearing_Completed",
1717 /* Execute event process. */
1719 bgp_event (struct thread
*thread
)
1725 peer
= THREAD_ARG (thread
);
1726 event
= THREAD_VAL (thread
);
1728 ret
= bgp_event_update(peer
, event
);
1734 bgp_event_update (struct peer
*peer
, int event
)
1739 int passive_conn
= 0;
1741 other
= peer
->doppelganger
;
1742 passive_conn
= (CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
)) ? 1 : 0;
1744 /* Logging this event. */
1745 next
= FSM
[peer
->status
-1][event
- 1].next_state
;
1747 if (bgp_debug_neighbor_events(peer
) && peer
->status
!= next
)
1748 zlog_debug ("%s [FSM] %s (%s->%s)", peer
->host
,
1749 bgp_event_str
[event
],
1750 LOOKUP (bgp_status_msg
, peer
->status
),
1751 LOOKUP (bgp_status_msg
, next
));
1753 /* Call function. */
1754 if (FSM
[peer
->status
-1][event
- 1].func
)
1755 ret
= (*(FSM
[peer
->status
- 1][event
- 1].func
))(peer
);
1757 /* When function do not want proceed next job return -1. */
1760 if (ret
== 1 && next
== Established
)
1762 /* The case when doppelganger swap accurred in bgp_establish.
1763 Update the peer pointer accordingly */
1767 /* If status is changed. */
1768 if (next
!= peer
->status
)
1769 bgp_fsm_change_status (peer
, next
);
1771 /* Make sure timer is set. */
1772 bgp_timer_set (peer
);
1775 else if (!passive_conn
&& peer
->bgp
)
1777 /* If we got a return value of -1, that means there was an error, restart
1778 * the FSM. If the peer structure was deleted
1780 bgp_fsm_change_status(peer
, Idle
);
1781 bgp_timer_set(peer
);