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