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"
33
34#include "bgpd/bgpd.h"
35#include "bgpd/bgp_attr.h"
36#include "bgpd/bgp_debug.h"
37#include "bgpd/bgp_fsm.h"
38#include "bgpd/bgp_packet.h"
39#include "bgpd/bgp_network.h"
40#include "bgpd/bgp_route.h"
41#include "bgpd/bgp_dump.h"
42#include "bgpd/bgp_open.h"
43#ifdef HAVE_SNMP
44#include "bgpd/bgp_snmp.h"
45#endif /* HAVE_SNMP */
46
47/* BGP FSM (finite state machine) has three types of functions.  Type
48   one is thread functions.  Type two is event functions.  Type three
49   is FSM functions.  Timer functions are set by bgp_timer_set
50   function. */
51
52/* BGP event function. */
53int bgp_event (struct thread *);
54
55/* BGP thread functions. */
56static int bgp_start_timer (struct thread *);
57static int bgp_connect_timer (struct thread *);
58static int bgp_holdtime_timer (struct thread *);
59static int bgp_keepalive_timer (struct thread *);
60
61/* BGP FSM functions. */
62static int bgp_start (struct peer *);
63
64/* BGP start timer jitter. */
65static int
66bgp_start_jitter (int time)
67{
68  return ((rand () % (time + 1)) - (time / 2));
69}
70
71/* Check if suppress start/restart of sessions to peer. */
72#define BGP_PEER_START_SUPPRESSED(P) \
73  (CHECK_FLAG ((P)->flags, PEER_FLAG_SHUTDOWN) \
74   || CHECK_FLAG ((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW))
75
76/* Hook function called after bgp event is occered.  And vty's
77   neighbor command invoke this function after making neighbor
78   structure. */
79void
80bgp_timer_set (struct peer *peer)
81{
82  int jitter = 0;
83
84  switch (peer->status)
85    {
86    case Idle:
87      /* First entry point of peer's finite state machine.  In Idle
88	 status start timer is on unless peer is shutdown or peer is
89	 inactive.  All other timer must be turned off */
90      if (BGP_PEER_START_SUPPRESSED (peer) || ! peer_active (peer))
91	{
92	  BGP_TIMER_OFF (peer->t_start);
93	}
94      else
95	{
96	  jitter = bgp_start_jitter (peer->v_start);
97	  BGP_TIMER_ON (peer->t_start, bgp_start_timer,
98			peer->v_start + jitter);
99	}
100      BGP_TIMER_OFF (peer->t_connect);
101      BGP_TIMER_OFF (peer->t_holdtime);
102      BGP_TIMER_OFF (peer->t_keepalive);
103      BGP_TIMER_OFF (peer->t_asorig);
104      BGP_TIMER_OFF (peer->t_routeadv);
105      break;
106
107    case Connect:
108      /* After start timer is expired, the peer moves to Connnect
109         status.  Make sure start timer is off and connect timer is
110         on. */
111      BGP_TIMER_OFF (peer->t_start);
112      BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
113      BGP_TIMER_OFF (peer->t_holdtime);
114      BGP_TIMER_OFF (peer->t_keepalive);
115      BGP_TIMER_OFF (peer->t_asorig);
116      BGP_TIMER_OFF (peer->t_routeadv);
117      break;
118
119    case Active:
120      /* Active is waiting connection from remote peer.  And if
121         connect timer is expired, change status to Connect. */
122      BGP_TIMER_OFF (peer->t_start);
123      /* If peer is passive mode, do not set connect timer. */
124      if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE)
125	  || CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
126	{
127	  BGP_TIMER_OFF (peer->t_connect);
128	}
129      else
130	{
131	  BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
132	}
133      BGP_TIMER_OFF (peer->t_holdtime);
134      BGP_TIMER_OFF (peer->t_keepalive);
135      BGP_TIMER_OFF (peer->t_asorig);
136      BGP_TIMER_OFF (peer->t_routeadv);
137      break;
138
139    case OpenSent:
140      /* OpenSent status. */
141      BGP_TIMER_OFF (peer->t_start);
142      BGP_TIMER_OFF (peer->t_connect);
143      if (peer->v_holdtime != 0)
144	{
145	  BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
146			peer->v_holdtime);
147	}
148      else
149	{
150	  BGP_TIMER_OFF (peer->t_holdtime);
151	}
152      BGP_TIMER_OFF (peer->t_keepalive);
153      BGP_TIMER_OFF (peer->t_asorig);
154      BGP_TIMER_OFF (peer->t_routeadv);
155      break;
156
157    case OpenConfirm:
158      /* OpenConfirm status. */
159      BGP_TIMER_OFF (peer->t_start);
160      BGP_TIMER_OFF (peer->t_connect);
161
162      /* If the negotiated Hold Time value is zero, then the Hold Time
163         timer and KeepAlive timers are not started. */
164      if (peer->v_holdtime == 0)
165	{
166	  BGP_TIMER_OFF (peer->t_holdtime);
167	  BGP_TIMER_OFF (peer->t_keepalive);
168	}
169      else
170	{
171	  BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
172			peer->v_holdtime);
173	  BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
174			peer->v_keepalive);
175	}
176      BGP_TIMER_OFF (peer->t_asorig);
177      BGP_TIMER_OFF (peer->t_routeadv);
178      break;
179
180    case Established:
181      /* In Established status start and connect timer is turned
182         off. */
183      BGP_TIMER_OFF (peer->t_start);
184      BGP_TIMER_OFF (peer->t_connect);
185
186      /* Same as OpenConfirm, if holdtime is zero then both holdtime
187         and keepalive must be turned off. */
188      if (peer->v_holdtime == 0)
189	{
190	  BGP_TIMER_OFF (peer->t_holdtime);
191	  BGP_TIMER_OFF (peer->t_keepalive);
192	}
193      else
194	{
195	  BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
196			peer->v_holdtime);
197	  BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
198			peer->v_keepalive);
199	}
200      BGP_TIMER_OFF (peer->t_asorig);
201      break;
202    case Deleted:
203      BGP_TIMER_OFF (peer->t_gr_restart);
204      BGP_TIMER_OFF (peer->t_gr_stale);
205      BGP_TIMER_OFF (peer->t_pmax_restart);
206    case Clearing:
207      BGP_TIMER_OFF (peer->t_start);
208      BGP_TIMER_OFF (peer->t_connect);
209      BGP_TIMER_OFF (peer->t_holdtime);
210      BGP_TIMER_OFF (peer->t_keepalive);
211      BGP_TIMER_OFF (peer->t_asorig);
212      BGP_TIMER_OFF (peer->t_routeadv);
213    }
214}
215
216/* BGP start timer.  This function set BGP_Start event to thread value
217   and process event. */
218static int
219bgp_start_timer (struct thread *thread)
220{
221  struct peer *peer;
222
223  peer = THREAD_ARG (thread);
224  peer->t_start = NULL;
225
226  if (BGP_DEBUG (fsm, FSM))
227    zlog (peer->log, LOG_DEBUG,
228	  "%s [FSM] Timer (start timer expire).", peer->host);
229
230  THREAD_VAL (thread) = BGP_Start;
231  bgp_event (thread);  /* bgp_event unlocks peer */
232
233  return 0;
234}
235
236/* BGP connect retry timer. */
237static int
238bgp_connect_timer (struct thread *thread)
239{
240  struct peer *peer;
241
242  peer = THREAD_ARG (thread);
243  peer->t_connect = NULL;
244
245  if (BGP_DEBUG (fsm, FSM))
246    zlog (peer->log, LOG_DEBUG, "%s [FSM] Timer (connect timer expire)",
247	  peer->host);
248
249  THREAD_VAL (thread) = ConnectRetry_timer_expired;
250  bgp_event (thread); /* bgp_event unlocks peer */
251
252  return 0;
253}
254
255/* BGP holdtime timer. */
256static int
257bgp_holdtime_timer (struct thread *thread)
258{
259  struct peer *peer;
260
261  peer = THREAD_ARG (thread);
262  peer->t_holdtime = NULL;
263
264  if (BGP_DEBUG (fsm, FSM))
265    zlog (peer->log, LOG_DEBUG,
266	  "%s [FSM] Timer (holdtime timer expire)",
267	  peer->host);
268
269  THREAD_VAL (thread) = Hold_Timer_expired;
270  bgp_event (thread); /* bgp_event unlocks peer */
271
272  return 0;
273}
274
275/* BGP keepalive fire ! */
276static int
277bgp_keepalive_timer (struct thread *thread)
278{
279  struct peer *peer;
280
281  peer = THREAD_ARG (thread);
282  peer->t_keepalive = NULL;
283
284  if (BGP_DEBUG (fsm, FSM))
285    zlog (peer->log, LOG_DEBUG,
286	  "%s [FSM] Timer (keepalive timer expire)",
287	  peer->host);
288
289  THREAD_VAL (thread) = KeepAlive_timer_expired;
290  bgp_event (thread); /* bgp_event unlocks peer */
291
292  return 0;
293}
294
295static int
296bgp_routeadv_timer (struct thread *thread)
297{
298  struct peer *peer;
299
300  peer = THREAD_ARG (thread);
301  peer->t_routeadv = NULL;
302
303  if (BGP_DEBUG (fsm, FSM))
304    zlog (peer->log, LOG_DEBUG,
305	  "%s [FSM] Timer (routeadv timer expire)",
306	  peer->host);
307
308  peer->synctime = bgp_clock ();
309
310  BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
311
312  BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer,
313		peer->v_routeadv);
314
315  return 0;
316}
317
318/* BGP Peer Down Cause */
319const char *peer_down_str[] =
320{
321  "",
322  "Router ID changed",
323  "Remote AS changed",
324  "Local AS change",
325  "Cluster ID changed",
326  "Confederation identifier changed",
327  "Confederation peer changed",
328  "RR client config change",
329  "RS client config change",
330  "Update source change",
331  "Address family activated",
332  "Admin. shutdown",
333  "User reset",
334  "BGP Notification received",
335  "BGP Notification send",
336  "Peer closed the session",
337  "Neighbor deleted",
338  "Peer-group add member",
339  "Peer-group delete member",
340  "Capability changed",
341  "Passive config change",
342  "Multihop config change",
343  "NSF peer closed the session"
344};
345
346static int
347bgp_graceful_restart_timer_expire (struct thread *thread)
348{
349  struct peer *peer;
350  afi_t afi;
351  safi_t safi;
352
353  peer = THREAD_ARG (thread);
354  peer->t_gr_restart = NULL;
355
356  /* NSF delete stale route */
357  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
358    for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
359      if (peer->nsf[afi][safi])
360	bgp_clear_stale_route (peer, afi, safi);
361
362  UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
363  BGP_TIMER_OFF (peer->t_gr_stale);
364
365  if (BGP_DEBUG (events, EVENTS))
366    {
367      zlog_debug ("%s graceful restart timer expired", peer->host);
368      zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
369    }
370
371  bgp_timer_set (peer);
372
373  return 0;
374}
375
376static int
377bgp_graceful_stale_timer_expire (struct thread *thread)
378{
379  struct peer *peer;
380  afi_t afi;
381  safi_t safi;
382
383  peer = THREAD_ARG (thread);
384  peer->t_gr_stale = NULL;
385
386  if (BGP_DEBUG (events, EVENTS))
387    zlog_debug ("%s graceful restart stalepath timer expired", peer->host);
388
389  /* NSF delete stale route */
390  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
391    for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
392      if (peer->nsf[afi][safi])
393	bgp_clear_stale_route (peer, afi, safi);
394
395  return 0;
396}
397
398/* Called after event occured, this function change status and reset
399   read/write and timer thread. */
400void
401bgp_fsm_change_status (struct peer *peer, int status)
402{
403  bgp_dump_state (peer, peer->status, status);
404
405  /* Transition into Clearing or Deleted must /always/ clear all routes..
406   * (and must do so before actually changing into Deleted..
407   */
408  if (status >= Clearing)
409    bgp_clear_route_all (peer);
410
411  /* Preserve old status and change into new status. */
412  peer->ostatus = peer->status;
413  peer->status = status;
414
415  if (BGP_DEBUG (normal, NORMAL))
416    zlog_debug ("%s went from %s to %s",
417		peer->host,
418		LOOKUP (bgp_status_msg, peer->ostatus),
419		LOOKUP (bgp_status_msg, peer->status));
420}
421
422/* Flush the event queue and ensure the peer is shut down */
423static int
424bgp_clearing_completed (struct peer *peer)
425{
426  int rc = bgp_stop(peer);
427  BGP_EVENT_FLUSH (peer);
428
429  return rc;
430}
431
432/* Administrative BGP peer stop event. */
433/* May be called multiple times for the same peer */
434int
435bgp_stop (struct peer *peer)
436{
437  afi_t afi;
438  safi_t safi;
439  char orf_name[BUFSIZ];
440
441  /* Can't do this in Clearing; events are used for state transitions */
442  if (peer->status != Clearing)
443    {
444      /* Delete all existing events of the peer */
445      BGP_EVENT_FLUSH (peer);
446    }
447
448  /* Increment Dropped count. */
449  if (peer->status == Established)
450    {
451      peer->dropped++;
452
453      /* bgp log-neighbor-changes of neighbor Down */
454      if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
455	zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer->host,
456                   peer_down_str [(int) peer->last_reset]);
457
458      /* graceful restart */
459      if (peer->t_gr_stale)
460	{
461	  BGP_TIMER_OFF (peer->t_gr_stale);
462	  if (BGP_DEBUG (events, EVENTS))
463	    zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
464	}
465      if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
466	{
467	  if (BGP_DEBUG (events, EVENTS))
468	    {
469	      zlog_debug ("%s graceful restart timer started for %d sec",
470			  peer->host, peer->v_gr_restart);
471	      zlog_debug ("%s graceful restart stalepath timer started for %d sec",
472			  peer->host, peer->bgp->stalepath_time);
473	    }
474	  BGP_TIMER_ON (peer->t_gr_restart, bgp_graceful_restart_timer_expire,
475			peer->v_gr_restart);
476	  BGP_TIMER_ON (peer->t_gr_stale, bgp_graceful_stale_timer_expire,
477			peer->bgp->stalepath_time);
478	}
479      else
480	{
481	  UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
482
483	  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
484	    for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
485	      peer->nsf[afi][safi] = 0;
486	}
487
488      /* set last reset time */
489      peer->resettime = peer->uptime = bgp_clock ();
490
491#ifdef HAVE_SNMP
492      bgpTrapBackwardTransition (peer);
493#endif /* HAVE_SNMP */
494
495      /* Reset peer synctime */
496      peer->synctime = 0;
497    }
498
499  /* Stop read and write threads when exists. */
500  BGP_READ_OFF (peer->t_read);
501  BGP_WRITE_OFF (peer->t_write);
502
503  /* Stop all timers. */
504  BGP_TIMER_OFF (peer->t_start);
505  BGP_TIMER_OFF (peer->t_connect);
506  BGP_TIMER_OFF (peer->t_holdtime);
507  BGP_TIMER_OFF (peer->t_keepalive);
508  BGP_TIMER_OFF (peer->t_asorig);
509  BGP_TIMER_OFF (peer->t_routeadv);
510
511  /* Stream reset. */
512  peer->packet_size = 0;
513
514  /* Clear input and output buffer.  */
515  if (peer->ibuf)
516    stream_reset (peer->ibuf);
517  if (peer->work)
518    stream_reset (peer->work);
519  if (peer->obuf)
520    stream_fifo_clean (peer->obuf);
521
522  /* Close of file descriptor. */
523  if (peer->fd >= 0)
524    {
525      close (peer->fd);
526      peer->fd = -1;
527    }
528
529  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
530    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
531      {
532        /* Reset all negotiated variables */
533        peer->afc_nego[afi][safi] = 0;
534        peer->afc_adv[afi][safi] = 0;
535        peer->afc_recv[afi][safi] = 0;
536
537	/* peer address family capability flags*/
538	peer->af_cap[afi][safi] = 0;
539
540	/* peer address family status flags*/
541	peer->af_sflags[afi][safi] = 0;
542
543	/* Received ORF prefix-filter */
544	peer->orf_plist[afi][safi] = NULL;
545
546        /* ORF received prefix-filter pnt */
547        sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
548        prefix_bgp_orf_remove_all (orf_name);
549      }
550
551  /* Reset keepalive and holdtime */
552  if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
553    {
554      peer->v_keepalive = peer->keepalive;
555      peer->v_holdtime = peer->holdtime;
556    }
557  else
558    {
559      peer->v_keepalive = peer->bgp->default_keepalive;
560      peer->v_holdtime = peer->bgp->default_holdtime;
561    }
562
563  peer->update_time = 0;
564
565  /* Until we are sure that there is no problem about prefix count
566     this should be commented out.*/
567#if 0
568  /* Reset prefix count */
569  peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
570  peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
571  peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
572  peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
573  peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
574#endif /* 0 */
575
576  return 0;
577}
578
579/* BGP peer is stoped by the error. */
580static int
581bgp_stop_with_error (struct peer *peer)
582{
583  /* Double start timer. */
584  peer->v_start *= 2;
585
586  /* Overflow check. */
587  if (peer->v_start >= (60 * 2))
588    peer->v_start = (60 * 2);
589
590  bgp_stop (peer);
591
592  return 0;
593}
594
595
596/* something went wrong, send notify and tear down */
597static int
598bgp_stop_with_notify (struct peer *peer, u_char code, u_char sub_code)
599{
600  /* Send notify to remote peer */
601  bgp_notify_send (peer, code, sub_code);
602
603  /* Sweep if it is temporary peer. */
604  if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
605    {
606      zlog_info ("%s [Event] Accepting BGP peer is deleted", peer->host);
607      peer_delete (peer);
608      return -1;
609    }
610
611  /* Clear start timer value to default. */
612  peer->v_start = BGP_INIT_START_TIMER;
613
614  /* bgp_stop needs to be invoked while in Established state */
615  bgp_stop(peer);
616
617  return 0;
618}
619
620
621/* TCP connection open.  Next we send open message to remote peer. And
622   add read thread for reading open message. */
623static int
624bgp_connect_success (struct peer *peer)
625{
626  if (peer->fd < 0)
627    {
628      zlog_err ("bgp_connect_success peer's fd is negative value %d",
629		peer->fd);
630      return -1;
631    }
632  BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
633
634  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
635    bgp_getsockname (peer);
636
637  if (BGP_DEBUG (normal, NORMAL))
638    {
639      char buf1[SU_ADDRSTRLEN];
640
641      if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
642	zlog_debug ("%s open active, local address %s", peer->host,
643		    sockunion2str (peer->su_local, buf1, SU_ADDRSTRLEN));
644      else
645	zlog_debug ("%s passive open", peer->host);
646    }
647
648  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
649    bgp_open_send (peer);
650
651  return 0;
652}
653
654/* TCP connect fail */
655static int
656bgp_connect_fail (struct peer *peer)
657{
658  bgp_stop (peer);
659  return 0;
660}
661
662/* This function is the first starting point of all BGP connection. It
663   try to connect to remote peer with non-blocking IO. */
664int
665bgp_start (struct peer *peer)
666{
667  int status;
668
669  if (BGP_PEER_START_SUPPRESSED (peer))
670    {
671      if (BGP_DEBUG (fsm, FSM))
672        plog_err (peer->log, "%s [FSM] Trying to start suppressed peer"
673                  " - this is never supposed to happen!", peer->host);
674      return -1;
675    }
676
677  /* Scrub some information that might be left over from a previous,
678   * session
679   */
680  /* Connection information. */
681  if (peer->su_local)
682    {
683      sockunion_free (peer->su_local);
684      peer->su_local = NULL;
685    }
686
687  if (peer->su_remote)
688    {
689      sockunion_free (peer->su_remote);
690      peer->su_remote = NULL;
691    }
692
693  /* Clear remote router-id. */
694  peer->remote_id.s_addr = 0;
695
696  /* Clear peer capability flag. */
697  peer->cap = 0;
698
699  /* If the peer is passive mode, force to move to Active mode. */
700  if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
701    {
702      BGP_EVENT_ADD (peer, TCP_connection_open_failed);
703      return 0;
704    }
705
706  status = bgp_connect (peer);
707
708  switch (status)
709    {
710    case connect_error:
711      if (BGP_DEBUG (fsm, FSM))
712	plog_debug (peer->log, "%s [FSM] Connect error", peer->host);
713      BGP_EVENT_ADD (peer, TCP_connection_open_failed);
714      break;
715    case connect_success:
716      if (BGP_DEBUG (fsm, FSM))
717	plog_debug (peer->log, "%s [FSM] Connect immediately success",
718		   peer->host);
719      BGP_EVENT_ADD (peer, TCP_connection_open);
720      break;
721    case connect_in_progress:
722      /* To check nonblocking connect, we wait until socket is
723         readable or writable. */
724      if (BGP_DEBUG (fsm, FSM))
725	plog_debug (peer->log, "%s [FSM] Non blocking connect waiting result",
726		   peer->host);
727      if (peer->fd < 0)
728	{
729	  zlog_err ("bgp_start peer's fd is negative value %d",
730		    peer->fd);
731	  return -1;
732	}
733      BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
734      BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
735      break;
736    }
737  return 0;
738}
739
740/* Connect retry timer is expired when the peer status is Connect. */
741static int
742bgp_reconnect (struct peer *peer)
743{
744  bgp_stop (peer);
745  bgp_start (peer);
746  return 0;
747}
748
749static int
750bgp_fsm_open (struct peer *peer)
751{
752  /* Send keepalive and make keepalive timer */
753  bgp_keepalive_send (peer);
754
755  /* Reset holdtimer value. */
756  BGP_TIMER_OFF (peer->t_holdtime);
757
758  return 0;
759}
760
761/* Keepalive send to peer. */
762static int
763bgp_fsm_keepalive_expire (struct peer *peer)
764{
765  bgp_keepalive_send (peer);
766  return 0;
767}
768
769/* FSM error, unexpected event.  This is error of BGP connection. So cut the
770   peer and change to Idle status. */
771static int
772bgp_fsm_event_error (struct peer *peer)
773{
774  plog_err (peer->log, "%s [FSM] unexpected packet received in state %s",
775	    peer->host, LOOKUP (bgp_status_msg, peer->status));
776
777  return bgp_stop_with_notify (peer, BGP_NOTIFY_FSM_ERR, 0);
778}
779
780/* Hold timer expire.  This is error of BGP connection. So cut the
781   peer and change to Idle status. */
782static int
783bgp_fsm_holdtime_expire (struct peer *peer)
784{
785  if (BGP_DEBUG (fsm, FSM))
786    plog_debug (peer->log, "%s [FSM] Hold timer expire", peer->host);
787
788  return bgp_stop_with_notify (peer, BGP_NOTIFY_HOLD_ERR, 0);
789}
790
791/* Status goes to Established.  Send keepalive packet then make first
792   update information. */
793static int
794bgp_establish (struct peer *peer)
795{
796  struct bgp_notify *notify;
797  afi_t afi;
798  safi_t safi;
799  int nsf_af_count = 0;
800
801  /* Reset capability open status flag. */
802  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
803    SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
804
805  /* Clear last notification data. */
806  notify = &peer->notify;
807  if (notify->data)
808    XFREE (MTYPE_TMP, notify->data);
809  memset (notify, 0, sizeof (struct bgp_notify));
810
811  /* Clear start timer value to default. */
812  peer->v_start = BGP_INIT_START_TIMER;
813
814  /* Increment established count. */
815  peer->established++;
816  bgp_fsm_change_status (peer, Established);
817
818  /* bgp log-neighbor-changes of neighbor Up */
819  if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
820    zlog_info ("%%ADJCHANGE: neighbor %s Up", peer->host);
821
822  /* graceful restart */
823  UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
824  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
825    for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
826      {
827	if (peer->afc_nego[afi][safi]
828	    && CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV)
829	    && CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV))
830	  {
831	    if (peer->nsf[afi][safi]
832		&& ! CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV))
833	      bgp_clear_stale_route (peer, afi, safi);
834
835	    peer->nsf[afi][safi] = 1;
836	    nsf_af_count++;
837	  }
838	else
839	  {
840	    if (peer->nsf[afi][safi])
841	      bgp_clear_stale_route (peer, afi, safi);
842	    peer->nsf[afi][safi] = 0;
843	  }
844      }
845
846  if (nsf_af_count)
847    SET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
848  else
849    {
850      UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
851      if (peer->t_gr_stale)
852	{
853	  BGP_TIMER_OFF (peer->t_gr_stale);
854	  if (BGP_DEBUG (events, EVENTS))
855	    zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
856	}
857    }
858
859  if (peer->t_gr_restart)
860    {
861      BGP_TIMER_OFF (peer->t_gr_restart);
862      if (BGP_DEBUG (events, EVENTS))
863	zlog_debug ("%s graceful restart timer stopped", peer->host);
864    }
865
866#ifdef HAVE_SNMP
867  bgpTrapEstablished (peer);
868#endif /* HAVE_SNMP */
869
870  /* Reset uptime, send keepalive, send current table. */
871  peer->uptime = bgp_clock ();
872
873  /* Send route-refresh when ORF is enabled */
874  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
875    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
876      if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV))
877	{
878	  if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
879	    bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX,
880				    REFRESH_IMMEDIATE, 0);
881	  else if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
882	    bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX_OLD,
883				    REFRESH_IMMEDIATE, 0);
884	}
885
886  if (peer->v_keepalive)
887    bgp_keepalive_send (peer);
888
889  /* First update is deferred until ORF or ROUTE-REFRESH is received */
890  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
891    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
892      if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV))
893	if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
894	    || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
895	  SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
896
897  bgp_announce_route_all (peer);
898
899  BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, 1);
900
901  return 0;
902}
903
904/* Keepalive packet is received. */
905static int
906bgp_fsm_keepalive (struct peer *peer)
907{
908  /* peer count update */
909  peer->keepalive_in++;
910
911  BGP_TIMER_OFF (peer->t_holdtime);
912  return 0;
913}
914
915/* Update packet is received. */
916static int
917bgp_fsm_update (struct peer *peer)
918{
919  BGP_TIMER_OFF (peer->t_holdtime);
920  return 0;
921}
922
923/* This is empty event. */
924static int
925bgp_ignore (struct peer *peer)
926{
927  if (BGP_DEBUG (fsm, FSM))
928    zlog (peer->log, LOG_DEBUG, "%s [FSM] bgp_ignore called", peer->host);
929  return 0;
930}
931
932/* Finite State Machine structure */
933static const struct {
934  int (*func) (struct peer *);
935  int next_state;
936} FSM [BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] =
937{
938  {
939    /* Idle state: In Idle state, all events other than BGP_Start is
940       ignored.  With BGP_Start event, finite state machine calls
941       bgp_start(). */
942    {bgp_start,  Connect},	/* BGP_Start                    */
943    {bgp_stop,   Idle},		/* BGP_Stop                     */
944    {bgp_stop,   Idle},		/* TCP_connection_open          */
945    {bgp_stop,   Idle},		/* TCP_connection_closed        */
946    {bgp_ignore, Idle},		/* TCP_connection_open_failed   */
947    {bgp_stop,   Idle},		/* TCP_fatal_error              */
948    {bgp_ignore, Idle},		/* ConnectRetry_timer_expired   */
949    {bgp_ignore, Idle},		/* Hold_Timer_expired           */
950    {bgp_ignore, Idle},		/* KeepAlive_timer_expired      */
951    {bgp_ignore, Idle},		/* Receive_OPEN_message         */
952    {bgp_ignore, Idle},		/* Receive_KEEPALIVE_message    */
953    {bgp_ignore, Idle},		/* Receive_UPDATE_message       */
954    {bgp_ignore, Idle},		/* Receive_NOTIFICATION_message */
955    {bgp_ignore, Idle},         /* Clearing_Completed           */
956  },
957  {
958    /* Connect */
959    {bgp_ignore,  Connect},	/* BGP_Start                    */
960    {bgp_stop,    Idle},	/* BGP_Stop                     */
961    {bgp_connect_success, OpenSent}, /* TCP_connection_open          */
962    {bgp_stop, Idle},		/* TCP_connection_closed        */
963    {bgp_connect_fail, Active}, /* TCP_connection_open_failed   */
964    {bgp_connect_fail, Idle},	/* TCP_fatal_error              */
965    {bgp_reconnect, Connect},	/* ConnectRetry_timer_expired   */
966    {bgp_ignore,  Idle},	/* Hold_Timer_expired           */
967    {bgp_ignore,  Idle},	/* KeepAlive_timer_expired      */
968    {bgp_ignore,  Idle},	/* Receive_OPEN_message         */
969    {bgp_ignore,  Idle},	/* Receive_KEEPALIVE_message    */
970    {bgp_ignore,  Idle},	/* Receive_UPDATE_message       */
971    {bgp_stop,    Idle},	/* Receive_NOTIFICATION_message */
972    {bgp_ignore,  Idle},         /* Clearing_Completed           */
973  },
974  {
975    /* Active, */
976    {bgp_ignore,  Active},	/* BGP_Start                    */
977    {bgp_stop,    Idle},	/* BGP_Stop                     */
978    {bgp_connect_success, OpenSent}, /* TCP_connection_open          */
979    {bgp_stop,    Idle},	/* TCP_connection_closed        */
980    {bgp_ignore,  Active},	/* TCP_connection_open_failed   */
981    {bgp_ignore,  Idle},	/* TCP_fatal_error              */
982    {bgp_start,   Connect},	/* ConnectRetry_timer_expired   */
983    {bgp_ignore,  Idle},	/* Hold_Timer_expired           */
984    {bgp_ignore,  Idle},	/* KeepAlive_timer_expired      */
985    {bgp_ignore,  Idle},	/* Receive_OPEN_message         */
986    {bgp_ignore,  Idle},	/* Receive_KEEPALIVE_message    */
987    {bgp_ignore,  Idle},	/* Receive_UPDATE_message       */
988    {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
989    {bgp_ignore, Idle},         /* Clearing_Completed           */
990  },
991  {
992    /* OpenSent, */
993    {bgp_ignore,  OpenSent},	/* BGP_Start                    */
994    {bgp_stop,    Idle},	/* BGP_Stop                     */
995    {bgp_stop,    Active},	/* TCP_connection_open          */
996    {bgp_stop,    Active},	/* TCP_connection_closed        */
997    {bgp_stop,    Active},	/* TCP_connection_open_failed   */
998    {bgp_stop,    Active},	/* TCP_fatal_error              */
999    {bgp_ignore,  Idle},	/* ConnectRetry_timer_expired   */
1000    {bgp_fsm_holdtime_expire, Idle},	/* Hold_Timer_expired           */
1001    {bgp_ignore,  Idle},	/* KeepAlive_timer_expired      */
1002    {bgp_fsm_open,    OpenConfirm},	/* Receive_OPEN_message         */
1003    {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message    */
1004    {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message       */
1005    {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
1006    {bgp_ignore, Idle},         /* Clearing_Completed           */
1007  },
1008  {
1009    /* OpenConfirm, */
1010    {bgp_ignore,  OpenConfirm},	/* BGP_Start                    */
1011    {bgp_stop,    Idle},	/* BGP_Stop                     */
1012    {bgp_stop,    Idle},	/* TCP_connection_open          */
1013    {bgp_stop,    Idle},	/* TCP_connection_closed        */
1014    {bgp_stop,    Idle},	/* TCP_connection_open_failed   */
1015    {bgp_stop,    Idle},	/* TCP_fatal_error              */
1016    {bgp_ignore,  Idle},	/* ConnectRetry_timer_expired   */
1017    {bgp_fsm_holdtime_expire, Idle},	/* Hold_Timer_expired           */
1018    {bgp_ignore,  OpenConfirm},	/* KeepAlive_timer_expired      */
1019    {bgp_ignore,  Idle},	/* Receive_OPEN_message         */
1020    {bgp_establish, Established}, /* Receive_KEEPALIVE_message    */
1021    {bgp_ignore,  Idle},	/* Receive_UPDATE_message       */
1022    {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
1023    {bgp_ignore, Idle},         /* Clearing_Completed           */
1024  },
1025  {
1026    /* Established, */
1027    {bgp_ignore,               Established}, /* BGP_Start                    */
1028    {bgp_stop,                    Clearing}, /* BGP_Stop                     */
1029    {bgp_stop,                    Clearing}, /* TCP_connection_open          */
1030    {bgp_stop,                    Clearing}, /* TCP_connection_closed        */
1031    {bgp_stop,                 Clearing},	/* TCP_connection_open_failed   */
1032    {bgp_stop,                    Clearing}, /* TCP_fatal_error              */
1033    {bgp_stop,                 Clearing},	/* ConnectRetry_timer_expired   */
1034    {bgp_fsm_holdtime_expire,     Clearing}, /* Hold_Timer_expired           */
1035    {bgp_fsm_keepalive_expire, Established}, /* KeepAlive_timer_expired      */
1036    {bgp_stop,                    Clearing}, /* Receive_OPEN_message         */
1037    {bgp_fsm_keepalive,        Established}, /* Receive_KEEPALIVE_message    */
1038    {bgp_fsm_update,           Established}, /* Receive_UPDATE_message       */
1039    {bgp_stop_with_error,         Clearing}, /* Receive_NOTIFICATION_message */
1040    {bgp_ignore,                      Idle}, /* Clearing_Completed           */
1041  },
1042  {
1043    /* Clearing, */
1044    {bgp_ignore,  Clearing},	/* BGP_Start                    */
1045    {bgp_stop,			Clearing},	/* BGP_Stop                     */
1046    {bgp_stop,			Clearing},	/* TCP_connection_open          */
1047    {bgp_stop,			Clearing},	/* TCP_connection_closed        */
1048    {bgp_stop,			Clearing},	/* TCP_connection_open_failed   */
1049    {bgp_stop,			Clearing},	/* TCP_fatal_error              */
1050    {bgp_stop,			Clearing},	/* ConnectRetry_timer_expired   */
1051    {bgp_stop,			Clearing},	/* Hold_Timer_expired           */
1052    {bgp_stop,			Clearing},	/* KeepAlive_timer_expired      */
1053    {bgp_stop,			Clearing},	/* Receive_OPEN_message         */
1054    {bgp_stop,			Clearing},	/* Receive_KEEPALIVE_message    */
1055    {bgp_stop,			Clearing},	/* Receive_UPDATE_message       */
1056    {bgp_stop,			Clearing},	/* Receive_NOTIFICATION_message */
1057    {bgp_clearing_completed,    Idle},		/* Clearing_Completed           */
1058  },
1059  {
1060    /* Deleted, */
1061    {bgp_ignore,  Deleted},	/* BGP_Start                    */
1062    {bgp_ignore,  Deleted},	/* BGP_Stop                     */
1063    {bgp_ignore,  Deleted},	/* TCP_connection_open          */
1064    {bgp_ignore,  Deleted},	/* TCP_connection_closed        */
1065    {bgp_ignore,  Deleted},	/* TCP_connection_open_failed   */
1066    {bgp_ignore,  Deleted},	/* TCP_fatal_error              */
1067    {bgp_ignore,  Deleted},	/* ConnectRetry_timer_expired   */
1068    {bgp_ignore,  Deleted},	/* Hold_Timer_expired           */
1069    {bgp_ignore,  Deleted},	/* KeepAlive_timer_expired      */
1070    {bgp_ignore,  Deleted},	/* Receive_OPEN_message         */
1071    {bgp_ignore,  Deleted},	/* Receive_KEEPALIVE_message    */
1072    {bgp_ignore,  Deleted},	/* Receive_UPDATE_message       */
1073    {bgp_ignore,  Deleted},	/* Receive_NOTIFICATION_message */
1074    {bgp_ignore,  Deleted},	/* Clearing_Completed           */
1075  },
1076};
1077
1078static const char *bgp_event_str[] =
1079{
1080  NULL,
1081  "BGP_Start",
1082  "BGP_Stop",
1083  "TCP_connection_open",
1084  "TCP_connection_closed",
1085  "TCP_connection_open_failed",
1086  "TCP_fatal_error",
1087  "ConnectRetry_timer_expired",
1088  "Hold_Timer_expired",
1089  "KeepAlive_timer_expired",
1090  "Receive_OPEN_message",
1091  "Receive_KEEPALIVE_message",
1092  "Receive_UPDATE_message",
1093  "Receive_NOTIFICATION_message",
1094  "Clearing_Completed",
1095};
1096
1097/* Execute event process. */
1098int
1099bgp_event (struct thread *thread)
1100{
1101  int ret = 0;
1102  int event;
1103  int next;
1104  struct peer *peer;
1105
1106  peer = THREAD_ARG (thread);
1107  event = THREAD_VAL (thread);
1108
1109  /* Logging this event. */
1110  next = FSM [peer->status -1][event - 1].next_state;
1111
1112  if (BGP_DEBUG (fsm, FSM) && peer->status != next)
1113    plog_debug (peer->log, "%s [FSM] %s (%s->%s)", peer->host,
1114	       bgp_event_str[event],
1115	       LOOKUP (bgp_status_msg, peer->status),
1116	       LOOKUP (bgp_status_msg, next));
1117
1118  /* Call function. */
1119  if (FSM [peer->status -1][event - 1].func)
1120    ret = (*(FSM [peer->status - 1][event - 1].func))(peer);
1121
1122  /* When function do not want proceed next job return -1. */
1123  if (ret >= 0)
1124    {
1125      /* If status is changed. */
1126      if (next != peer->status)
1127        bgp_fsm_change_status (peer, next);
1128
1129      /* Make sure timer is set. */
1130      bgp_timer_set (peer);
1131    }
1132
1133  return ret;
1134}
1135