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