]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_fsm.c
bgpd-nht-connected-route.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
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;
419
420 if (BGP_DEBUG (fsm, FSM))
421 zlog (peer->log, LOG_DEBUG,
422 "%s [FSM] Timer (routeadv timer expire)",
423 peer->host);
424
65957886 425 peer->synctime = bgp_clock ();
718e3744 426
eb821189 427 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
718e3744 428
cb1faec9
DS
429 /*
430 * If there is no UPDATE to send, don't start the timer. We will start
431 * it when the queues go non-empty.
432 */
433 if (bgp_routeq_empty(peer))
434 return 0;
435
436 BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, peer->v_routeadv);
718e3744 437
438 return 0;
439}
440
e0701b79 441/* BGP Peer Down Cause */
fd79ac91 442const char *peer_down_str[] =
e0701b79 443{
444 "",
445 "Router ID changed",
446 "Remote AS changed",
447 "Local AS change",
448 "Cluster ID changed",
449 "Confederation identifier changed",
450 "Confederation peer changed",
451 "RR client config change",
452 "RS client config change",
453 "Update source change",
454 "Address family activated",
455 "Admin. shutdown",
456 "User reset",
457 "BGP Notification received",
458 "BGP Notification send",
459 "Peer closed the session",
460 "Neighbor deleted",
461 "Peer-group add member",
462 "Peer-group delete member",
463 "Capability changed",
464 "Passive config change",
93406d87 465 "Multihop config change",
466 "NSF peer closed the session"
e0701b79 467};
468
94f2b392 469static int
93406d87 470bgp_graceful_restart_timer_expire (struct thread *thread)
471{
472 struct peer *peer;
473 afi_t afi;
474 safi_t safi;
475
476 peer = THREAD_ARG (thread);
477 peer->t_gr_restart = NULL;
478
479 /* NSF delete stale route */
480 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
0a28130d 481 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
93406d87 482 if (peer->nsf[afi][safi])
483 bgp_clear_stale_route (peer, afi, safi);
484
485 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
486 BGP_TIMER_OFF (peer->t_gr_stale);
487
488 if (BGP_DEBUG (events, EVENTS))
489 {
490 zlog_debug ("%s graceful restart timer expired", peer->host);
491 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
492 }
493
494 bgp_timer_set (peer);
495
496 return 0;
497}
498
94f2b392 499static int
93406d87 500bgp_graceful_stale_timer_expire (struct thread *thread)
501{
502 struct peer *peer;
503 afi_t afi;
504 safi_t safi;
505
506 peer = THREAD_ARG (thread);
507 peer->t_gr_stale = NULL;
508
509 if (BGP_DEBUG (events, EVENTS))
510 zlog_debug ("%s graceful restart stalepath timer expired", peer->host);
511
512 /* NSF delete stale route */
513 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
0a28130d 514 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
93406d87 515 if (peer->nsf[afi][safi])
516 bgp_clear_stale_route (peer, afi, safi);
517
518 return 0;
519}
520
f188f2c4
DS
521static int
522bgp_update_delay_applicable (struct bgp *bgp)
523{
524 /* update_delay_over flag should be reset (set to 0) for any new
525 applicability of the update-delay during BGP process lifetime.
526 And it should be set after an occurence of the update-delay is over)*/
527 if (!bgp->update_delay_over)
528 return 1;
529
530 return 0;
531}
532
533int
534bgp_update_delay_active (struct bgp *bgp)
535{
536 if (bgp->t_update_delay)
537 return 1;
538
539 return 0;
540}
541
542int
543bgp_update_delay_configured (struct bgp *bgp)
544{
545 if (bgp->v_update_delay)
546 return 1;
547
548 return 0;
549}
550
551/* Do the post-processing needed when bgp comes out of the read-only mode
552 on ending the update delay. */
553void
554bgp_update_delay_end (struct bgp *bgp)
555{
f188f2c4
DS
556 THREAD_TIMER_OFF (bgp->t_update_delay);
557 THREAD_TIMER_OFF (bgp->t_establish_wait);
558
559 /* Reset update-delay related state */
560 bgp->update_delay_over = 1;
561 bgp->established = 0;
562 bgp->restarted_peers = 0;
563 bgp->implicit_eors = 0;
564 bgp->explicit_eors = 0;
565
566 quagga_timestamp(3, bgp->update_delay_end_time,
567 sizeof(bgp->update_delay_end_time));
568
cb1faec9
DS
569 /*
570 * Add an end-of-initial-update marker to the main process queues so that
4a16ae86
DS
571 * the route advertisement timer for the peers can be started. Also set
572 * the zebra and peer update hold flags. These flags are used to achieve
573 * three stages in the update-delay post processing:
574 * 1. Finish best-path selection for all the prefixes held on the queues.
575 * (routes in BGP are updated, and peers sync queues are populated too)
576 * 2. As the eoiu mark is reached in the bgp process routine, ship all the
577 * routes to zebra. With that zebra should see updates from BGP close
578 * to each other.
579 * 3. Unblock the peer update writes. With that peer update packing with
580 * the prefixes should be at its maximum.
cb1faec9
DS
581 */
582 bgp_add_eoiu_mark(bgp, BGP_TABLE_MAIN);
583 bgp_add_eoiu_mark(bgp, BGP_TABLE_RSCLIENT);
4a16ae86
DS
584 bgp->main_zebra_update_hold = 1;
585 bgp->main_peers_update_hold = 1;
586 bgp->rsclient_peers_update_hold = 1;
f188f2c4
DS
587
588 /* Resume the queue processing. This should trigger the event that would take
589 care of processing any work that was queued during the read-only mode. */
590 work_queue_unplug(bm->process_main_queue);
591 work_queue_unplug(bm->process_rsclient_queue);
592}
593
cb1faec9
DS
594/**
595 * see bgp_fsm.h
596 */
597void
598bgp_start_routeadv (struct bgp *bgp)
599{
600 struct listnode *node, *nnode;
601 struct peer *peer;
602
4a16ae86
DS
603 zlog_info("bgp_start_routeadv(), update hold status - main: %d, rsclient: %d",
604 bgp->main_peers_update_hold, bgp->rsclient_peers_update_hold);
605
606 if (bgp->main_peers_update_hold || bgp->rsclient_peers_update_hold)
607 return;
608
609 quagga_timestamp(3, bgp->update_delay_peers_resume_time,
610 sizeof(bgp->update_delay_peers_resume_time));
611
cb1faec9
DS
612 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
613 {
614 if (peer->status != Established)
615 continue;
616 BGP_TIMER_OFF(peer->t_routeadv);
617 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
618 }
619}
620
621/**
622 * see bgp_fsm.h
623 */
624void
625bgp_adjust_routeadv (struct peer *peer)
626{
627 time_t nowtime = bgp_clock();
628 double diff;
629 unsigned long remain;
630
631 /*
632 * CASE I:
633 * If the last update was written more than MRAI back, expire the timer
634 * instantly so that we can send the update out sooner.
635 *
636 * <------- MRAI --------->
637 * |-----------------|-----------------------|
638 * <------------- m ------------>
639 * ^ ^ ^
640 * | | |
641 * | | current time
642 * | timer start
643 * last write
644 *
645 * m > MRAI
646 */
647 diff = difftime(nowtime, peer->last_write);
648 if (diff > (double) peer->v_routeadv)
649 {
650 BGP_TIMER_OFF(peer->t_routeadv);
651 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
652 if (BGP_DEBUG (update, UPDATE_OUT))
653 zlog (peer->log, LOG_DEBUG, "%s: MRAI timer to expire instantly\n",
654 peer->host);
655 return;
656 }
657
658 /*
659 * CASE II:
660 * - Find when to expire the MRAI timer.
661 * If MRAI timer is not active, assume we can start it now.
662 *
663 * <------- MRAI --------->
664 * |------------|-----------------------|
665 * <-------- m ----------><----- r ----->
666 * ^ ^ ^
667 * | | |
668 * | | current time
669 * | timer start
670 * last write
671 *
672 * (MRAI - m) < r
673 */
674 if (peer->t_routeadv)
675 remain = thread_timer_remain_second(peer->t_routeadv);
676 else
677 remain = peer->v_routeadv;
678 diff = peer->v_routeadv - diff;
679 if (diff <= (double) remain)
680 {
681 BGP_TIMER_OFF(peer->t_routeadv);
682 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, diff);
683 if (BGP_DEBUG (update, UPDATE_OUT))
684 zlog (peer->log, LOG_DEBUG, "%s: MRAI timer to expire in %f secs\n",
685 peer->host, diff);
686 }
687}
688
abc920f8
DS
689static int
690bgp_maxmed_onstartup_applicable (struct bgp *bgp)
691{
692 if (!bgp->maxmed_onstartup_over)
693 return 1;
694
695 return 0;
696}
697
698int
699bgp_maxmed_onstartup_configured (struct bgp *bgp)
700{
701 if (bgp->v_maxmed_onstartup != BGP_MAXMED_ONSTARTUP_UNCONFIGURED)
702 return 1;
703
704 return 0;
705}
706
707int
708bgp_maxmed_onstartup_active (struct bgp *bgp)
709{
710 if (bgp->t_maxmed_onstartup)
711 return 1;
712
713 return 0;
714}
715
716void
717bgp_maxmed_update (struct bgp *bgp)
718{
719 struct listnode *node, *nnode;
720 struct peer *peer;
721 u_char maxmed_active;
722 u_int32_t maxmed_value;
723
724 if (bgp->v_maxmed_admin)
725 {
726 maxmed_active = 1;
727 maxmed_value = bgp->maxmed_admin_value;
728 }
729 else if (bgp->t_maxmed_onstartup)
730 {
731 maxmed_active = 1;
732 maxmed_value = bgp->maxmed_onstartup_value;
733 }
734 else
735 {
736 maxmed_active = 0;
737 maxmed_value = BGP_MAXMED_VALUE_DEFAULT;
738 }
739
740 if (bgp->maxmed_active != maxmed_active ||
741 bgp->maxmed_value != maxmed_value)
742 {
743 bgp->maxmed_active = maxmed_active;
744 bgp->maxmed_value = maxmed_value;
745
746 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
747 bgp_announce_route_all (peer);
748 }
749}
750
751/* The maxmed onstartup timer expiry callback. */
752static int
753bgp_maxmed_onstartup_timer (struct thread *thread)
754{
755 struct bgp *bgp;
756
757 zlog_info ("Max med on startup ended - timer expired.");
758
759 bgp = THREAD_ARG (thread);
760 THREAD_TIMER_OFF (bgp->t_maxmed_onstartup);
761 bgp->maxmed_onstartup_over = 1;
762
763 bgp_maxmed_update(bgp);
764
765 return 0;
766}
767
768static void
769bgp_maxmed_onstartup_begin (struct bgp *bgp)
770{
771 /* Applicable only once in the process lifetime on the startup */
772 if (bgp->maxmed_onstartup_over)
773 return;
774
775 zlog_info ("Begin maxmed onstartup mode - timer %d seconds",
776 bgp->v_maxmed_onstartup);
777
778 THREAD_TIMER_ON (master, bgp->t_maxmed_onstartup,
779 bgp_maxmed_onstartup_timer,
780 bgp, bgp->v_maxmed_onstartup);
781
782 if (!bgp->v_maxmed_admin)
783 {
784 bgp->maxmed_active = 1;
785 bgp->maxmed_value = bgp->maxmed_onstartup_value;
786 }
787
788 /* Route announce to all peers should happen after this in bgp_establish() */
789}
790
791static void
792bgp_maxmed_onstartup_process_status_change(struct peer *peer)
793{
794 if (peer->status == Established && !peer->bgp->established)
795 {
796 bgp_maxmed_onstartup_begin(peer->bgp);
797 }
798}
799
f188f2c4
DS
800/* The update delay timer expiry callback. */
801static int
802bgp_update_delay_timer (struct thread *thread)
803{
804 struct bgp *bgp;
805
806 zlog_info ("Update delay ended - timer expired.");
807
808 bgp = THREAD_ARG (thread);
809 THREAD_TIMER_OFF (bgp->t_update_delay);
810 bgp_update_delay_end(bgp);
811
812 return 0;
813}
814
815/* The establish wait timer expiry callback. */
816static int
817bgp_establish_wait_timer (struct thread *thread)
818{
819 struct bgp *bgp;
820
821 zlog_info ("Establish wait - timer expired.");
822
823 bgp = THREAD_ARG (thread);
824 THREAD_TIMER_OFF (bgp->t_establish_wait);
825 bgp_check_update_delay(bgp);
826
827 return 0;
828}
829
830/* Steps to begin the update delay:
831 - initialize queues if needed
832 - stop the queue processing
833 - start the timer */
834static void
835bgp_update_delay_begin (struct bgp *bgp)
836{
837 struct listnode *node, *nnode;
838 struct peer *peer;
839
840 if ((bm->process_main_queue == NULL) ||
841 (bm->process_rsclient_queue == NULL))
842 bgp_process_queue_init();
843
844 /* Stop the processing of queued work. Enqueue shall continue */
845 work_queue_plug(bm->process_main_queue);
846 work_queue_plug(bm->process_rsclient_queue);
847
848 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
849 peer->update_delay_over = 0;
850
851 /* Start the update-delay timer */
852 THREAD_TIMER_ON (master, bgp->t_update_delay, bgp_update_delay_timer,
853 bgp, bgp->v_update_delay);
854
855 if (bgp->v_establish_wait != bgp->v_update_delay)
856 THREAD_TIMER_ON (master, bgp->t_establish_wait, bgp_establish_wait_timer,
857 bgp, bgp->v_establish_wait);
858
859 quagga_timestamp(3, bgp->update_delay_begin_time,
860 sizeof(bgp->update_delay_begin_time));
861}
862
863static void
864bgp_update_delay_process_status_change(struct peer *peer)
865{
866 if (peer->status == Established)
867 {
868 if (!peer->bgp->established++)
869 {
870 bgp_update_delay_begin(peer->bgp);
871 zlog_info ("Begin read-only mode - update-delay timer %d seconds",
872 peer->bgp->v_update_delay);
873 }
874 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_BIT_RCV))
875 bgp_update_restarted_peers(peer);
876 }
877 if (peer->ostatus == Established && bgp_update_delay_active(peer->bgp))
878 {
879 /* Adjust the update-delay state to account for this flap.
880 NOTE: Intentionally skipping adjusting implicit_eors or explicit_eors
881 counters. Extra sanity check in bgp_check_update_delay() should
882 be enough to take care of any additive discrepancy in bgp eor
883 counters */
884 peer->bgp->established--;
885 peer->update_delay_over = 0;
886 }
887}
888
200df115 889/* Called after event occured, this function change status and reset
890 read/write and timer thread. */
891void
892bgp_fsm_change_status (struct peer *peer, int status)
893{
1ff9a340 894
200df115 895 bgp_dump_state (peer, peer->status, status);
896
f2c31acb
PJ
897 /* Transition into Clearing or Deleted must /always/ clear all routes..
898 * (and must do so before actually changing into Deleted..
899 */
900 if (status >= Clearing)
901 bgp_clear_route_all (peer);
902
200df115 903 /* Preserve old status and change into new status. */
904 peer->ostatus = peer->status;
905 peer->status = status;
f188f2c4 906
1ff9a340
DS
907 if (status == Established)
908 UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
909
abc920f8
DS
910 /* If max-med processing is applicable, do the necessary. */
911 if (status == Established)
912 {
913 if (bgp_maxmed_onstartup_configured(peer->bgp) &&
914 bgp_maxmed_onstartup_applicable(peer->bgp))
915 bgp_maxmed_onstartup_process_status_change(peer);
916 else
917 peer->bgp->maxmed_onstartup_over = 1;
918 }
919
f188f2c4
DS
920 /* If update-delay processing is applicable, do the necessary. */
921 if (bgp_update_delay_configured(peer->bgp) &&
922 bgp_update_delay_applicable(peer->bgp))
923 bgp_update_delay_process_status_change(peer);
924
200df115 925 if (BGP_DEBUG (normal, NORMAL))
926 zlog_debug ("%s went from %s to %s",
927 peer->host,
928 LOOKUP (bgp_status_msg, peer->ostatus),
929 LOOKUP (bgp_status_msg, peer->status));
930}
931
3117b5c4 932/* Flush the event queue and ensure the peer is shut down */
9e4ca89c 933static int
3117b5c4
SH
934bgp_clearing_completed (struct peer *peer)
935{
936 int rc = bgp_stop(peer);
1ff9a340
DS
937
938 if (rc >= 0)
939 BGP_EVENT_FLUSH (peer);
3117b5c4
SH
940
941 return rc;
942}
943
718e3744 944/* Administrative BGP peer stop event. */
3117b5c4 945/* May be called multiple times for the same peer */
718e3744 946int
947bgp_stop (struct peer *peer)
948{
718e3744 949 afi_t afi;
950 safi_t safi;
951 char orf_name[BUFSIZ];
1ff9a340 952 int ret = 0;
718e3744 953
3117b5c4
SH
954 /* Can't do this in Clearing; events are used for state transitions */
955 if (peer->status != Clearing)
2158ad23
PJ
956 {
957 /* Delete all existing events of the peer */
958 BGP_EVENT_FLUSH (peer);
959 }
dcdf399f 960
718e3744 961 /* Increment Dropped count. */
962 if (peer->status == Established)
963 {
718e3744 964 peer->dropped++;
848973c7 965
966 /* bgp log-neighbor-changes of neighbor Down */
967 if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
e0701b79 968 zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer->host,
969 peer_down_str [(int) peer->last_reset]);
848973c7 970
93406d87 971 /* graceful restart */
972 if (peer->t_gr_stale)
973 {
974 BGP_TIMER_OFF (peer->t_gr_stale);
975 if (BGP_DEBUG (events, EVENTS))
976 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
977 }
978 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
979 {
980 if (BGP_DEBUG (events, EVENTS))
981 {
982 zlog_debug ("%s graceful restart timer started for %d sec",
983 peer->host, peer->v_gr_restart);
984 zlog_debug ("%s graceful restart stalepath timer started for %d sec",
985 peer->host, peer->bgp->stalepath_time);
986 }
987 BGP_TIMER_ON (peer->t_gr_restart, bgp_graceful_restart_timer_expire,
988 peer->v_gr_restart);
989 BGP_TIMER_ON (peer->t_gr_stale, bgp_graceful_stale_timer_expire,
990 peer->bgp->stalepath_time);
991 }
992 else
993 {
994 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
995
996 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
0a28130d 997 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
93406d87 998 peer->nsf[afi][safi] = 0;
999 }
1000
848973c7 1001 /* set last reset time */
65957886 1002 peer->resettime = peer->uptime = bgp_clock ();
848973c7 1003
718e3744 1004#ifdef HAVE_SNMP
1005 bgpTrapBackwardTransition (peer);
1006#endif /* HAVE_SNMP */
718e3744 1007
f418446b 1008 /* Reset peer synctime */
1009 peer->synctime = 0;
538621f2 1010 }
718e3744 1011
1012 /* Stop read and write threads when exists. */
1013 BGP_READ_OFF (peer->t_read);
1014 BGP_WRITE_OFF (peer->t_write);
1015
1016 /* Stop all timers. */
1017 BGP_TIMER_OFF (peer->t_start);
1018 BGP_TIMER_OFF (peer->t_connect);
1019 BGP_TIMER_OFF (peer->t_holdtime);
1020 BGP_TIMER_OFF (peer->t_keepalive);
1021 BGP_TIMER_OFF (peer->t_asorig);
1022 BGP_TIMER_OFF (peer->t_routeadv);
1023
718e3744 1024 /* Stream reset. */
1025 peer->packet_size = 0;
1026
1027 /* Clear input and output buffer. */
1028 if (peer->ibuf)
1029 stream_reset (peer->ibuf);
1030 if (peer->work)
1031 stream_reset (peer->work);
200df115 1032 if (peer->obuf)
1033 stream_fifo_clean (peer->obuf);
718e3744 1034
eb821189 1035 /* Close of file descriptor. */
1036 if (peer->fd >= 0)
1037 {
1038 close (peer->fd);
1039 peer->fd = -1;
1040 }
718e3744 1041
718e3744 1042 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1043 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1044 {
538621f2 1045 /* Reset all negotiated variables */
1046 peer->afc_nego[afi][safi] = 0;
1047 peer->afc_adv[afi][safi] = 0;
1048 peer->afc_recv[afi][safi] = 0;
1049
718e3744 1050 /* peer address family capability flags*/
1051 peer->af_cap[afi][safi] = 0;
538621f2 1052
718e3744 1053 /* peer address family status flags*/
1054 peer->af_sflags[afi][safi] = 0;
538621f2 1055
718e3744 1056 /* Received ORF prefix-filter */
1057 peer->orf_plist[afi][safi] = NULL;
538621f2 1058
1ff9a340
DS
1059 if ((peer->status == OpenConfirm) || (peer->status == Established)) {
1060 /* ORF received prefix-filter pnt */
1061 sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
1062 prefix_bgp_orf_remove_all (orf_name);
1063 }
718e3744 1064 }
1065
1066 /* Reset keepalive and holdtime */
1067 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1068 {
1069 peer->v_keepalive = peer->keepalive;
1070 peer->v_holdtime = peer->holdtime;
1071 }
1072 else
1073 {
1074 peer->v_keepalive = peer->bgp->default_keepalive;
1075 peer->v_holdtime = peer->bgp->default_holdtime;
1076 }
1077
1078 peer->update_time = 0;
1079
1080 /* Until we are sure that there is no problem about prefix count
1081 this should be commented out.*/
1082#if 0
1083 /* Reset prefix count */
1084 peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
1085 peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
1086 peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
1087 peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
1088 peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
1089#endif /* 0 */
1090
1ff9a340
DS
1091 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE) &&
1092 !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE)))
1093 {
1094 peer_delete(peer);
1095 ret = -1;
1096 }
a80beece
DS
1097 else
1098 {
1099 bgp_peer_conf_if_to_su_update(peer);
1100 }
1ff9a340
DS
1101
1102 return ret;
718e3744 1103}
1104
1105/* BGP peer is stoped by the error. */
94f2b392 1106static int
718e3744 1107bgp_stop_with_error (struct peer *peer)
1108{
1109 /* Double start timer. */
1110 peer->v_start *= 2;
1111
1112 /* Overflow check. */
1113 if (peer->v_start >= (60 * 2))
1114 peer->v_start = (60 * 2);
1115
1ff9a340 1116 return(bgp_stop (peer));
718e3744 1117}
1118
397b5bde
LR
1119
1120/* something went wrong, send notify and tear down */
1121static int
1122bgp_stop_with_notify (struct peer *peer, u_char code, u_char sub_code)
1123{
1124 /* Send notify to remote peer */
1125 bgp_notify_send (peer, code, sub_code);
1126
397b5bde
LR
1127 /* Clear start timer value to default. */
1128 peer->v_start = BGP_INIT_START_TIMER;
1129
1ff9a340 1130 return(bgp_stop(peer));
397b5bde
LR
1131}
1132
1133
718e3744 1134/* TCP connection open. Next we send open message to remote peer. And
1135 add read thread for reading open message. */
94f2b392 1136static int
718e3744 1137bgp_connect_success (struct peer *peer)
1138{
1ff9a340
DS
1139 int ret = 0;
1140
eb821189 1141 if (peer->fd < 0)
718e3744 1142 {
1143 zlog_err ("bgp_connect_success peer's fd is negative value %d",
eb821189 1144 peer->fd);
1ff9a340 1145 bgp_stop(peer);
718e3744 1146 return -1;
1147 }
718e3744 1148
1ff9a340
DS
1149 if (bgp_getsockname (peer) < 0)
1150 {
1151 zlog_err ("%s: bgp_getsockname(): failed for peer %s", __FUNCTION__,
1152 peer->host);
1153 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0); /* internal error */
1154 return -1;
1155 }
1156
1157 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
f418446b 1158
1159 if (BGP_DEBUG (normal, NORMAL))
1160 {
682ca04c
JBD
1161 char buf1[SU_ADDRSTRLEN];
1162
f418446b 1163 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1164 zlog_debug ("%s open active, local address %s", peer->host,
1165 sockunion2str (peer->su_local, buf1, SU_ADDRSTRLEN));
1166 else
1167 zlog_debug ("%s passive open", peer->host);
1168 }
718e3744 1169
1ff9a340 1170 bgp_open_send (peer);
718e3744 1171
1172 return 0;
1173}
1174
1175/* TCP connect fail */
94f2b392 1176static int
718e3744 1177bgp_connect_fail (struct peer *peer)
1178{
1ff9a340 1179 return (bgp_stop (peer));
718e3744 1180}
1181
1182/* This function is the first starting point of all BGP connection. It
1183 try to connect to remote peer with non-blocking IO. */
1184int
1185bgp_start (struct peer *peer)
1186{
1187 int status;
fc9a856f 1188 int connected = 0;
718e3744 1189
a80beece
DS
1190 bgp_peer_conf_if_to_su_update(peer);
1191
ca058a30
PJ
1192 if (BGP_PEER_START_SUPPRESSED (peer))
1193 {
1194 if (BGP_DEBUG (fsm, FSM))
1195 plog_err (peer->log, "%s [FSM] Trying to start suppressed peer"
1196 " - this is never supposed to happen!", peer->host);
1197 return -1;
1198 }
1199
33d5ab9e
PJ
1200 /* Scrub some information that might be left over from a previous,
1201 * session
1202 */
1203 /* Connection information. */
1204 if (peer->su_local)
1205 {
1206 sockunion_free (peer->su_local);
1207 peer->su_local = NULL;
1208 }
1209
1210 if (peer->su_remote)
1211 {
1212 sockunion_free (peer->su_remote);
1213 peer->su_remote = NULL;
1214 }
1215
1216 /* Clear remote router-id. */
1217 peer->remote_id.s_addr = 0;
1218
1219 /* Clear peer capability flag. */
1220 peer->cap = 0;
1221
718e3744 1222 /* If the peer is passive mode, force to move to Active mode. */
1223 if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
1224 {
1225 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
1226 return 0;
1227 }
1228
fc9a856f
DS
1229 /* Register to be notified on peer up */
1230 if ((peer->ttl == 1) || (peer->gtsm_hops == 1))
1231 connected = 1;
1232
1233 bgp_find_or_add_nexthop(family2afi(peer->su.sa.sa_family), NULL, peer,
1234 connected);
718e3744 1235 status = bgp_connect (peer);
1236
1237 switch (status)
1238 {
1239 case connect_error:
1240 if (BGP_DEBUG (fsm, FSM))
8c2e200a 1241 plog_debug (peer->log, "%s [FSM] Connect error", peer->host);
718e3744 1242 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
1243 break;
1244 case connect_success:
1245 if (BGP_DEBUG (fsm, FSM))
8c2e200a 1246 plog_debug (peer->log, "%s [FSM] Connect immediately success",
eb821189 1247 peer->host);
718e3744 1248 BGP_EVENT_ADD (peer, TCP_connection_open);
1249 break;
1250 case connect_in_progress:
1251 /* To check nonblocking connect, we wait until socket is
1252 readable or writable. */
1253 if (BGP_DEBUG (fsm, FSM))
8c2e200a 1254 plog_debug (peer->log, "%s [FSM] Non blocking connect waiting result",
eb821189 1255 peer->host);
1256 if (peer->fd < 0)
718e3744 1257 {
1258 zlog_err ("bgp_start peer's fd is negative value %d",
eb821189 1259 peer->fd);
718e3744 1260 return -1;
1261 }
eb821189 1262 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1263 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
718e3744 1264 break;
1265 }
1266 return 0;
1267}
1268
1269/* Connect retry timer is expired when the peer status is Connect. */
94f2b392 1270static int
718e3744 1271bgp_reconnect (struct peer *peer)
1272{
1ff9a340
DS
1273 int ret = 0;
1274
1275 if (bgp_stop (peer) > 0)
1276 bgp_start (peer);
1277 else
1278 ret = -1;
1279
1280 return ret;
718e3744 1281}
1282
94f2b392 1283static int
718e3744 1284bgp_fsm_open (struct peer *peer)
1285{
1286 /* Send keepalive and make keepalive timer */
1287 bgp_keepalive_send (peer);
1288
1289 /* Reset holdtimer value. */
1290 BGP_TIMER_OFF (peer->t_holdtime);
1291
1292 return 0;
1293}
1294
718e3744 1295/* Keepalive send to peer. */
94f2b392 1296static int
718e3744 1297bgp_fsm_keepalive_expire (struct peer *peer)
1298{
cb1faec9
DS
1299 /*
1300 * If there are UPDATE messages to send, no need to send keepalive. The
1301 * peer will note our progress through the UPDATEs.
1302 */
1303 if (!bgp_routeq_empty(peer))
1304 return 0;
f188f2c4 1305
718e3744 1306 bgp_keepalive_send (peer);
1307 return 0;
1308}
1309
397b5bde
LR
1310/* FSM error, unexpected event. This is error of BGP connection. So cut the
1311 peer and change to Idle status. */
1312static int
1313bgp_fsm_event_error (struct peer *peer)
1314{
1315 plog_err (peer->log, "%s [FSM] unexpected packet received in state %s",
1316 peer->host, LOOKUP (bgp_status_msg, peer->status));
1317
1318 return bgp_stop_with_notify (peer, BGP_NOTIFY_FSM_ERR, 0);
1319}
1320
718e3744 1321/* Hold timer expire. This is error of BGP connection. So cut the
1322 peer and change to Idle status. */
94f2b392 1323static int
718e3744 1324bgp_fsm_holdtime_expire (struct peer *peer)
1325{
1326 if (BGP_DEBUG (fsm, FSM))
397b5bde 1327 plog_debug (peer->log, "%s [FSM] Hold timer expire", peer->host);
718e3744 1328
397b5bde 1329 return bgp_stop_with_notify (peer, BGP_NOTIFY_HOLD_ERR, 0);
718e3744 1330}
1331
1332/* Status goes to Established. Send keepalive packet then make first
1333 update information. */
94f2b392 1334static int
718e3744 1335bgp_establish (struct peer *peer)
1336{
1337 struct bgp_notify *notify;
1338 afi_t afi;
1339 safi_t safi;
93406d87 1340 int nsf_af_count = 0;
1ff9a340
DS
1341 int ret = 0;
1342 struct peer *other;
1343
1344 other = peer->doppelganger;
1345 peer = peer_xfer_conn(peer);
1346 if (!peer)
1347 {
1348 zlog_err ("%%Neighbor failed in xfer_conn");
1349 return -1;
1350 }
1351
1352 if (other == peer)
1353 ret = 1; /* bgp_establish specific code when xfer_conn happens. */
718e3744 1354
1355 /* Reset capability open status flag. */
1356 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
1357 SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1358
1359 /* Clear last notification data. */
1360 notify = &peer->notify;
1361 if (notify->data)
1362 XFREE (MTYPE_TMP, notify->data);
1363 memset (notify, 0, sizeof (struct bgp_notify));
1364
1365 /* Clear start timer value to default. */
1366 peer->v_start = BGP_INIT_START_TIMER;
1367
1368 /* Increment established count. */
1369 peer->established++;
1370 bgp_fsm_change_status (peer, Established);
848973c7 1371
1372 /* bgp log-neighbor-changes of neighbor Up */
1373 if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
1374 zlog_info ("%%ADJCHANGE: neighbor %s Up", peer->host);
1375
93406d87 1376 /* graceful restart */
1377 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
1378 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
0a28130d 1379 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
93406d87 1380 {
1381 if (peer->afc_nego[afi][safi]
1382 && CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV)
1383 && CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV))
1384 {
1385 if (peer->nsf[afi][safi]
1386 && ! CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV))
1387 bgp_clear_stale_route (peer, afi, safi);
1388
1389 peer->nsf[afi][safi] = 1;
1390 nsf_af_count++;
1391 }
1392 else
1393 {
1394 if (peer->nsf[afi][safi])
1395 bgp_clear_stale_route (peer, afi, safi);
1396 peer->nsf[afi][safi] = 0;
1397 }
1398 }
1399
1400 if (nsf_af_count)
1401 SET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1402 else
1403 {
1404 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1405 if (peer->t_gr_stale)
1406 {
1407 BGP_TIMER_OFF (peer->t_gr_stale);
1408 if (BGP_DEBUG (events, EVENTS))
1409 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
1410 }
1411 }
1412
1413 if (peer->t_gr_restart)
1414 {
1415 BGP_TIMER_OFF (peer->t_gr_restart);
1416 if (BGP_DEBUG (events, EVENTS))
1417 zlog_debug ("%s graceful restart timer stopped", peer->host);
1418 }
1419
718e3744 1420#ifdef HAVE_SNMP
1421 bgpTrapEstablished (peer);
1422#endif /* HAVE_SNMP */
1423
1424 /* Reset uptime, send keepalive, send current table. */
65957886 1425 peer->uptime = bgp_clock ();
718e3744 1426
1427 /* Send route-refresh when ORF is enabled */
1428 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1429 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1430 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV))
1431 {
1432 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
1433 bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX,
1434 REFRESH_IMMEDIATE, 0);
1435 else if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
1436 bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX_OLD,
1437 REFRESH_IMMEDIATE, 0);
1438 }
1439
718e3744 1440 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1441 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1442 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1443 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV))
1444 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1445 || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
1446 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
1447
1448 bgp_announce_route_all (peer);
1449
cb1faec9
DS
1450 /* Start the route advertisement timer to send updates to the peer - if BGP
1451 * is not in read-only mode. If it is, the timer will be started at the end
1452 * of read-only mode.
1453 */
1454 if (!bgp_update_delay_active(peer->bgp))
1455 BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, 0);
718e3744 1456
1ff9a340
DS
1457 if (peer->doppelganger && (peer->doppelganger->status != Deleted))
1458 {
1459 if (BGP_DEBUG (events, EVENTS))
1460 zlog_debug("[Event] Deleting stub connection for peer %s", peer->host);
1461
1462 if (peer->doppelganger->status > Active)
1463 bgp_notify_send (peer->doppelganger, BGP_NOTIFY_CEASE,
1464 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1465 else
1466 peer_delete(peer->doppelganger);
1467 }
1468
1469 return ret;
718e3744 1470}
1471
1472/* Keepalive packet is received. */
94f2b392 1473static int
718e3744 1474bgp_fsm_keepalive (struct peer *peer)
1475{
f188f2c4
DS
1476 bgp_update_implicit_eors(peer);
1477
718e3744 1478 /* peer count update */
1479 peer->keepalive_in++;
1480
1481 BGP_TIMER_OFF (peer->t_holdtime);
1482 return 0;
1483}
1484
1485/* Update packet is received. */
94f2b392 1486static int
718e3744 1487bgp_fsm_update (struct peer *peer)
1488{
1489 BGP_TIMER_OFF (peer->t_holdtime);
1490 return 0;
1491}
1492
1493/* This is empty event. */
94f2b392 1494static int
718e3744 1495bgp_ignore (struct peer *peer)
1496{
1497 if (BGP_DEBUG (fsm, FSM))
1498 zlog (peer->log, LOG_DEBUG, "%s [FSM] bgp_ignore called", peer->host);
1499 return 0;
1500}
6b0655a2 1501
fc9a856f
DS
1502void
1503bgp_fsm_nht_update(struct peer *peer, int valid)
1504{
1505 int ret = 0;
1506
1507 if (!peer)
1508 return;
1509
1510 switch (peer->status)
1511 {
1512 case Idle:
1513 if (valid)
1514 BGP_EVENT_ADD(peer, BGP_Start);
1515 break;
1516 case Connect:
1517 ret = bgp_connect_check(peer, 0);
1518 if (!ret && valid)
1519 {
1520 BGP_TIMER_OFF(peer->t_connect);
1521 BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
1522 }
1523 break;
1524 case Active:
1525 if (valid)
1526 {
1527 BGP_TIMER_OFF(peer->t_connect);
1528 BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
1529 }
1530 case OpenSent:
1531 case OpenConfirm:
1532 case Established:
1533 case Clearing:
1534 case Deleted:
1535 default:
1536 break;
1537 }
1538}
1539
1540
718e3744 1541/* Finite State Machine structure */
fda1d3e0 1542static const struct {
66e5cd87 1543 int (*func) (struct peer *);
718e3744 1544 int next_state;
1545} FSM [BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] =
1546{
1547 {
1548 /* Idle state: In Idle state, all events other than BGP_Start is
1549 ignored. With BGP_Start event, finite state machine calls
1550 bgp_start(). */
1551 {bgp_start, Connect}, /* BGP_Start */
1552 {bgp_stop, Idle}, /* BGP_Stop */
1553 {bgp_stop, Idle}, /* TCP_connection_open */
1554 {bgp_stop, Idle}, /* TCP_connection_closed */
1555 {bgp_ignore, Idle}, /* TCP_connection_open_failed */
1556 {bgp_stop, Idle}, /* TCP_fatal_error */
1557 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
1558 {bgp_ignore, Idle}, /* Hold_Timer_expired */
1559 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
1560 {bgp_ignore, Idle}, /* Receive_OPEN_message */
1561 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
1562 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
1563 {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1564 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1565 },
1566 {
1567 /* Connect */
1568 {bgp_ignore, Connect}, /* BGP_Start */
1569 {bgp_stop, Idle}, /* BGP_Stop */
1570 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
1571 {bgp_stop, Idle}, /* TCP_connection_closed */
1572 {bgp_connect_fail, Active}, /* TCP_connection_open_failed */
1573 {bgp_connect_fail, Idle}, /* TCP_fatal_error */
1574 {bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
1575 {bgp_ignore, Idle}, /* Hold_Timer_expired */
1576 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
1577 {bgp_ignore, Idle}, /* Receive_OPEN_message */
1578 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
1579 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
1580 {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1581 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1582 },
1583 {
1584 /* Active, */
1585 {bgp_ignore, Active}, /* BGP_Start */
1586 {bgp_stop, Idle}, /* BGP_Stop */
1587 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
1588 {bgp_stop, Idle}, /* TCP_connection_closed */
1589 {bgp_ignore, Active}, /* TCP_connection_open_failed */
1590 {bgp_ignore, Idle}, /* TCP_fatal_error */
1591 {bgp_start, Connect}, /* ConnectRetry_timer_expired */
1592 {bgp_ignore, Idle}, /* Hold_Timer_expired */
1593 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
1594 {bgp_ignore, Idle}, /* Receive_OPEN_message */
1595 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
1596 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
1597 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1598 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1599 },
1600 {
1601 /* OpenSent, */
1602 {bgp_ignore, OpenSent}, /* BGP_Start */
1603 {bgp_stop, Idle}, /* BGP_Stop */
536792cd 1604 {bgp_stop, Active}, /* TCP_connection_open */
718e3744 1605 {bgp_stop, Active}, /* TCP_connection_closed */
536792cd
PJ
1606 {bgp_stop, Active}, /* TCP_connection_open_failed */
1607 {bgp_stop, Active}, /* TCP_fatal_error */
718e3744 1608 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
1609 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
1610 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
1611 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
397b5bde
LR
1612 {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
1613 {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
718e3744 1614 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1615 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1616 },
1617 {
1618 /* OpenConfirm, */
1619 {bgp_ignore, OpenConfirm}, /* BGP_Start */
1620 {bgp_stop, Idle}, /* BGP_Stop */
1621 {bgp_stop, Idle}, /* TCP_connection_open */
1622 {bgp_stop, Idle}, /* TCP_connection_closed */
1623 {bgp_stop, Idle}, /* TCP_connection_open_failed */
1624 {bgp_stop, Idle}, /* TCP_fatal_error */
1625 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
1626 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
1627 {bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
1628 {bgp_ignore, Idle}, /* Receive_OPEN_message */
1629 {bgp_establish, Established}, /* Receive_KEEPALIVE_message */
1630 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
1631 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1632 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1633 },
1634 {
1635 /* Established, */
ca058a30
PJ
1636 {bgp_ignore, Established}, /* BGP_Start */
1637 {bgp_stop, Clearing}, /* BGP_Stop */
1638 {bgp_stop, Clearing}, /* TCP_connection_open */
1639 {bgp_stop, Clearing}, /* TCP_connection_closed */
3117b5c4 1640 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
ca058a30 1641 {bgp_stop, Clearing}, /* TCP_fatal_error */
3117b5c4 1642 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
ca058a30 1643 {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
718e3744 1644 {bgp_fsm_keepalive_expire, Established}, /* KeepAlive_timer_expired */
ca058a30
PJ
1645 {bgp_stop, Clearing}, /* Receive_OPEN_message */
1646 {bgp_fsm_keepalive, Established}, /* Receive_KEEPALIVE_message */
1647 {bgp_fsm_update, Established}, /* Receive_UPDATE_message */
1648 {bgp_stop_with_error, Clearing}, /* Receive_NOTIFICATION_message */
1649 {bgp_ignore, Idle}, /* Clearing_Completed */
1650 },
1651 {
1652 /* Clearing, */
1653 {bgp_ignore, Clearing}, /* BGP_Start */
3117b5c4
SH
1654 {bgp_stop, Clearing}, /* BGP_Stop */
1655 {bgp_stop, Clearing}, /* TCP_connection_open */
1656 {bgp_stop, Clearing}, /* TCP_connection_closed */
1657 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
1658 {bgp_stop, Clearing}, /* TCP_fatal_error */
1659 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
1660 {bgp_stop, Clearing}, /* Hold_Timer_expired */
1661 {bgp_stop, Clearing}, /* KeepAlive_timer_expired */
1662 {bgp_stop, Clearing}, /* Receive_OPEN_message */
1663 {bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
1664 {bgp_stop, Clearing}, /* Receive_UPDATE_message */
1665 {bgp_stop, Clearing}, /* Receive_NOTIFICATION_message */
1666 {bgp_clearing_completed, Idle}, /* Clearing_Completed */
ca058a30
PJ
1667 },
1668 {
1669 /* Deleted, */
1670 {bgp_ignore, Deleted}, /* BGP_Start */
1671 {bgp_ignore, Deleted}, /* BGP_Stop */
1672 {bgp_ignore, Deleted}, /* TCP_connection_open */
1673 {bgp_ignore, Deleted}, /* TCP_connection_closed */
1674 {bgp_ignore, Deleted}, /* TCP_connection_open_failed */
1675 {bgp_ignore, Deleted}, /* TCP_fatal_error */
1676 {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
1677 {bgp_ignore, Deleted}, /* Hold_Timer_expired */
1678 {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
1679 {bgp_ignore, Deleted}, /* Receive_OPEN_message */
1680 {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
1681 {bgp_ignore, Deleted}, /* Receive_UPDATE_message */
1682 {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */
1683 {bgp_ignore, Deleted}, /* Clearing_Completed */
718e3744 1684 },
1685};
1686
fd79ac91 1687static const char *bgp_event_str[] =
718e3744 1688{
1689 NULL,
1690 "BGP_Start",
1691 "BGP_Stop",
1692 "TCP_connection_open",
1693 "TCP_connection_closed",
1694 "TCP_connection_open_failed",
1695 "TCP_fatal_error",
1696 "ConnectRetry_timer_expired",
1697 "Hold_Timer_expired",
1698 "KeepAlive_timer_expired",
1699 "Receive_OPEN_message",
1700 "Receive_KEEPALIVE_message",
1701 "Receive_UPDATE_message",
ca058a30
PJ
1702 "Receive_NOTIFICATION_message",
1703 "Clearing_Completed",
718e3744 1704};
1705
1706/* Execute event process. */
1707int
1708bgp_event (struct thread *thread)
1709{
718e3744 1710 int event;
718e3744 1711 struct peer *peer;
1ff9a340 1712 int ret;
718e3744 1713
1714 peer = THREAD_ARG (thread);
1715 event = THREAD_VAL (thread);
1716
1ff9a340
DS
1717 ret = bgp_event_update(peer, event);
1718
1719 return (ret);
1720}
1721
1722int
1723bgp_event_update (struct peer *peer, int event)
1724{
1725 int next;
1726 int ret = 0;
1727 struct peer *other;
1728 int passive_conn = 0;
1729
1730 other = peer->doppelganger;
1731 passive_conn = (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) ? 1 : 0;
1732
718e3744 1733 /* Logging this event. */
1734 next = FSM [peer->status -1][event - 1].next_state;
1735
ca058a30 1736 if (BGP_DEBUG (fsm, FSM) && peer->status != next)
1ff9a340 1737 plog_debug (peer->log, "%s [FSM] %s (%s->%s)", peer->host,
718e3744 1738 bgp_event_str[event],
1739 LOOKUP (bgp_status_msg, peer->status),
1740 LOOKUP (bgp_status_msg, next));
718e3744 1741
1742 /* Call function. */
ca058a30
PJ
1743 if (FSM [peer->status -1][event - 1].func)
1744 ret = (*(FSM [peer->status - 1][event - 1].func))(peer);
718e3744 1745
1746 /* When function do not want proceed next job return -1. */
200df115 1747 if (ret >= 0)
1748 {
1ff9a340
DS
1749 if (ret == 1 && next == Established)
1750 {
1751 /* The case when doppelganger swap accurred in bgp_establish.
1752 Update the peer pointer accordingly */
1753 peer = other;
1754 }
1755
200df115 1756 /* If status is changed. */
1757 if (next != peer->status)
f2c31acb 1758 bgp_fsm_change_status (peer, next);
95fdcd8a 1759
200df115 1760 /* Make sure timer is set. */
1761 bgp_timer_set (peer);
1ff9a340
DS
1762
1763 }
1764 else if (!passive_conn && peer->bgp)
1765 {
1766 /* If we got a return value of -1, that means there was an error, restart
1767 * the FSM. If the peer structure was deleted
1768 */
1769 bgp_fsm_change_status(peer, Idle);
1770 bgp_timer_set(peer);
200df115 1771 }
200df115 1772 return ret;
718e3744 1773}