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