added files
[bcm963xx.git] / userapps / opensource / zebra / bgpd / bgp_fsm.c
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
5 This file is part of GNU Zebra.
6
7 GNU Zebra is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 GNU Zebra is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Zebra; see the file COPYING.  If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-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 \f
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. */
53 int bgp_event (struct thread *);
54
55 /* BGP thread functions. */
56 static int bgp_start_timer (struct thread *);
57 static int bgp_connect_timer (struct thread *);
58 static int bgp_holdtime_timer (struct thread *);
59 static int bgp_keepalive_timer (struct thread *);
60
61 /* BGP FSM functions. */
62 static int bgp_start (struct peer *);
63
64 /* BGP start timer jitter. */
65 int
66 bgp_start_jitter (int time)
67 {
68   return ((rand () % (time + 1)) - (time / 2));
69 }
70
71 /* Hook function called after bgp event is occered.  And vty's
72    neighbor command invoke this function after making neighbor
73    structure. */
74 void
75 bgp_timer_set (struct peer *peer)
76 {
77   int jitter = 0;
78
79   switch (peer->status)
80     {
81     case Idle:
82       /* First entry point of peer's finite state machine.  In Idle
83          status start timer is on unless peer is shutdown or peer is
84          inactive.  All other timer must be turned off */
85       if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN)
86           || CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)
87           || ! peer_active (peer))
88         {
89           BGP_TIMER_OFF (peer->t_start);
90         }
91       else
92         {
93           jitter = bgp_start_jitter (peer->v_start);
94           BGP_TIMER_ON (peer->t_start, bgp_start_timer,
95                         peer->v_start + jitter);
96         }
97       BGP_TIMER_OFF (peer->t_connect);
98       BGP_TIMER_OFF (peer->t_holdtime);
99       BGP_TIMER_OFF (peer->t_keepalive);
100       BGP_TIMER_OFF (peer->t_asorig);
101       BGP_TIMER_OFF (peer->t_routeadv);
102       break;
103
104     case Connect:
105       /* After start timer is expired, the peer moves to Connnect
106          status.  Make sure start timer is off and connect timer is
107          on. */
108       BGP_TIMER_OFF (peer->t_start);
109       BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
110       BGP_TIMER_OFF (peer->t_holdtime);
111       BGP_TIMER_OFF (peer->t_keepalive);
112       BGP_TIMER_OFF (peer->t_asorig);
113       BGP_TIMER_OFF (peer->t_routeadv);
114       break;
115
116     case Active:
117       /* Active is waiting connection from remote peer.  And if
118          connect timer is expired, change status to Connect. */
119       BGP_TIMER_OFF (peer->t_start);
120       /* If peer is passive mode, do not set connect timer. */
121       if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
122         {
123           BGP_TIMER_OFF (peer->t_connect);
124         }
125       else
126         {
127           BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
128         }
129       BGP_TIMER_OFF (peer->t_holdtime);
130       BGP_TIMER_OFF (peer->t_keepalive);
131       BGP_TIMER_OFF (peer->t_asorig);
132       BGP_TIMER_OFF (peer->t_routeadv);
133       break;
134
135     case OpenSent:
136       /* OpenSent status. */
137       BGP_TIMER_OFF (peer->t_start);
138       BGP_TIMER_OFF (peer->t_connect);
139       if (peer->v_holdtime != 0)
140         {
141           BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer, 
142                         peer->v_holdtime);
143         }
144       else
145         {
146           BGP_TIMER_OFF (peer->t_holdtime);
147         }
148       BGP_TIMER_OFF (peer->t_keepalive);
149       BGP_TIMER_OFF (peer->t_asorig);
150       BGP_TIMER_OFF (peer->t_routeadv);
151       break;
152
153     case OpenConfirm:
154       /* OpenConfirm status. */
155       BGP_TIMER_OFF (peer->t_start);
156       BGP_TIMER_OFF (peer->t_connect);
157
158       /* If the negotiated Hold Time value is zero, then the Hold Time
159          timer and KeepAlive timers are not started. */
160       if (peer->v_holdtime == 0)
161         {
162           BGP_TIMER_OFF (peer->t_holdtime);
163           BGP_TIMER_OFF (peer->t_keepalive);
164         }
165       else
166         {
167           BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
168                         peer->v_holdtime);
169           BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer, 
170                         peer->v_keepalive);
171         }
172       BGP_TIMER_OFF (peer->t_asorig);
173       BGP_TIMER_OFF (peer->t_routeadv);
174       break;
175
176     case Established:
177       /* In Established status start and connect timer is turned
178          off. */
179       BGP_TIMER_OFF (peer->t_start);
180       BGP_TIMER_OFF (peer->t_connect);
181
182       /* Same as OpenConfirm, if holdtime is zero then both holdtime
183          and keepalive must be turned off. */
184       if (peer->v_holdtime == 0)
185         {
186           BGP_TIMER_OFF (peer->t_holdtime);
187           BGP_TIMER_OFF (peer->t_keepalive);
188         }
189       else
190         {
191           BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
192                         peer->v_holdtime);
193           BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
194                         peer->v_keepalive);
195         }
196       BGP_TIMER_OFF (peer->t_asorig);
197       break;
198     }
199 }
200
201 /* BGP start timer.  This function set BGP_Start event to thread value
202    and process event. */
203 static int
204 bgp_start_timer (struct thread *thread)
205 {
206   struct peer *peer;
207
208   peer = THREAD_ARG (thread);
209   peer->t_start = NULL;
210
211   if (BGP_DEBUG (fsm, FSM))
212     zlog (peer->log, LOG_DEBUG,
213           "%s [FSM] Timer (start timer expire).", peer->host);
214
215   THREAD_VAL (thread) = BGP_Start;
216   bgp_event (thread);
217
218   return 0;
219 }
220
221 /* BGP connect retry timer. */
222 static int
223 bgp_connect_timer (struct thread *thread)
224 {
225   struct peer *peer;
226
227   peer = THREAD_ARG (thread);
228   peer->t_connect = NULL;
229
230   if (BGP_DEBUG (fsm, FSM))
231     zlog (peer->log, LOG_DEBUG, "%s [FSM] Timer (connect timer expire)",
232           peer->host);
233
234   THREAD_VAL (thread) = ConnectRetry_timer_expired;
235   bgp_event (thread);
236
237   return 0;
238 }
239
240 /* BGP holdtime timer. */
241 static int
242 bgp_holdtime_timer (struct thread *thread)
243 {
244   struct peer *peer;
245
246   peer = THREAD_ARG (thread);
247   peer->t_holdtime = NULL;
248
249   if (BGP_DEBUG (fsm, FSM))
250     zlog (peer->log, LOG_DEBUG,
251           "%s [FSM] Timer (holdtime timer expire)",
252           peer->host);
253
254   THREAD_VAL (thread) = Hold_Timer_expired;
255   bgp_event (thread);
256
257   return 0;
258 }
259
260 /* BGP keepalive fire ! */
261 static int
262 bgp_keepalive_timer (struct thread *thread)
263 {
264   struct peer *peer;
265
266   peer = THREAD_ARG (thread);
267   peer->t_keepalive = NULL;
268
269   if (BGP_DEBUG (fsm, FSM))
270     zlog (peer->log, LOG_DEBUG,
271           "%s [FSM] Timer (keepalive timer expire)",
272           peer->host);
273
274   THREAD_VAL (thread) = KeepAlive_timer_expired;
275   bgp_event (thread);
276
277   return 0;
278 }
279
280 int
281 bgp_routeadv_timer (struct thread *thread)
282 {
283   struct peer *peer;
284
285   peer = THREAD_ARG (thread);
286   peer->t_routeadv = NULL;
287
288   if (BGP_DEBUG (fsm, FSM))
289     zlog (peer->log, LOG_DEBUG,
290           "%s [FSM] Timer (routeadv timer expire)",
291           peer->host);
292
293   peer->synctime = time (NULL);
294
295   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
296
297   BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer,
298                 peer->v_routeadv);
299
300   return 0;
301 }
302
303 /* Reset bgp update timer */
304 static void
305 bgp_uptime_reset (struct peer *peer)
306 {
307   peer->uptime = time (NULL);
308 }
309
310 /* Administrative BGP peer stop event. */
311 int
312 bgp_stop (struct peer *peer)
313 {
314   int established = 0;
315   afi_t afi;
316   safi_t safi;
317   char orf_name[BUFSIZ];
318
319   /* Increment Dropped count. */
320   if (peer->status == Established)
321     {
322       established = 1;
323       peer->dropped++;
324       bgp_fsm_change_status (peer, Idle);
325 #ifdef HAVE_SNMP
326       bgpTrapBackwardTransition (peer);
327 #endif /* HAVE_SNMP */
328     }
329
330   /* Reset uptime. */
331   bgp_uptime_reset (peer);
332
333   /* Need of clear of peer. */
334   if (established)
335     bgp_clear_route_all (peer);
336
337   /* Stop read and write threads when exists. */
338   BGP_READ_OFF (peer->t_read);
339   BGP_WRITE_OFF (peer->t_write);
340
341   /* Stop all timers. */
342   BGP_TIMER_OFF (peer->t_start);
343   BGP_TIMER_OFF (peer->t_connect);
344   BGP_TIMER_OFF (peer->t_holdtime);
345   BGP_TIMER_OFF (peer->t_keepalive);
346   BGP_TIMER_OFF (peer->t_asorig);
347   BGP_TIMER_OFF (peer->t_routeadv);
348
349   /* Delete all existing events of the peer. */
350   BGP_EVENT_DELETE (peer);
351
352   /* Stream reset. */
353   peer->packet_size = 0;
354
355   /* Clear input and output buffer.  */
356   if (peer->ibuf)
357     stream_reset (peer->ibuf);
358   if (peer->work)
359     stream_reset (peer->work);
360   stream_fifo_clean (peer->obuf);
361
362   /* Close of file descriptor. */
363   if (peer->fd >= 0)
364     {
365       close (peer->fd);
366       peer->fd = -1;
367     }
368
369   /* Connection information. */
370   if (peer->su_local)
371     {
372       XFREE (MTYPE_SOCKUNION, peer->su_local);
373       peer->su_local = NULL;
374     }
375
376   if (peer->su_remote)
377     {
378       XFREE (MTYPE_SOCKUNION, peer->su_remote);
379       peer->su_remote = NULL;
380     }
381
382   /* Clear remote router-id. */
383   peer->remote_id.s_addr = 0;
384
385   /* Reset all negotiated variables */
386   peer->afc_nego[AFI_IP][SAFI_UNICAST] = 0;
387   peer->afc_nego[AFI_IP][SAFI_MULTICAST] = 0;
388   peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] = 0;
389   peer->afc_nego[AFI_IP6][SAFI_UNICAST] = 0;
390   peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = 0;
391   peer->afc_adv[AFI_IP][SAFI_UNICAST] = 0;
392   peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 0;
393   peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 0;
394   peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 0;
395   peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 0;
396   peer->afc_recv[AFI_IP][SAFI_UNICAST] = 0;
397   peer->afc_recv[AFI_IP][SAFI_MULTICAST] = 0;
398   peer->afc_recv[AFI_IP][SAFI_MPLS_VPN] = 0;
399   peer->afc_recv[AFI_IP6][SAFI_UNICAST] = 0;
400   peer->afc_recv[AFI_IP6][SAFI_MULTICAST] = 0;
401
402   /* Reset route refresh flag. */
403   UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
404   UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
405   UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
406   UNSET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
407   UNSET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
408
409   for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
410     for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
411       {
412         /* peer address family capability flags*/
413         peer->af_cap[afi][safi] = 0;
414         /* peer address family status flags*/
415         peer->af_sflags[afi][safi] = 0;
416         /* Received ORF prefix-filter */
417         peer->orf_plist[afi][safi] = NULL;
418         /* ORF received prefix-filter pnt */
419         sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
420         prefix_bgp_orf_remove_all (orf_name);
421       }
422
423   UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
424               PEER_FLAG_DEFAULT_ORIGINATE_CHECK);
425   UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
426               PEER_FLAG_DEFAULT_ORIGINATE_CHECK);
427   UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],
428               PEER_FLAG_DEFAULT_ORIGINATE_CHECK);
429   UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST],
430               PEER_FLAG_DEFAULT_ORIGINATE_CHECK);
431
432   /* Reset keepalive and holdtime */
433   if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
434     {
435       peer->v_keepalive = peer->keepalive;
436       peer->v_holdtime = peer->holdtime;
437     }
438   else
439     {
440       peer->v_keepalive = peer->bgp->default_keepalive;
441       peer->v_holdtime = peer->bgp->default_holdtime;
442     }
443
444   peer->update_time = 0;
445
446   /* Until we are sure that there is no problem about prefix count
447      this should be commented out.*/
448 #if 0
449   /* Reset prefix count */
450   peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
451   peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
452   peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
453   peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
454   peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
455 #endif /* 0 */
456
457   return 0;
458 }
459
460 /* BGP peer is stoped by the error. */
461 int
462 bgp_stop_with_error (struct peer *peer)
463 {
464   /* Double start timer. */
465   peer->v_start *= 2;
466
467   /* Overflow check. */
468   if (peer->v_start >= (60 * 2))
469     peer->v_start = (60 * 2);
470
471   bgp_stop (peer);
472
473   return 0;
474 }
475
476 /* TCP connection open.  Next we send open message to remote peer. And
477    add read thread for reading open message. */
478 int
479 bgp_connect_success (struct peer *peer)
480 {
481   if (peer->fd < 0)
482     {
483       zlog_err ("bgp_connect_success peer's fd is negative value %d",
484                 peer->fd);
485       return -1;
486     }
487   BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
488
489   /* bgp_getsockname (peer); */
490
491   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
492     bgp_open_send (peer);
493
494   return 0;
495 }
496
497 /* TCP connect fail */
498 int
499 bgp_connect_fail (struct peer *peer)
500 {
501   bgp_stop (peer);
502   return 0;
503 }
504
505 /* This function is the first starting point of all BGP connection. It
506    try to connect to remote peer with non-blocking IO. */
507 int
508 bgp_start (struct peer *peer)
509 {
510   int status;
511
512   /* If the peer is passive mode, force to move to Active mode. */
513   if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
514     {
515       BGP_EVENT_ADD (peer, TCP_connection_open_failed);
516       return 0;
517     }
518
519   status = bgp_connect (peer);
520
521   switch (status)
522     {
523     case connect_error:
524       if (BGP_DEBUG (fsm, FSM))
525         plog_info (peer->log, "%s [FSM] Connect error", peer->host);
526       BGP_EVENT_ADD (peer, TCP_connection_open_failed);
527       break;
528     case connect_success:
529       if (BGP_DEBUG (fsm, FSM))
530         plog_info (peer->log, "%s [FSM] Connect immediately success",
531                    peer->host);
532       BGP_EVENT_ADD (peer, TCP_connection_open);
533       break;
534     case connect_in_progress:
535       /* To check nonblocking connect, we wait until socket is
536          readable or writable. */
537       if (BGP_DEBUG (fsm, FSM))
538         plog_info (peer->log, "%s [FSM] Non blocking connect waiting result",
539                    peer->host);
540       if (peer->fd < 0)
541         {
542           zlog_err ("bgp_start peer's fd is negative value %d",
543                     peer->fd);
544           return -1;
545         }
546       BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
547       BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
548       break;
549     }
550   return 0;
551 }
552
553 /* Connect retry timer is expired when the peer status is Connect. */
554 int
555 bgp_reconnect (struct peer *peer)
556 {
557   bgp_stop (peer);
558   bgp_start (peer);
559   return 0;
560 }
561
562 int
563 bgp_fsm_open (struct peer *peer)
564 {
565   /* Send keepalive and make keepalive timer */
566   bgp_keepalive_send (peer);
567
568   /* Reset holdtimer value. */
569   BGP_TIMER_OFF (peer->t_holdtime);
570
571   return 0;
572 }
573
574 /* Called after event occured, this function change status and reset
575    read/write and timer thread. */
576 void
577 bgp_fsm_change_status (struct peer *peer, int status)
578 {
579   bgp_dump_state (peer, peer->status, status);
580
581   /* Preserve old status and change into new status. */
582   peer->ostatus = peer->status;
583   peer->status = status;
584 }
585
586 /* Keepalive send to peer. */
587 int
588 bgp_fsm_keepalive_expire (struct peer *peer)
589 {
590   bgp_keepalive_send (peer);
591   return 0;
592 }
593
594 /* Hold timer expire.  This is error of BGP connection. So cut the
595    peer and change to Idle status. */
596 int
597 bgp_fsm_holdtime_expire (struct peer *peer)
598 {
599   if (BGP_DEBUG (fsm, FSM))
600     zlog (peer->log, LOG_DEBUG, "%s [FSM] Hold timer expire", peer->host);
601
602   /* Send notify to remote peer. */
603   bgp_notify_send (peer, BGP_NOTIFY_HOLD_ERR, 0);
604
605   /* Sweep if it is temporary peer. */
606   if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
607     {
608       zlog_info ("%s [Event] Accepting BGP peer is deleted", peer->host);
609       peer_delete (peer);
610       return -1;
611     }
612
613   return 0;
614 }
615
616 /* Status goes to Established.  Send keepalive packet then make first
617    update information. */
618 int
619 bgp_establish (struct peer *peer)
620 {
621   struct bgp_notify *notify;
622   afi_t afi;
623   safi_t safi;
624
625   /* Reset capability open status flag. */
626   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
627     SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
628
629   /* Clear last notification data. */
630   notify = &peer->notify;
631   if (notify->data)
632     XFREE (MTYPE_TMP, notify->data);
633   memset (notify, 0, sizeof (struct bgp_notify));
634
635   /* Clear start timer value to default. */
636   peer->v_start = BGP_INIT_START_TIMER;
637
638   /* Increment established count. */
639   peer->established++;
640   bgp_fsm_change_status (peer, Established);
641 #ifdef HAVE_SNMP
642   bgpTrapEstablished (peer);
643 #endif /* HAVE_SNMP */
644
645   /* Reset uptime, send keepalive, send current table. */
646   bgp_uptime_reset (peer);
647
648   /* Send route-refresh when ORF is enabled */
649   for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
650     for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
651       if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV))
652         {
653           if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
654             bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX,
655                                     REFRESH_IMMEDIATE, 0);
656           else if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
657             bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX_OLD,
658                                     REFRESH_IMMEDIATE, 0);
659         }
660
661   if (peer->v_keepalive)
662     bgp_keepalive_send (peer);
663
664   /* First update is deferred until ORF or ROUTE-REFRESH is received */
665   for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
666     for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
667       if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV))
668         if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
669             || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
670           SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
671
672   bgp_announce_route_all (peer);
673
674   BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, 1);
675
676   return 0;
677 }
678
679 /* Keepalive packet is received. */
680 int
681 bgp_fsm_keepalive (struct peer *peer)
682 {
683   /* peer count update */
684   peer->keepalive_in++;
685
686   BGP_TIMER_OFF (peer->t_holdtime);
687   return 0;
688 }
689
690 /* Update packet is received. */
691 int
692 bgp_fsm_update (struct peer *peer)
693 {
694   BGP_TIMER_OFF (peer->t_holdtime);
695   return 0;
696 }
697
698 /* This is empty event. */
699 int
700 bgp_ignore (struct peer *peer)
701 {
702   if (BGP_DEBUG (fsm, FSM))
703     zlog (peer->log, LOG_DEBUG, "%s [FSM] bgp_ignore called", peer->host);
704   return 0;
705 }
706 \f
707 /* Finite State Machine structure */
708 struct {
709   int (*func) ();
710   int next_state;
711 } FSM [BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] = 
712 {
713   {
714     /* Idle state: In Idle state, all events other than BGP_Start is
715        ignored.  With BGP_Start event, finite state machine calls
716        bgp_start(). */
717     {bgp_start,  Connect},      /* BGP_Start                    */
718     {bgp_stop,   Idle},         /* BGP_Stop                     */
719     {bgp_stop,   Idle},         /* TCP_connection_open          */
720     {bgp_stop,   Idle},         /* TCP_connection_closed        */
721     {bgp_ignore, Idle},         /* TCP_connection_open_failed   */
722     {bgp_stop,   Idle},         /* TCP_fatal_error              */
723     {bgp_ignore, Idle},         /* ConnectRetry_timer_expired   */
724     {bgp_ignore, Idle},         /* Hold_Timer_expired           */
725     {bgp_ignore, Idle},         /* KeepAlive_timer_expired      */
726     {bgp_ignore, Idle},         /* Receive_OPEN_message         */
727     {bgp_ignore, Idle},         /* Receive_KEEPALIVE_message    */
728     {bgp_ignore, Idle},         /* Receive_UPDATE_message       */
729     {bgp_ignore, Idle},         /* Receive_NOTIFICATION_message */
730   },
731   {
732     /* Connect */
733     {bgp_ignore,  Connect},     /* BGP_Start                    */
734     {bgp_stop,    Idle},        /* BGP_Stop                     */
735     {bgp_connect_success, OpenSent}, /* TCP_connection_open          */
736     {bgp_stop, Idle},           /* TCP_connection_closed        */
737     {bgp_connect_fail, Active}, /* TCP_connection_open_failed   */
738     {bgp_connect_fail, Idle},   /* TCP_fatal_error              */
739     {bgp_reconnect, Connect},   /* ConnectRetry_timer_expired   */
740     {bgp_ignore,  Idle},        /* Hold_Timer_expired           */
741     {bgp_ignore,  Idle},        /* KeepAlive_timer_expired      */
742     {bgp_ignore,  Idle},        /* Receive_OPEN_message         */
743     {bgp_ignore,  Idle},        /* Receive_KEEPALIVE_message    */
744     {bgp_ignore,  Idle},        /* Receive_UPDATE_message       */
745     {bgp_stop,    Idle},        /* Receive_NOTIFICATION_message */
746   },
747   {
748     /* Active, */
749     {bgp_ignore,  Active},      /* BGP_Start                    */
750     {bgp_stop,    Idle},        /* BGP_Stop                     */
751     {bgp_connect_success, OpenSent}, /* TCP_connection_open          */
752     {bgp_stop,    Idle},        /* TCP_connection_closed        */
753     {bgp_ignore,  Active},      /* TCP_connection_open_failed   */
754     {bgp_ignore,  Idle},        /* TCP_fatal_error              */
755     {bgp_start,   Connect},     /* ConnectRetry_timer_expired   */
756     {bgp_ignore,  Idle},        /* Hold_Timer_expired           */
757     {bgp_ignore,  Idle},        /* KeepAlive_timer_expired      */
758     {bgp_ignore,  Idle},        /* Receive_OPEN_message         */
759     {bgp_ignore,  Idle},        /* Receive_KEEPALIVE_message    */
760     {bgp_ignore,  Idle},        /* Receive_UPDATE_message       */
761     {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
762   },
763   {
764     /* OpenSent, */
765     {bgp_ignore,  OpenSent},    /* BGP_Start                    */
766     {bgp_stop,    Idle},        /* BGP_Stop                     */
767     {bgp_stop,    Idle},        /* TCP_connection_open          */
768     {bgp_stop,    Active},      /* TCP_connection_closed        */
769     {bgp_ignore,  Idle},        /* TCP_connection_open_failed   */
770     {bgp_stop,    Idle},        /* TCP_fatal_error              */
771     {bgp_ignore,  Idle},        /* ConnectRetry_timer_expired   */
772     {bgp_fsm_holdtime_expire, Idle},    /* Hold_Timer_expired           */
773     {bgp_ignore,  Idle},        /* KeepAlive_timer_expired      */
774     {bgp_fsm_open,    OpenConfirm},     /* Receive_OPEN_message         */
775     {bgp_ignore,  Idle},        /* Receive_KEEPALIVE_message    */
776     {bgp_ignore,  Idle},        /* Receive_UPDATE_message       */
777     {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
778   },
779   {
780     /* OpenConfirm, */
781     {bgp_ignore,  OpenConfirm}, /* BGP_Start                    */
782     {bgp_stop,    Idle},        /* BGP_Stop                     */
783     {bgp_stop,    Idle},        /* TCP_connection_open          */
784     {bgp_stop,    Idle},        /* TCP_connection_closed        */
785     {bgp_stop,    Idle},        /* TCP_connection_open_failed   */
786     {bgp_stop,    Idle},        /* TCP_fatal_error              */
787     {bgp_ignore,  Idle},        /* ConnectRetry_timer_expired   */
788     {bgp_fsm_holdtime_expire, Idle},    /* Hold_Timer_expired           */
789     {bgp_ignore,  OpenConfirm}, /* KeepAlive_timer_expired      */
790     {bgp_ignore,  Idle},        /* Receive_OPEN_message         */
791     {bgp_establish, Established}, /* Receive_KEEPALIVE_message    */
792     {bgp_ignore,  Idle},        /* Receive_UPDATE_message       */
793     {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
794   },
795   {
796     /* Established, */
797     {bgp_ignore,  Established}, /* BGP_Start                    */
798     {bgp_stop,    Idle},        /* BGP_Stop                     */
799     {bgp_stop,    Idle},        /* TCP_connection_open          */
800     {bgp_stop,    Idle},        /* TCP_connection_closed        */
801     {bgp_ignore,  Idle},        /* TCP_connection_open_failed   */
802     {bgp_stop,    Idle},        /* TCP_fatal_error              */
803     {bgp_ignore,  Idle},        /* ConnectRetry_timer_expired   */
804     {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired           */
805     {bgp_fsm_keepalive_expire, Established}, /* KeepAlive_timer_expired      */
806     {bgp_stop, Idle},           /* Receive_OPEN_message         */
807     {bgp_fsm_keepalive, Established}, /* Receive_KEEPALIVE_message    */
808     {bgp_fsm_update,   Established}, /* Receive_UPDATE_message       */
809     {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
810   },
811 };
812
813 static char *bgp_event_str[] =
814 {
815   NULL,
816   "BGP_Start",
817   "BGP_Stop",
818   "TCP_connection_open",
819   "TCP_connection_closed",
820   "TCP_connection_open_failed",
821   "TCP_fatal_error",
822   "ConnectRetry_timer_expired",
823   "Hold_Timer_expired",
824   "KeepAlive_timer_expired",
825   "Receive_OPEN_message",
826   "Receive_KEEPALIVE_message",
827   "Receive_UPDATE_message",
828   "Receive_NOTIFICATION_message"
829 };
830
831 /* Execute event process. */
832 int
833 bgp_event (struct thread *thread)
834 {
835   int ret;
836   int event;
837   int next;
838   struct peer *peer;
839
840   peer = THREAD_ARG (thread);
841   event = THREAD_VAL (thread);
842
843   /* Logging this event. */
844   next = FSM [peer->status -1][event - 1].next_state;
845
846   if (BGP_DEBUG (fsm, FSM))
847     plog_info (peer->log, "%s [FSM] %s (%s->%s)", peer->host, 
848                bgp_event_str[event],
849                LOOKUP (bgp_status_msg, peer->status),
850                LOOKUP (bgp_status_msg, next));
851   if (BGP_DEBUG (normal, NORMAL)
852       && strcmp (LOOKUP (bgp_status_msg, peer->status), LOOKUP (bgp_status_msg, next)))
853     zlog_info ("%s went from %s to %s",
854                peer->host,
855                LOOKUP (bgp_status_msg, peer->status),
856                LOOKUP (bgp_status_msg, next));
857
858   /* Call function. */
859   ret = (*(FSM [peer->status - 1][event - 1].func))(peer);
860
861   /* When function do not want proceed next job return -1. */
862   if (ret < 0)
863     return ret;
864     
865   /* If status is changed. */
866   if (next != peer->status)
867     bgp_fsm_change_status (peer, next);
868
869   /* Make sure timer is set. */
870   bgp_timer_set (peer);
871
872   return 0;
873 }