]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_fsm.c
Changes to improve BGP convergence time:
[mirror_frr.git] / bgpd / bgp_fsm.c
CommitLineData
718e3744 1/* BGP-4 Finite State Machine
2 From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
3 Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
4
5This file is part of GNU Zebra.
6
7GNU Zebra is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by the
9Free Software Foundation; either version 2, or (at your option) any
10later version.
11
12GNU Zebra is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Zebra; see the file COPYING. If not, write to the Free
19Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
21
22#include <zebra.h>
23
24#include "linklist.h"
25#include "prefix.h"
26#include "vty.h"
27#include "sockunion.h"
28#include "thread.h"
29#include "log.h"
30#include "stream.h"
31#include "memory.h"
32#include "plist.h"
f188f2c4 33#include "workqueue.h"
718e3744 34
35#include "bgpd/bgpd.h"
36#include "bgpd/bgp_attr.h"
37#include "bgpd/bgp_debug.h"
38#include "bgpd/bgp_fsm.h"
39#include "bgpd/bgp_packet.h"
40#include "bgpd/bgp_network.h"
41#include "bgpd/bgp_route.h"
42#include "bgpd/bgp_dump.h"
43#include "bgpd/bgp_open.h"
f188f2c4 44#include "bgpd/bgp_advertise.h"
718e3744 45#ifdef HAVE_SNMP
46#include "bgpd/bgp_snmp.h"
47#endif /* HAVE_SNMP */
6b0655a2 48
718e3744 49/* BGP FSM (finite state machine) has three types of functions. Type
50 one is thread functions. Type two is event functions. Type three
51 is FSM functions. Timer functions are set by bgp_timer_set
52 function. */
53
54/* BGP event function. */
55int bgp_event (struct thread *);
56
57/* BGP thread functions. */
58static int bgp_start_timer (struct thread *);
59static int bgp_connect_timer (struct thread *);
60static int bgp_holdtime_timer (struct thread *);
61static int bgp_keepalive_timer (struct thread *);
62
63/* BGP FSM functions. */
64static int bgp_start (struct peer *);
65
1ff9a340
DS
66static void
67peer_xfer_stats (struct peer *peer_dst, struct peer *peer_src)
68{
69 /* Copy stats over. These are only the pre-established state stats */
70 peer_dst->open_in += peer_src->open_in;
71 peer_dst->open_out += peer_src->open_out;
72 peer_dst->keepalive_in += peer_src->keepalive_in;
73 peer_dst->keepalive_out += peer_src->keepalive_out;
74 peer_dst->notify_in += peer_src->notify_in;
75 peer_dst->notify_out += peer_src->notify_out;
76 peer_dst->dynamic_cap_in += peer_src->dynamic_cap_in;
77 peer_dst->dynamic_cap_out += peer_src->dynamic_cap_out;
78}
79
80static struct peer *
81peer_xfer_conn(struct peer *from_peer)
82{
83 struct peer *peer;
84 afi_t afi;
85 safi_t safi;
86 int fd;
87 int status, pstatus;
88
89 assert(from_peer != NULL);
90
91 peer = from_peer->doppelganger;
92
93 if (!peer || !CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
94 return from_peer;
95
96 BGP_WRITE_OFF(peer->t_write);
97 BGP_READ_OFF(peer->t_read);
98 BGP_WRITE_OFF(from_peer->t_write);
99 BGP_READ_OFF(from_peer->t_read);
100
101 fd = peer->fd;
102 peer->fd = from_peer->fd;
103 from_peer->fd = fd;
104 stream_reset(peer->ibuf);
105 stream_fifo_clean(peer->obuf);
106 stream_fifo_clean(from_peer->obuf);
107
108 peer->v_holdtime = from_peer->v_holdtime;
109 peer->v_keepalive = from_peer->v_keepalive;
110 peer->v_asorig = from_peer->v_asorig;
111 peer->routeadv = from_peer->routeadv;
112 peer->v_routeadv = from_peer->v_routeadv;
113 peer->v_gr_restart = from_peer->v_gr_restart;
114 peer->cap = from_peer->cap;
115 status = peer->status;
116 pstatus = peer->ostatus;
117 peer->status = from_peer->status;
118 peer->ostatus = from_peer->ostatus;
119 from_peer->status = status;
120 from_peer->ostatus = pstatus;
121 peer->remote_id = from_peer->remote_id;
122
123 for (afi = AFI_IP; afi < AFI_MAX; afi++)
124 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
125 {
126 peer->af_flags[afi][safi] = from_peer->af_flags[afi][safi];
127 peer->af_sflags[afi][safi] = from_peer->af_sflags[afi][safi];
128 peer->af_cap[afi][safi] = from_peer->af_cap[afi][safi];
129 peer->afc_nego[afi][safi] = from_peer->afc_nego[afi][safi];
130 peer->afc_adv[afi][safi] = from_peer->afc_adv[afi][safi];
131 peer->afc_recv[afi][safi] = from_peer->afc_recv[afi][safi];
132 }
133
134 if (bgp_getsockname(peer) < 0)
135 {
136 zlog_err ("%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
137 (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER) ? "accept" : ""),
138 peer->host, peer->fd, from_peer->fd);
139 bgp_stop(peer);
140 bgp_stop(from_peer);
141 return NULL;
142 }
143 if (from_peer->status > Active)
144 {
145 if (bgp_getsockname(from_peer) < 0)
146 {
147 zlog_err ("%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
148 (CHECK_FLAG (from_peer->sflags, PEER_STATUS_ACCEPT_PEER) ? "accept" : ""),
149 from_peer->host, from_peer->fd, peer->fd);
150 bgp_stop(from_peer);
151 from_peer = NULL;
152 }
153 }
154
155 BGP_READ_ON(peer->t_read, bgp_read, peer->fd);
156 BGP_WRITE_ON(peer->t_write, bgp_write, peer->fd);
157
158 if (from_peer)
159 peer_xfer_stats(peer, from_peer);
160
161 return(peer);
162}
163
ca058a30
PJ
164/* Check if suppress start/restart of sessions to peer. */
165#define BGP_PEER_START_SUPPRESSED(P) \
166 (CHECK_FLAG ((P)->flags, PEER_FLAG_SHUTDOWN) \
167 || CHECK_FLAG ((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW))
168
718e3744 169/* Hook function called after bgp event is occered. And vty's
170 neighbor command invoke this function after making neighbor
171 structure. */
172void
173bgp_timer_set (struct peer *peer)
174{
718e3744 175 switch (peer->status)
176 {
177 case Idle:
178 /* First entry point of peer's finite state machine. In Idle
179 status start timer is on unless peer is shutdown or peer is
180 inactive. All other timer must be turned off */
ca058a30 181 if (BGP_PEER_START_SUPPRESSED (peer) || ! peer_active (peer))
718e3744 182 {
183 BGP_TIMER_OFF (peer->t_start);
184 }
185 else
186 {
718e3744 187 BGP_TIMER_ON (peer->t_start, bgp_start_timer,
5ca5f1c8 188 peer->v_start);
718e3744 189 }
190 BGP_TIMER_OFF (peer->t_connect);
191 BGP_TIMER_OFF (peer->t_holdtime);
192 BGP_TIMER_OFF (peer->t_keepalive);
193 BGP_TIMER_OFF (peer->t_asorig);
194 BGP_TIMER_OFF (peer->t_routeadv);
195 break;
196
197 case Connect:
5ca5f1c8 198 /* After start timer is expired, the peer moves to Connect
718e3744 199 status. Make sure start timer is off and connect timer is
200 on. */
201 BGP_TIMER_OFF (peer->t_start);
202 BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
203 BGP_TIMER_OFF (peer->t_holdtime);
204 BGP_TIMER_OFF (peer->t_keepalive);
205 BGP_TIMER_OFF (peer->t_asorig);
206 BGP_TIMER_OFF (peer->t_routeadv);
207 break;
208
209 case Active:
210 /* Active is waiting connection from remote peer. And if
211 connect timer is expired, change status to Connect. */
212 BGP_TIMER_OFF (peer->t_start);
213 /* If peer is passive mode, do not set connect timer. */
93406d87 214 if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE)
215 || CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
718e3744 216 {
217 BGP_TIMER_OFF (peer->t_connect);
218 }
219 else
220 {
221 BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
222 }
223 BGP_TIMER_OFF (peer->t_holdtime);
224 BGP_TIMER_OFF (peer->t_keepalive);
225 BGP_TIMER_OFF (peer->t_asorig);
226 BGP_TIMER_OFF (peer->t_routeadv);
227 break;
228
229 case OpenSent:
230 /* OpenSent status. */
231 BGP_TIMER_OFF (peer->t_start);
232 BGP_TIMER_OFF (peer->t_connect);
233 if (peer->v_holdtime != 0)
234 {
235 BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
236 peer->v_holdtime);
237 }
238 else
239 {
240 BGP_TIMER_OFF (peer->t_holdtime);
241 }
242 BGP_TIMER_OFF (peer->t_keepalive);
243 BGP_TIMER_OFF (peer->t_asorig);
244 BGP_TIMER_OFF (peer->t_routeadv);
245 break;
246
247 case OpenConfirm:
248 /* OpenConfirm status. */
249 BGP_TIMER_OFF (peer->t_start);
250 BGP_TIMER_OFF (peer->t_connect);
251
252 /* If the negotiated Hold Time value is zero, then the Hold Time
253 timer and KeepAlive timers are not started. */
254 if (peer->v_holdtime == 0)
255 {
256 BGP_TIMER_OFF (peer->t_holdtime);
257 BGP_TIMER_OFF (peer->t_keepalive);
258 }
259 else
260 {
261 BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
262 peer->v_holdtime);
263 BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
264 peer->v_keepalive);
265 }
266 BGP_TIMER_OFF (peer->t_asorig);
267 BGP_TIMER_OFF (peer->t_routeadv);
268 break;
269
270 case Established:
271 /* In Established status start and connect timer is turned
272 off. */
273 BGP_TIMER_OFF (peer->t_start);
274 BGP_TIMER_OFF (peer->t_connect);
275
276 /* Same as OpenConfirm, if holdtime is zero then both holdtime
277 and keepalive must be turned off. */
278 if (peer->v_holdtime == 0)
279 {
280 BGP_TIMER_OFF (peer->t_holdtime);
281 BGP_TIMER_OFF (peer->t_keepalive);
282 }
283 else
284 {
285 BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
286 peer->v_holdtime);
287 BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
288 peer->v_keepalive);
289 }
290 BGP_TIMER_OFF (peer->t_asorig);
291 break;
ca058a30
PJ
292 case Deleted:
293 BGP_TIMER_OFF (peer->t_gr_restart);
294 BGP_TIMER_OFF (peer->t_gr_stale);
295 BGP_TIMER_OFF (peer->t_pmax_restart);
296 case Clearing:
297 BGP_TIMER_OFF (peer->t_start);
298 BGP_TIMER_OFF (peer->t_connect);
299 BGP_TIMER_OFF (peer->t_holdtime);
300 BGP_TIMER_OFF (peer->t_keepalive);
301 BGP_TIMER_OFF (peer->t_asorig);
302 BGP_TIMER_OFF (peer->t_routeadv);
1ff9a340 303 break;
718e3744 304 }
305}
306
307/* BGP start timer. This function set BGP_Start event to thread value
308 and process event. */
309static int
310bgp_start_timer (struct thread *thread)
311{
312 struct peer *peer;
313
314 peer = THREAD_ARG (thread);
315 peer->t_start = NULL;
316
317 if (BGP_DEBUG (fsm, FSM))
318 zlog (peer->log, LOG_DEBUG,
319 "%s [FSM] Timer (start timer expire).", peer->host);
320
321 THREAD_VAL (thread) = BGP_Start;
200df115 322 bgp_event (thread); /* bgp_event unlocks peer */
718e3744 323
324 return 0;
325}
326
327/* BGP connect retry timer. */
328static int
329bgp_connect_timer (struct thread *thread)
330{
331 struct peer *peer;
1ff9a340 332 int ret;
718e3744 333
334 peer = THREAD_ARG (thread);
335 peer->t_connect = NULL;
336
337 if (BGP_DEBUG (fsm, FSM))
338 zlog (peer->log, LOG_DEBUG, "%s [FSM] Timer (connect timer expire)",
339 peer->host);
340
1ff9a340
DS
341 if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
342 {
343 bgp_stop(peer);
344 ret = -1;
345 }
346 else
347 {
348 THREAD_VAL (thread) = ConnectRetry_timer_expired;
349 bgp_event (thread); /* bgp_event unlocks peer */
350 ret = 0;
351 }
718e3744 352
1ff9a340 353 return ret;
718e3744 354}
355
356/* BGP holdtime timer. */
357static int
358bgp_holdtime_timer (struct thread *thread)
359{
360 struct peer *peer;
361
362 peer = THREAD_ARG (thread);
363 peer->t_holdtime = NULL;
364
365 if (BGP_DEBUG (fsm, FSM))
366 zlog (peer->log, LOG_DEBUG,
367 "%s [FSM] Timer (holdtime timer expire)",
368 peer->host);
369
370 THREAD_VAL (thread) = Hold_Timer_expired;
200df115 371 bgp_event (thread); /* bgp_event unlocks peer */
718e3744 372
373 return 0;
374}
375
376/* BGP keepalive fire ! */
377static int
378bgp_keepalive_timer (struct thread *thread)
379{
380 struct peer *peer;
381
382 peer = THREAD_ARG (thread);
383 peer->t_keepalive = NULL;
384
385 if (BGP_DEBUG (fsm, FSM))
386 zlog (peer->log, LOG_DEBUG,
387 "%s [FSM] Timer (keepalive timer expire)",
388 peer->host);
389
390 THREAD_VAL (thread) = KeepAlive_timer_expired;
200df115 391 bgp_event (thread); /* bgp_event unlocks peer */
718e3744 392
393 return 0;
394}
395
cb1faec9
DS
396static int
397bgp_routeq_empty (struct peer *peer)
398{
399 afi_t afi;
400 safi_t safi;
401
402 for (afi = AFI_IP; afi < AFI_MAX; afi++)
403 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
404 {
405 if (!FIFO_EMPTY(&peer->sync[afi][safi]->withdraw) ||
406 !FIFO_EMPTY(&peer->sync[afi][safi]->update))
407 return 0;
408 }
409 return 1;
410}
411
94f2b392 412static int
718e3744 413bgp_routeadv_timer (struct thread *thread)
414{
415 struct peer *peer;
416
417 peer = THREAD_ARG (thread);
418 peer->t_routeadv = NULL;
d889623f 419 peer->radv_adjusted = 0;
718e3744 420
421 if (BGP_DEBUG (fsm, FSM))
422 zlog (peer->log, LOG_DEBUG,
423 "%s [FSM] Timer (routeadv timer expire)",
424 peer->host);
425
65957886 426 peer->synctime = bgp_clock ();
718e3744 427
eb821189 428 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
718e3744 429
d889623f
DS
430 /* MRAI timer is no longer restarted here, it would be done
431 * when the FIFO is built.
cb1faec9 432 */
718e3744 433
434 return 0;
435}
436
e0701b79 437/* BGP Peer Down Cause */
fd79ac91 438const char *peer_down_str[] =
e0701b79 439{
440 "",
441 "Router ID changed",
442 "Remote AS changed",
443 "Local AS change",
444 "Cluster ID changed",
445 "Confederation identifier changed",
446 "Confederation peer changed",
447 "RR client config change",
448 "RS client config change",
449 "Update source change",
450 "Address family activated",
451 "Admin. shutdown",
452 "User reset",
453 "BGP Notification received",
454 "BGP Notification send",
455 "Peer closed the session",
456 "Neighbor deleted",
457 "Peer-group add member",
458 "Peer-group delete member",
459 "Capability changed",
460 "Passive config change",
93406d87 461 "Multihop config change",
462 "NSF peer closed the session"
e0701b79 463};
464
94f2b392 465static int
93406d87 466bgp_graceful_restart_timer_expire (struct thread *thread)
467{
468 struct peer *peer;
469 afi_t afi;
470 safi_t safi;
471
472 peer = THREAD_ARG (thread);
473 peer->t_gr_restart = NULL;
474
475 /* NSF delete stale route */
476 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
0a28130d 477 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
93406d87 478 if (peer->nsf[afi][safi])
479 bgp_clear_stale_route (peer, afi, safi);
480
481 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
482 BGP_TIMER_OFF (peer->t_gr_stale);
483
484 if (BGP_DEBUG (events, EVENTS))
485 {
486 zlog_debug ("%s graceful restart timer expired", peer->host);
487 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
488 }
489
490 bgp_timer_set (peer);
491
492 return 0;
493}
494
94f2b392 495static int
93406d87 496bgp_graceful_stale_timer_expire (struct thread *thread)
497{
498 struct peer *peer;
499 afi_t afi;
500 safi_t safi;
501
502 peer = THREAD_ARG (thread);
503 peer->t_gr_stale = NULL;
504
505 if (BGP_DEBUG (events, EVENTS))
506 zlog_debug ("%s graceful restart stalepath timer expired", peer->host);
507
508 /* NSF delete stale route */
509 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
0a28130d 510 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
93406d87 511 if (peer->nsf[afi][safi])
512 bgp_clear_stale_route (peer, afi, safi);
513
514 return 0;
515}
516
f188f2c4
DS
517static int
518bgp_update_delay_applicable (struct bgp *bgp)
519{
520 /* update_delay_over flag should be reset (set to 0) for any new
521 applicability of the update-delay during BGP process lifetime.
522 And it should be set after an occurence of the update-delay is over)*/
523 if (!bgp->update_delay_over)
524 return 1;
525
526 return 0;
527}
528
529int
530bgp_update_delay_active (struct bgp *bgp)
531{
532 if (bgp->t_update_delay)
533 return 1;
534
535 return 0;
536}
537
538int
539bgp_update_delay_configured (struct bgp *bgp)
540{
541 if (bgp->v_update_delay)
542 return 1;
543
544 return 0;
545}
546
547/* Do the post-processing needed when bgp comes out of the read-only mode
548 on ending the update delay. */
549void
550bgp_update_delay_end (struct bgp *bgp)
551{
f188f2c4
DS
552 THREAD_TIMER_OFF (bgp->t_update_delay);
553 THREAD_TIMER_OFF (bgp->t_establish_wait);
554
555 /* Reset update-delay related state */
556 bgp->update_delay_over = 1;
557 bgp->established = 0;
558 bgp->restarted_peers = 0;
559 bgp->implicit_eors = 0;
560 bgp->explicit_eors = 0;
561
562 quagga_timestamp(3, bgp->update_delay_end_time,
563 sizeof(bgp->update_delay_end_time));
564
cb1faec9
DS
565 /*
566 * Add an end-of-initial-update marker to the main process queues so that
4a16ae86
DS
567 * the route advertisement timer for the peers can be started. Also set
568 * the zebra and peer update hold flags. These flags are used to achieve
569 * three stages in the update-delay post processing:
570 * 1. Finish best-path selection for all the prefixes held on the queues.
571 * (routes in BGP are updated, and peers sync queues are populated too)
572 * 2. As the eoiu mark is reached in the bgp process routine, ship all the
573 * routes to zebra. With that zebra should see updates from BGP close
574 * to each other.
575 * 3. Unblock the peer update writes. With that peer update packing with
576 * the prefixes should be at its maximum.
cb1faec9
DS
577 */
578 bgp_add_eoiu_mark(bgp, BGP_TABLE_MAIN);
579 bgp_add_eoiu_mark(bgp, BGP_TABLE_RSCLIENT);
4a16ae86
DS
580 bgp->main_zebra_update_hold = 1;
581 bgp->main_peers_update_hold = 1;
582 bgp->rsclient_peers_update_hold = 1;
f188f2c4
DS
583
584 /* Resume the queue processing. This should trigger the event that would take
585 care of processing any work that was queued during the read-only mode. */
586 work_queue_unplug(bm->process_main_queue);
587 work_queue_unplug(bm->process_rsclient_queue);
588}
589
cb1faec9
DS
590/**
591 * see bgp_fsm.h
592 */
593void
594bgp_start_routeadv (struct bgp *bgp)
595{
596 struct listnode *node, *nnode;
597 struct peer *peer;
598
4a16ae86
DS
599 zlog_info("bgp_start_routeadv(), update hold status - main: %d, rsclient: %d",
600 bgp->main_peers_update_hold, bgp->rsclient_peers_update_hold);
601
602 if (bgp->main_peers_update_hold || bgp->rsclient_peers_update_hold)
603 return;
604
605 quagga_timestamp(3, bgp->update_delay_peers_resume_time,
606 sizeof(bgp->update_delay_peers_resume_time));
607
cb1faec9
DS
608 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
609 {
610 if (peer->status != Established)
611 continue;
612 BGP_TIMER_OFF(peer->t_routeadv);
613 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
614 }
615}
616
617/**
618 * see bgp_fsm.h
619 */
620void
621bgp_adjust_routeadv (struct peer *peer)
622{
623 time_t nowtime = bgp_clock();
624 double diff;
625 unsigned long remain;
626
d889623f
DS
627 /* Bypass checks for special case of MRAI being 0 */
628 if (peer->v_routeadv == 0)
629 {
630 /* Stop existing timer, just in case it is running for a different
631 * duration and schedule write thread immediately.
632 */
633 if (peer->t_routeadv)
634 BGP_TIMER_OFF(peer->t_routeadv);
635
636 peer->synctime = bgp_clock ();
637 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
638 return;
639 }
640
641 /* Mark that we've adjusted the timer */
642 peer->radv_adjusted = 1;
643
644
cb1faec9
DS
645 /*
646 * CASE I:
647 * If the last update was written more than MRAI back, expire the timer
648 * instantly so that we can send the update out sooner.
649 *
650 * <------- MRAI --------->
651 * |-----------------|-----------------------|
652 * <------------- m ------------>
653 * ^ ^ ^
654 * | | |
655 * | | current time
656 * | timer start
657 * last write
658 *
659 * m > MRAI
660 */
661 diff = difftime(nowtime, peer->last_write);
662 if (diff > (double) peer->v_routeadv)
663 {
664 BGP_TIMER_OFF(peer->t_routeadv);
665 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
666 if (BGP_DEBUG (update, UPDATE_OUT))
667 zlog (peer->log, LOG_DEBUG, "%s: MRAI timer to expire instantly\n",
668 peer->host);
669 return;
670 }
671
672 /*
673 * CASE II:
674 * - Find when to expire the MRAI timer.
675 * If MRAI timer is not active, assume we can start it now.
676 *
677 * <------- MRAI --------->
678 * |------------|-----------------------|
679 * <-------- m ----------><----- r ----->
680 * ^ ^ ^
681 * | | |
682 * | | current time
683 * | timer start
684 * last write
685 *
686 * (MRAI - m) < r
687 */
688 if (peer->t_routeadv)
689 remain = thread_timer_remain_second(peer->t_routeadv);
690 else
691 remain = peer->v_routeadv;
692 diff = peer->v_routeadv - diff;
693 if (diff <= (double) remain)
694 {
695 BGP_TIMER_OFF(peer->t_routeadv);
696 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, diff);
697 if (BGP_DEBUG (update, UPDATE_OUT))
698 zlog (peer->log, LOG_DEBUG, "%s: MRAI timer to expire in %f secs\n",
699 peer->host, diff);
700 }
701}
702
abc920f8
DS
703static int
704bgp_maxmed_onstartup_applicable (struct bgp *bgp)
705{
706 if (!bgp->maxmed_onstartup_over)
707 return 1;
708
709 return 0;
710}
711
712int
713bgp_maxmed_onstartup_configured (struct bgp *bgp)
714{
715 if (bgp->v_maxmed_onstartup != BGP_MAXMED_ONSTARTUP_UNCONFIGURED)
716 return 1;
717
718 return 0;
719}
720
721int
722bgp_maxmed_onstartup_active (struct bgp *bgp)
723{
724 if (bgp->t_maxmed_onstartup)
725 return 1;
726
727 return 0;
728}
729
730void
731bgp_maxmed_update (struct bgp *bgp)
732{
733 struct listnode *node, *nnode;
734 struct peer *peer;
735 u_char maxmed_active;
736 u_int32_t maxmed_value;
737
738 if (bgp->v_maxmed_admin)
739 {
740 maxmed_active = 1;
741 maxmed_value = bgp->maxmed_admin_value;
742 }
743 else if (bgp->t_maxmed_onstartup)
744 {
745 maxmed_active = 1;
746 maxmed_value = bgp->maxmed_onstartup_value;
747 }
748 else
749 {
750 maxmed_active = 0;
751 maxmed_value = BGP_MAXMED_VALUE_DEFAULT;
752 }
753
754 if (bgp->maxmed_active != maxmed_active ||
755 bgp->maxmed_value != maxmed_value)
756 {
757 bgp->maxmed_active = maxmed_active;
758 bgp->maxmed_value = maxmed_value;
759
760 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
761 bgp_announce_route_all (peer);
762 }
763}
764
765/* The maxmed onstartup timer expiry callback. */
766static int
767bgp_maxmed_onstartup_timer (struct thread *thread)
768{
769 struct bgp *bgp;
770
771 zlog_info ("Max med on startup ended - timer expired.");
772
773 bgp = THREAD_ARG (thread);
774 THREAD_TIMER_OFF (bgp->t_maxmed_onstartup);
775 bgp->maxmed_onstartup_over = 1;
776
777 bgp_maxmed_update(bgp);
778
779 return 0;
780}
781
782static void
783bgp_maxmed_onstartup_begin (struct bgp *bgp)
784{
785 /* Applicable only once in the process lifetime on the startup */
786 if (bgp->maxmed_onstartup_over)
787 return;
788
789 zlog_info ("Begin maxmed onstartup mode - timer %d seconds",
790 bgp->v_maxmed_onstartup);
791
792 THREAD_TIMER_ON (master, bgp->t_maxmed_onstartup,
793 bgp_maxmed_onstartup_timer,
794 bgp, bgp->v_maxmed_onstartup);
795
796 if (!bgp->v_maxmed_admin)
797 {
798 bgp->maxmed_active = 1;
799 bgp->maxmed_value = bgp->maxmed_onstartup_value;
800 }
801
802 /* Route announce to all peers should happen after this in bgp_establish() */
803}
804
805static void
806bgp_maxmed_onstartup_process_status_change(struct peer *peer)
807{
808 if (peer->status == Established && !peer->bgp->established)
809 {
810 bgp_maxmed_onstartup_begin(peer->bgp);
811 }
812}
813
f188f2c4
DS
814/* The update delay timer expiry callback. */
815static int
816bgp_update_delay_timer (struct thread *thread)
817{
818 struct bgp *bgp;
819
820 zlog_info ("Update delay ended - timer expired.");
821
822 bgp = THREAD_ARG (thread);
823 THREAD_TIMER_OFF (bgp->t_update_delay);
824 bgp_update_delay_end(bgp);
825
826 return 0;
827}
828
829/* The establish wait timer expiry callback. */
830static int
831bgp_establish_wait_timer (struct thread *thread)
832{
833 struct bgp *bgp;
834
835 zlog_info ("Establish wait - timer expired.");
836
837 bgp = THREAD_ARG (thread);
838 THREAD_TIMER_OFF (bgp->t_establish_wait);
839 bgp_check_update_delay(bgp);
840
841 return 0;
842}
843
844/* Steps to begin the update delay:
845 - initialize queues if needed
846 - stop the queue processing
847 - start the timer */
848static void
849bgp_update_delay_begin (struct bgp *bgp)
850{
851 struct listnode *node, *nnode;
852 struct peer *peer;
853
854 if ((bm->process_main_queue == NULL) ||
855 (bm->process_rsclient_queue == NULL))
856 bgp_process_queue_init();
857
858 /* Stop the processing of queued work. Enqueue shall continue */
859 work_queue_plug(bm->process_main_queue);
860 work_queue_plug(bm->process_rsclient_queue);
861
862 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
863 peer->update_delay_over = 0;
864
865 /* Start the update-delay timer */
866 THREAD_TIMER_ON (master, bgp->t_update_delay, bgp_update_delay_timer,
867 bgp, bgp->v_update_delay);
868
869 if (bgp->v_establish_wait != bgp->v_update_delay)
870 THREAD_TIMER_ON (master, bgp->t_establish_wait, bgp_establish_wait_timer,
871 bgp, bgp->v_establish_wait);
872
873 quagga_timestamp(3, bgp->update_delay_begin_time,
874 sizeof(bgp->update_delay_begin_time));
875}
876
877static void
878bgp_update_delay_process_status_change(struct peer *peer)
879{
880 if (peer->status == Established)
881 {
882 if (!peer->bgp->established++)
883 {
884 bgp_update_delay_begin(peer->bgp);
885 zlog_info ("Begin read-only mode - update-delay timer %d seconds",
886 peer->bgp->v_update_delay);
887 }
888 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_BIT_RCV))
889 bgp_update_restarted_peers(peer);
890 }
891 if (peer->ostatus == Established && bgp_update_delay_active(peer->bgp))
892 {
893 /* Adjust the update-delay state to account for this flap.
894 NOTE: Intentionally skipping adjusting implicit_eors or explicit_eors
895 counters. Extra sanity check in bgp_check_update_delay() should
896 be enough to take care of any additive discrepancy in bgp eor
897 counters */
898 peer->bgp->established--;
899 peer->update_delay_over = 0;
900 }
901}
902
200df115 903/* Called after event occured, this function change status and reset
904 read/write and timer thread. */
905void
906bgp_fsm_change_status (struct peer *peer, int status)
907{
1ff9a340 908
200df115 909 bgp_dump_state (peer, peer->status, status);
910
f2c31acb
PJ
911 /* Transition into Clearing or Deleted must /always/ clear all routes..
912 * (and must do so before actually changing into Deleted..
913 */
914 if (status >= Clearing)
915 bgp_clear_route_all (peer);
916
200df115 917 /* Preserve old status and change into new status. */
918 peer->ostatus = peer->status;
919 peer->status = status;
f188f2c4 920
1ff9a340
DS
921 if (status == Established)
922 UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
923
abc920f8
DS
924 /* If max-med processing is applicable, do the necessary. */
925 if (status == Established)
926 {
927 if (bgp_maxmed_onstartup_configured(peer->bgp) &&
928 bgp_maxmed_onstartup_applicable(peer->bgp))
929 bgp_maxmed_onstartup_process_status_change(peer);
930 else
931 peer->bgp->maxmed_onstartup_over = 1;
932 }
933
f188f2c4
DS
934 /* If update-delay processing is applicable, do the necessary. */
935 if (bgp_update_delay_configured(peer->bgp) &&
936 bgp_update_delay_applicable(peer->bgp))
937 bgp_update_delay_process_status_change(peer);
938
200df115 939 if (BGP_DEBUG (normal, NORMAL))
940 zlog_debug ("%s went from %s to %s",
941 peer->host,
942 LOOKUP (bgp_status_msg, peer->ostatus),
943 LOOKUP (bgp_status_msg, peer->status));
944}
945
3117b5c4 946/* Flush the event queue and ensure the peer is shut down */
9e4ca89c 947static int
3117b5c4
SH
948bgp_clearing_completed (struct peer *peer)
949{
950 int rc = bgp_stop(peer);
1ff9a340
DS
951
952 if (rc >= 0)
953 BGP_EVENT_FLUSH (peer);
3117b5c4
SH
954
955 return rc;
956}
957
718e3744 958/* Administrative BGP peer stop event. */
3117b5c4 959/* May be called multiple times for the same peer */
718e3744 960int
961bgp_stop (struct peer *peer)
962{
718e3744 963 afi_t afi;
964 safi_t safi;
965 char orf_name[BUFSIZ];
1ff9a340 966 int ret = 0;
718e3744 967
3117b5c4
SH
968 /* Can't do this in Clearing; events are used for state transitions */
969 if (peer->status != Clearing)
2158ad23
PJ
970 {
971 /* Delete all existing events of the peer */
972 BGP_EVENT_FLUSH (peer);
973 }
dcdf399f 974
718e3744 975 /* Increment Dropped count. */
976 if (peer->status == Established)
977 {
718e3744 978 peer->dropped++;
848973c7 979
980 /* bgp log-neighbor-changes of neighbor Down */
981 if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
e0701b79 982 zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer->host,
983 peer_down_str [(int) peer->last_reset]);
848973c7 984
93406d87 985 /* graceful restart */
986 if (peer->t_gr_stale)
987 {
988 BGP_TIMER_OFF (peer->t_gr_stale);
989 if (BGP_DEBUG (events, EVENTS))
990 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
991 }
992 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
993 {
994 if (BGP_DEBUG (events, EVENTS))
995 {
996 zlog_debug ("%s graceful restart timer started for %d sec",
997 peer->host, peer->v_gr_restart);
998 zlog_debug ("%s graceful restart stalepath timer started for %d sec",
999 peer->host, peer->bgp->stalepath_time);
1000 }
1001 BGP_TIMER_ON (peer->t_gr_restart, bgp_graceful_restart_timer_expire,
1002 peer->v_gr_restart);
1003 BGP_TIMER_ON (peer->t_gr_stale, bgp_graceful_stale_timer_expire,
1004 peer->bgp->stalepath_time);
1005 }
1006 else
1007 {
1008 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1009
1010 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
0a28130d 1011 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
93406d87 1012 peer->nsf[afi][safi] = 0;
1013 }
1014
848973c7 1015 /* set last reset time */
65957886 1016 peer->resettime = peer->uptime = bgp_clock ();
848973c7 1017
718e3744 1018#ifdef HAVE_SNMP
1019 bgpTrapBackwardTransition (peer);
1020#endif /* HAVE_SNMP */
718e3744 1021
f418446b 1022 /* Reset peer synctime */
1023 peer->synctime = 0;
538621f2 1024 }
718e3744 1025
1026 /* Stop read and write threads when exists. */
1027 BGP_READ_OFF (peer->t_read);
1028 BGP_WRITE_OFF (peer->t_write);
1029
1030 /* Stop all timers. */
1031 BGP_TIMER_OFF (peer->t_start);
1032 BGP_TIMER_OFF (peer->t_connect);
1033 BGP_TIMER_OFF (peer->t_holdtime);
1034 BGP_TIMER_OFF (peer->t_keepalive);
1035 BGP_TIMER_OFF (peer->t_asorig);
1036 BGP_TIMER_OFF (peer->t_routeadv);
1037
718e3744 1038 /* Stream reset. */
1039 peer->packet_size = 0;
1040
1041 /* Clear input and output buffer. */
1042 if (peer->ibuf)
1043 stream_reset (peer->ibuf);
1044 if (peer->work)
1045 stream_reset (peer->work);
200df115 1046 if (peer->obuf)
1047 stream_fifo_clean (peer->obuf);
718e3744 1048
eb821189 1049 /* Close of file descriptor. */
1050 if (peer->fd >= 0)
1051 {
1052 close (peer->fd);
1053 peer->fd = -1;
1054 }
718e3744 1055
718e3744 1056 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1057 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1058 {
538621f2 1059 /* Reset all negotiated variables */
1060 peer->afc_nego[afi][safi] = 0;
1061 peer->afc_adv[afi][safi] = 0;
1062 peer->afc_recv[afi][safi] = 0;
1063
718e3744 1064 /* peer address family capability flags*/
1065 peer->af_cap[afi][safi] = 0;
538621f2 1066
718e3744 1067 /* peer address family status flags*/
1068 peer->af_sflags[afi][safi] = 0;
538621f2 1069
718e3744 1070 /* Received ORF prefix-filter */
1071 peer->orf_plist[afi][safi] = NULL;
538621f2 1072
1ff9a340
DS
1073 if ((peer->status == OpenConfirm) || (peer->status == Established)) {
1074 /* ORF received prefix-filter pnt */
1075 sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
1076 prefix_bgp_orf_remove_all (orf_name);
1077 }
718e3744 1078 }
1079
1080 /* Reset keepalive and holdtime */
1081 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1082 {
1083 peer->v_keepalive = peer->keepalive;
1084 peer->v_holdtime = peer->holdtime;
1085 }
1086 else
1087 {
1088 peer->v_keepalive = peer->bgp->default_keepalive;
1089 peer->v_holdtime = peer->bgp->default_holdtime;
1090 }
1091
1092 peer->update_time = 0;
1093
1094 /* Until we are sure that there is no problem about prefix count
1095 this should be commented out.*/
1096#if 0
1097 /* Reset prefix count */
1098 peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
1099 peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
1100 peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
1101 peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
1102 peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
1103#endif /* 0 */
1104
1ff9a340
DS
1105 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE) &&
1106 !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE)))
1107 {
1108 peer_delete(peer);
1109 ret = -1;
1110 }
a80beece
DS
1111 else
1112 {
1113 bgp_peer_conf_if_to_su_update(peer);
1114 }
1ff9a340
DS
1115
1116 return ret;
718e3744 1117}
1118
1119/* BGP peer is stoped by the error. */
94f2b392 1120static int
718e3744 1121bgp_stop_with_error (struct peer *peer)
1122{
1123 /* Double start timer. */
1124 peer->v_start *= 2;
1125
1126 /* Overflow check. */
1127 if (peer->v_start >= (60 * 2))
1128 peer->v_start = (60 * 2);
1129
1ff9a340 1130 return(bgp_stop (peer));
718e3744 1131}
1132
397b5bde
LR
1133
1134/* something went wrong, send notify and tear down */
1135static int
1136bgp_stop_with_notify (struct peer *peer, u_char code, u_char sub_code)
1137{
1138 /* Send notify to remote peer */
1139 bgp_notify_send (peer, code, sub_code);
1140
397b5bde
LR
1141 /* Clear start timer value to default. */
1142 peer->v_start = BGP_INIT_START_TIMER;
1143
1ff9a340 1144 return(bgp_stop(peer));
397b5bde
LR
1145}
1146
1147
718e3744 1148/* TCP connection open. Next we send open message to remote peer. And
1149 add read thread for reading open message. */
94f2b392 1150static int
718e3744 1151bgp_connect_success (struct peer *peer)
1152{
1ff9a340
DS
1153 int ret = 0;
1154
eb821189 1155 if (peer->fd < 0)
718e3744 1156 {
1157 zlog_err ("bgp_connect_success peer's fd is negative value %d",
eb821189 1158 peer->fd);
1ff9a340 1159 bgp_stop(peer);
718e3744 1160 return -1;
1161 }
718e3744 1162
1ff9a340
DS
1163 if (bgp_getsockname (peer) < 0)
1164 {
1165 zlog_err ("%s: bgp_getsockname(): failed for peer %s", __FUNCTION__,
1166 peer->host);
1167 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0); /* internal error */
1168 return -1;
1169 }
1170
1171 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
f418446b 1172
1173 if (BGP_DEBUG (normal, NORMAL))
1174 {
682ca04c
JBD
1175 char buf1[SU_ADDRSTRLEN];
1176
f418446b 1177 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1178 zlog_debug ("%s open active, local address %s", peer->host,
1179 sockunion2str (peer->su_local, buf1, SU_ADDRSTRLEN));
1180 else
1181 zlog_debug ("%s passive open", peer->host);
1182 }
718e3744 1183
1ff9a340 1184 bgp_open_send (peer);
718e3744 1185
1186 return 0;
1187}
1188
1189/* TCP connect fail */
94f2b392 1190static int
718e3744 1191bgp_connect_fail (struct peer *peer)
1192{
1ff9a340 1193 return (bgp_stop (peer));
718e3744 1194}
1195
1196/* This function is the first starting point of all BGP connection. It
1197 try to connect to remote peer with non-blocking IO. */
1198int
1199bgp_start (struct peer *peer)
1200{
1201 int status;
fc9a856f 1202 int connected = 0;
718e3744 1203
a80beece
DS
1204 bgp_peer_conf_if_to_su_update(peer);
1205
ca058a30
PJ
1206 if (BGP_PEER_START_SUPPRESSED (peer))
1207 {
1208 if (BGP_DEBUG (fsm, FSM))
1209 plog_err (peer->log, "%s [FSM] Trying to start suppressed peer"
1210 " - this is never supposed to happen!", peer->host);
1211 return -1;
1212 }
1213
33d5ab9e
PJ
1214 /* Scrub some information that might be left over from a previous,
1215 * session
1216 */
1217 /* Connection information. */
1218 if (peer->su_local)
1219 {
1220 sockunion_free (peer->su_local);
1221 peer->su_local = NULL;
1222 }
1223
1224 if (peer->su_remote)
1225 {
1226 sockunion_free (peer->su_remote);
1227 peer->su_remote = NULL;
1228 }
1229
1230 /* Clear remote router-id. */
1231 peer->remote_id.s_addr = 0;
1232
1233 /* Clear peer capability flag. */
1234 peer->cap = 0;
1235
718e3744 1236 /* If the peer is passive mode, force to move to Active mode. */
1237 if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
1238 {
1239 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
1240 return 0;
1241 }
1242
fc9a856f
DS
1243 /* Register to be notified on peer up */
1244 if ((peer->ttl == 1) || (peer->gtsm_hops == 1))
1245 connected = 1;
1246
1247 bgp_find_or_add_nexthop(family2afi(peer->su.sa.sa_family), NULL, peer,
1248 connected);
718e3744 1249 status = bgp_connect (peer);
1250
1251 switch (status)
1252 {
1253 case connect_error:
1254 if (BGP_DEBUG (fsm, FSM))
8c2e200a 1255 plog_debug (peer->log, "%s [FSM] Connect error", peer->host);
718e3744 1256 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
1257 break;
1258 case connect_success:
1259 if (BGP_DEBUG (fsm, FSM))
8c2e200a 1260 plog_debug (peer->log, "%s [FSM] Connect immediately success",
eb821189 1261 peer->host);
718e3744 1262 BGP_EVENT_ADD (peer, TCP_connection_open);
1263 break;
1264 case connect_in_progress:
1265 /* To check nonblocking connect, we wait until socket is
1266 readable or writable. */
1267 if (BGP_DEBUG (fsm, FSM))
8c2e200a 1268 plog_debug (peer->log, "%s [FSM] Non blocking connect waiting result",
eb821189 1269 peer->host);
1270 if (peer->fd < 0)
718e3744 1271 {
1272 zlog_err ("bgp_start peer's fd is negative value %d",
eb821189 1273 peer->fd);
718e3744 1274 return -1;
1275 }
eb821189 1276 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1277 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
718e3744 1278 break;
1279 }
1280 return 0;
1281}
1282
1283/* Connect retry timer is expired when the peer status is Connect. */
94f2b392 1284static int
718e3744 1285bgp_reconnect (struct peer *peer)
1286{
1ff9a340
DS
1287 int ret = 0;
1288
1289 if (bgp_stop (peer) > 0)
1290 bgp_start (peer);
1291 else
1292 ret = -1;
1293
1294 return ret;
718e3744 1295}
1296
94f2b392 1297static int
718e3744 1298bgp_fsm_open (struct peer *peer)
1299{
1300 /* Send keepalive and make keepalive timer */
1301 bgp_keepalive_send (peer);
1302
1303 /* Reset holdtimer value. */
1304 BGP_TIMER_OFF (peer->t_holdtime);
1305
1306 return 0;
1307}
1308
718e3744 1309/* Keepalive send to peer. */
94f2b392 1310static int
718e3744 1311bgp_fsm_keepalive_expire (struct peer *peer)
1312{
cb1faec9
DS
1313 /*
1314 * If there are UPDATE messages to send, no need to send keepalive. The
1315 * peer will note our progress through the UPDATEs.
1316 */
1317 if (!bgp_routeq_empty(peer))
1318 return 0;
f188f2c4 1319
718e3744 1320 bgp_keepalive_send (peer);
1321 return 0;
1322}
1323
397b5bde
LR
1324/* FSM error, unexpected event. This is error of BGP connection. So cut the
1325 peer and change to Idle status. */
1326static int
1327bgp_fsm_event_error (struct peer *peer)
1328{
1329 plog_err (peer->log, "%s [FSM] unexpected packet received in state %s",
1330 peer->host, LOOKUP (bgp_status_msg, peer->status));
1331
1332 return bgp_stop_with_notify (peer, BGP_NOTIFY_FSM_ERR, 0);
1333}
1334
718e3744 1335/* Hold timer expire. This is error of BGP connection. So cut the
1336 peer and change to Idle status. */
94f2b392 1337static int
718e3744 1338bgp_fsm_holdtime_expire (struct peer *peer)
1339{
1340 if (BGP_DEBUG (fsm, FSM))
397b5bde 1341 plog_debug (peer->log, "%s [FSM] Hold timer expire", peer->host);
718e3744 1342
397b5bde 1343 return bgp_stop_with_notify (peer, BGP_NOTIFY_HOLD_ERR, 0);
718e3744 1344}
1345
1346/* Status goes to Established. Send keepalive packet then make first
1347 update information. */
94f2b392 1348static int
718e3744 1349bgp_establish (struct peer *peer)
1350{
1351 struct bgp_notify *notify;
1352 afi_t afi;
1353 safi_t safi;
93406d87 1354 int nsf_af_count = 0;
1ff9a340
DS
1355 int ret = 0;
1356 struct peer *other;
1357
1358 other = peer->doppelganger;
1359 peer = peer_xfer_conn(peer);
1360 if (!peer)
1361 {
1362 zlog_err ("%%Neighbor failed in xfer_conn");
1363 return -1;
1364 }
1365
1366 if (other == peer)
1367 ret = 1; /* bgp_establish specific code when xfer_conn happens. */
718e3744 1368
1369 /* Reset capability open status flag. */
1370 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
1371 SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1372
1373 /* Clear last notification data. */
1374 notify = &peer->notify;
1375 if (notify->data)
1376 XFREE (MTYPE_TMP, notify->data);
1377 memset (notify, 0, sizeof (struct bgp_notify));
1378
1379 /* Clear start timer value to default. */
1380 peer->v_start = BGP_INIT_START_TIMER;
1381
1382 /* Increment established count. */
1383 peer->established++;
1384 bgp_fsm_change_status (peer, Established);
848973c7 1385
1386 /* bgp log-neighbor-changes of neighbor Up */
1387 if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
1388 zlog_info ("%%ADJCHANGE: neighbor %s Up", peer->host);
1389
93406d87 1390 /* graceful restart */
1391 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
1392 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
0a28130d 1393 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
93406d87 1394 {
1395 if (peer->afc_nego[afi][safi]
1396 && CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV)
1397 && CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV))
1398 {
1399 if (peer->nsf[afi][safi]
1400 && ! CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV))
1401 bgp_clear_stale_route (peer, afi, safi);
1402
1403 peer->nsf[afi][safi] = 1;
1404 nsf_af_count++;
1405 }
1406 else
1407 {
1408 if (peer->nsf[afi][safi])
1409 bgp_clear_stale_route (peer, afi, safi);
1410 peer->nsf[afi][safi] = 0;
1411 }
1412 }
1413
1414 if (nsf_af_count)
1415 SET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1416 else
1417 {
1418 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1419 if (peer->t_gr_stale)
1420 {
1421 BGP_TIMER_OFF (peer->t_gr_stale);
1422 if (BGP_DEBUG (events, EVENTS))
1423 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
1424 }
1425 }
1426
1427 if (peer->t_gr_restart)
1428 {
1429 BGP_TIMER_OFF (peer->t_gr_restart);
1430 if (BGP_DEBUG (events, EVENTS))
1431 zlog_debug ("%s graceful restart timer stopped", peer->host);
1432 }
1433
718e3744 1434#ifdef HAVE_SNMP
1435 bgpTrapEstablished (peer);
1436#endif /* HAVE_SNMP */
1437
1438 /* Reset uptime, send keepalive, send current table. */
65957886 1439 peer->uptime = bgp_clock ();
718e3744 1440
1441 /* Send route-refresh when ORF is enabled */
1442 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1443 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1444 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV))
1445 {
1446 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
1447 bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX,
1448 REFRESH_IMMEDIATE, 0);
1449 else if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
1450 bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX_OLD,
1451 REFRESH_IMMEDIATE, 0);
1452 }
1453
718e3744 1454 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1455 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1456 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1457 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV))
1458 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1459 || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
1460 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
1461
1462 bgp_announce_route_all (peer);
1463
cb1faec9
DS
1464 /* Start the route advertisement timer to send updates to the peer - if BGP
1465 * is not in read-only mode. If it is, the timer will be started at the end
1466 * of read-only mode.
1467 */
1468 if (!bgp_update_delay_active(peer->bgp))
1469 BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, 0);
718e3744 1470
1ff9a340
DS
1471 if (peer->doppelganger && (peer->doppelganger->status != Deleted))
1472 {
1473 if (BGP_DEBUG (events, EVENTS))
1474 zlog_debug("[Event] Deleting stub connection for peer %s", peer->host);
1475
1476 if (peer->doppelganger->status > Active)
1477 bgp_notify_send (peer->doppelganger, BGP_NOTIFY_CEASE,
1478 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1479 else
1480 peer_delete(peer->doppelganger);
1481 }
1482
1483 return ret;
718e3744 1484}
1485
1486/* Keepalive packet is received. */
94f2b392 1487static int
718e3744 1488bgp_fsm_keepalive (struct peer *peer)
1489{
f188f2c4
DS
1490 bgp_update_implicit_eors(peer);
1491
718e3744 1492 /* peer count update */
1493 peer->keepalive_in++;
1494
1495 BGP_TIMER_OFF (peer->t_holdtime);
1496 return 0;
1497}
1498
1499/* Update packet is received. */
94f2b392 1500static int
718e3744 1501bgp_fsm_update (struct peer *peer)
1502{
1503 BGP_TIMER_OFF (peer->t_holdtime);
1504 return 0;
1505}
1506
1507/* This is empty event. */
94f2b392 1508static int
718e3744 1509bgp_ignore (struct peer *peer)
1510{
1511 if (BGP_DEBUG (fsm, FSM))
1512 zlog (peer->log, LOG_DEBUG, "%s [FSM] bgp_ignore called", peer->host);
1513 return 0;
1514}
6b0655a2 1515
fc9a856f
DS
1516void
1517bgp_fsm_nht_update(struct peer *peer, int valid)
1518{
1519 int ret = 0;
1520
1521 if (!peer)
1522 return;
1523
1524 switch (peer->status)
1525 {
1526 case Idle:
1527 if (valid)
1528 BGP_EVENT_ADD(peer, BGP_Start);
1529 break;
1530 case Connect:
1531 ret = bgp_connect_check(peer, 0);
1532 if (!ret && valid)
1533 {
1534 BGP_TIMER_OFF(peer->t_connect);
1535 BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
1536 }
1537 break;
1538 case Active:
1539 if (valid)
1540 {
1541 BGP_TIMER_OFF(peer->t_connect);
1542 BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
1543 }
1544 case OpenSent:
1545 case OpenConfirm:
1546 case Established:
1547 case Clearing:
1548 case Deleted:
1549 default:
1550 break;
1551 }
1552}
1553
1554
718e3744 1555/* Finite State Machine structure */
fda1d3e0 1556static const struct {
66e5cd87 1557 int (*func) (struct peer *);
718e3744 1558 int next_state;
1559} FSM [BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] =
1560{
1561 {
1562 /* Idle state: In Idle state, all events other than BGP_Start is
1563 ignored. With BGP_Start event, finite state machine calls
1564 bgp_start(). */
1565 {bgp_start, Connect}, /* BGP_Start */
1566 {bgp_stop, Idle}, /* BGP_Stop */
1567 {bgp_stop, Idle}, /* TCP_connection_open */
1568 {bgp_stop, Idle}, /* TCP_connection_closed */
1569 {bgp_ignore, Idle}, /* TCP_connection_open_failed */
1570 {bgp_stop, Idle}, /* TCP_fatal_error */
1571 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
1572 {bgp_ignore, Idle}, /* Hold_Timer_expired */
1573 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
1574 {bgp_ignore, Idle}, /* Receive_OPEN_message */
1575 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
1576 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
1577 {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1578 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1579 },
1580 {
1581 /* Connect */
1582 {bgp_ignore, Connect}, /* BGP_Start */
1583 {bgp_stop, Idle}, /* BGP_Stop */
1584 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
1585 {bgp_stop, Idle}, /* TCP_connection_closed */
1586 {bgp_connect_fail, Active}, /* TCP_connection_open_failed */
1587 {bgp_connect_fail, Idle}, /* TCP_fatal_error */
1588 {bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
1589 {bgp_ignore, Idle}, /* Hold_Timer_expired */
1590 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
1591 {bgp_ignore, Idle}, /* Receive_OPEN_message */
1592 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
1593 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
1594 {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1595 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1596 },
1597 {
1598 /* Active, */
1599 {bgp_ignore, Active}, /* BGP_Start */
1600 {bgp_stop, Idle}, /* BGP_Stop */
1601 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
1602 {bgp_stop, Idle}, /* TCP_connection_closed */
1603 {bgp_ignore, Active}, /* TCP_connection_open_failed */
1604 {bgp_ignore, Idle}, /* TCP_fatal_error */
1605 {bgp_start, Connect}, /* ConnectRetry_timer_expired */
1606 {bgp_ignore, Idle}, /* Hold_Timer_expired */
1607 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
1608 {bgp_ignore, Idle}, /* Receive_OPEN_message */
1609 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
1610 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
1611 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1612 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1613 },
1614 {
1615 /* OpenSent, */
1616 {bgp_ignore, OpenSent}, /* BGP_Start */
1617 {bgp_stop, Idle}, /* BGP_Stop */
536792cd 1618 {bgp_stop, Active}, /* TCP_connection_open */
718e3744 1619 {bgp_stop, Active}, /* TCP_connection_closed */
536792cd
PJ
1620 {bgp_stop, Active}, /* TCP_connection_open_failed */
1621 {bgp_stop, Active}, /* TCP_fatal_error */
718e3744 1622 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
1623 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
1624 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
1625 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
397b5bde
LR
1626 {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
1627 {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
718e3744 1628 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1629 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1630 },
1631 {
1632 /* OpenConfirm, */
1633 {bgp_ignore, OpenConfirm}, /* BGP_Start */
1634 {bgp_stop, Idle}, /* BGP_Stop */
1635 {bgp_stop, Idle}, /* TCP_connection_open */
1636 {bgp_stop, Idle}, /* TCP_connection_closed */
1637 {bgp_stop, Idle}, /* TCP_connection_open_failed */
1638 {bgp_stop, Idle}, /* TCP_fatal_error */
1639 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
1640 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
1641 {bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
1642 {bgp_ignore, Idle}, /* Receive_OPEN_message */
1643 {bgp_establish, Established}, /* Receive_KEEPALIVE_message */
1644 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
1645 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1646 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1647 },
1648 {
1649 /* Established, */
ca058a30
PJ
1650 {bgp_ignore, Established}, /* BGP_Start */
1651 {bgp_stop, Clearing}, /* BGP_Stop */
1652 {bgp_stop, Clearing}, /* TCP_connection_open */
1653 {bgp_stop, Clearing}, /* TCP_connection_closed */
3117b5c4 1654 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
ca058a30 1655 {bgp_stop, Clearing}, /* TCP_fatal_error */
3117b5c4 1656 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
ca058a30 1657 {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
718e3744 1658 {bgp_fsm_keepalive_expire, Established}, /* KeepAlive_timer_expired */
ca058a30
PJ
1659 {bgp_stop, Clearing}, /* Receive_OPEN_message */
1660 {bgp_fsm_keepalive, Established}, /* Receive_KEEPALIVE_message */
1661 {bgp_fsm_update, Established}, /* Receive_UPDATE_message */
1662 {bgp_stop_with_error, Clearing}, /* Receive_NOTIFICATION_message */
1663 {bgp_ignore, Idle}, /* Clearing_Completed */
1664 },
1665 {
1666 /* Clearing, */
1667 {bgp_ignore, Clearing}, /* BGP_Start */
3117b5c4
SH
1668 {bgp_stop, Clearing}, /* BGP_Stop */
1669 {bgp_stop, Clearing}, /* TCP_connection_open */
1670 {bgp_stop, Clearing}, /* TCP_connection_closed */
1671 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
1672 {bgp_stop, Clearing}, /* TCP_fatal_error */
1673 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
1674 {bgp_stop, Clearing}, /* Hold_Timer_expired */
1675 {bgp_stop, Clearing}, /* KeepAlive_timer_expired */
1676 {bgp_stop, Clearing}, /* Receive_OPEN_message */
1677 {bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
1678 {bgp_stop, Clearing}, /* Receive_UPDATE_message */
1679 {bgp_stop, Clearing}, /* Receive_NOTIFICATION_message */
1680 {bgp_clearing_completed, Idle}, /* Clearing_Completed */
ca058a30
PJ
1681 },
1682 {
1683 /* Deleted, */
1684 {bgp_ignore, Deleted}, /* BGP_Start */
1685 {bgp_ignore, Deleted}, /* BGP_Stop */
1686 {bgp_ignore, Deleted}, /* TCP_connection_open */
1687 {bgp_ignore, Deleted}, /* TCP_connection_closed */
1688 {bgp_ignore, Deleted}, /* TCP_connection_open_failed */
1689 {bgp_ignore, Deleted}, /* TCP_fatal_error */
1690 {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
1691 {bgp_ignore, Deleted}, /* Hold_Timer_expired */
1692 {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
1693 {bgp_ignore, Deleted}, /* Receive_OPEN_message */
1694 {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
1695 {bgp_ignore, Deleted}, /* Receive_UPDATE_message */
1696 {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */
1697 {bgp_ignore, Deleted}, /* Clearing_Completed */
718e3744 1698 },
1699};
1700
fd79ac91 1701static const char *bgp_event_str[] =
718e3744 1702{
1703 NULL,
1704 "BGP_Start",
1705 "BGP_Stop",
1706 "TCP_connection_open",
1707 "TCP_connection_closed",
1708 "TCP_connection_open_failed",
1709 "TCP_fatal_error",
1710 "ConnectRetry_timer_expired",
1711 "Hold_Timer_expired",
1712 "KeepAlive_timer_expired",
1713 "Receive_OPEN_message",
1714 "Receive_KEEPALIVE_message",
1715 "Receive_UPDATE_message",
ca058a30
PJ
1716 "Receive_NOTIFICATION_message",
1717 "Clearing_Completed",
718e3744 1718};
1719
1720/* Execute event process. */
1721int
1722bgp_event (struct thread *thread)
1723{
718e3744 1724 int event;
718e3744 1725 struct peer *peer;
1ff9a340 1726 int ret;
718e3744 1727
1728 peer = THREAD_ARG (thread);
1729 event = THREAD_VAL (thread);
1730
1ff9a340
DS
1731 ret = bgp_event_update(peer, event);
1732
1733 return (ret);
1734}
1735
1736int
1737bgp_event_update (struct peer *peer, int event)
1738{
1739 int next;
1740 int ret = 0;
1741 struct peer *other;
1742 int passive_conn = 0;
1743
1744 other = peer->doppelganger;
1745 passive_conn = (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) ? 1 : 0;
1746
718e3744 1747 /* Logging this event. */
1748 next = FSM [peer->status -1][event - 1].next_state;
1749
ca058a30 1750 if (BGP_DEBUG (fsm, FSM) && peer->status != next)
1ff9a340 1751 plog_debug (peer->log, "%s [FSM] %s (%s->%s)", peer->host,
718e3744 1752 bgp_event_str[event],
1753 LOOKUP (bgp_status_msg, peer->status),
1754 LOOKUP (bgp_status_msg, next));
718e3744 1755
1756 /* Call function. */
ca058a30
PJ
1757 if (FSM [peer->status -1][event - 1].func)
1758 ret = (*(FSM [peer->status - 1][event - 1].func))(peer);
718e3744 1759
1760 /* When function do not want proceed next job return -1. */
200df115 1761 if (ret >= 0)
1762 {
1ff9a340
DS
1763 if (ret == 1 && next == Established)
1764 {
1765 /* The case when doppelganger swap accurred in bgp_establish.
1766 Update the peer pointer accordingly */
1767 peer = other;
1768 }
1769
200df115 1770 /* If status is changed. */
1771 if (next != peer->status)
f2c31acb 1772 bgp_fsm_change_status (peer, next);
95fdcd8a 1773
200df115 1774 /* Make sure timer is set. */
1775 bgp_timer_set (peer);
1ff9a340
DS
1776
1777 }
1778 else if (!passive_conn && peer->bgp)
1779 {
1780 /* If we got a return value of -1, that means there was an error, restart
1781 * the FSM. If the peer structure was deleted
1782 */
1783 bgp_fsm_change_status(peer, Idle);
1784 bgp_timer_set(peer);
200df115 1785 }
200df115 1786 return ret;
718e3744 1787}