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