Annotation of embedaddon/quagga/bgpd/bgp_fsm.c, revision 1.1.1.3
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"
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. */
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: static int
66: bgp_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. */
79: void
80: bgp_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. */
218: static int
219: bgp_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. */
237: static int
238: bgp_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. */
256: static int
257: bgp_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 ! */
276: static int
277: bgp_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:
295: static int
296: bgp_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 */
319: const 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:
346: static int
347: bgp_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++)
1.1.1.2 misho 358: for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
1.1 misho 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:
376: static int
377: bgp_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++)
1.1.1.2 misho 391: for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
1.1 misho 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. */
400: void
401: bgp_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 */
423: static int
424: bgp_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 */
434: int
435: bgp_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++)
1.1.1.2 misho 484: for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
1.1 misho 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. */
580: static int
581: bgp_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: /* TCP connection open. Next we send open message to remote peer. And
596: add read thread for reading open message. */
597: static int
598: bgp_connect_success (struct peer *peer)
599: {
600: if (peer->fd < 0)
601: {
602: zlog_err ("bgp_connect_success peer's fd is negative value %d",
603: peer->fd);
604: return -1;
605: }
606: BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
607:
608: if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
609: bgp_getsockname (peer);
610:
611: if (BGP_DEBUG (normal, NORMAL))
612: {
1.1.1.3 ! misho 613: char buf1[SU_ADDRSTRLEN];
! 614:
1.1 misho 615: if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
616: zlog_debug ("%s open active, local address %s", peer->host,
617: sockunion2str (peer->su_local, buf1, SU_ADDRSTRLEN));
618: else
619: zlog_debug ("%s passive open", peer->host);
620: }
621:
622: if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
623: bgp_open_send (peer);
624:
625: return 0;
626: }
627:
628: /* TCP connect fail */
629: static int
630: bgp_connect_fail (struct peer *peer)
631: {
632: bgp_stop (peer);
633: return 0;
634: }
635:
636: /* This function is the first starting point of all BGP connection. It
637: try to connect to remote peer with non-blocking IO. */
638: int
639: bgp_start (struct peer *peer)
640: {
641: int status;
642:
643: if (BGP_PEER_START_SUPPRESSED (peer))
644: {
645: if (BGP_DEBUG (fsm, FSM))
646: plog_err (peer->log, "%s [FSM] Trying to start suppressed peer"
647: " - this is never supposed to happen!", peer->host);
648: return -1;
649: }
650:
651: /* Scrub some information that might be left over from a previous,
652: * session
653: */
654: /* Connection information. */
655: if (peer->su_local)
656: {
657: sockunion_free (peer->su_local);
658: peer->su_local = NULL;
659: }
660:
661: if (peer->su_remote)
662: {
663: sockunion_free (peer->su_remote);
664: peer->su_remote = NULL;
665: }
666:
667: /* Clear remote router-id. */
668: peer->remote_id.s_addr = 0;
669:
670: /* Clear peer capability flag. */
671: peer->cap = 0;
672:
673: /* If the peer is passive mode, force to move to Active mode. */
674: if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
675: {
676: BGP_EVENT_ADD (peer, TCP_connection_open_failed);
677: return 0;
678: }
679:
680: status = bgp_connect (peer);
681:
682: switch (status)
683: {
684: case connect_error:
685: if (BGP_DEBUG (fsm, FSM))
686: plog_debug (peer->log, "%s [FSM] Connect error", peer->host);
687: BGP_EVENT_ADD (peer, TCP_connection_open_failed);
688: break;
689: case connect_success:
690: if (BGP_DEBUG (fsm, FSM))
691: plog_debug (peer->log, "%s [FSM] Connect immediately success",
692: peer->host);
693: BGP_EVENT_ADD (peer, TCP_connection_open);
694: break;
695: case connect_in_progress:
696: /* To check nonblocking connect, we wait until socket is
697: readable or writable. */
698: if (BGP_DEBUG (fsm, FSM))
699: plog_debug (peer->log, "%s [FSM] Non blocking connect waiting result",
700: peer->host);
701: if (peer->fd < 0)
702: {
703: zlog_err ("bgp_start peer's fd is negative value %d",
704: peer->fd);
705: return -1;
706: }
707: BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
708: BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
709: break;
710: }
711: return 0;
712: }
713:
714: /* Connect retry timer is expired when the peer status is Connect. */
715: static int
716: bgp_reconnect (struct peer *peer)
717: {
718: bgp_stop (peer);
719: bgp_start (peer);
720: return 0;
721: }
722:
723: static int
724: bgp_fsm_open (struct peer *peer)
725: {
726: /* Send keepalive and make keepalive timer */
727: bgp_keepalive_send (peer);
728:
729: /* Reset holdtimer value. */
730: BGP_TIMER_OFF (peer->t_holdtime);
731:
732: return 0;
733: }
734:
735: /* Keepalive send to peer. */
736: static int
737: bgp_fsm_keepalive_expire (struct peer *peer)
738: {
739: bgp_keepalive_send (peer);
740: return 0;
741: }
742:
743: /* Hold timer expire. This is error of BGP connection. So cut the
744: peer and change to Idle status. */
745: static int
746: bgp_fsm_holdtime_expire (struct peer *peer)
747: {
748: if (BGP_DEBUG (fsm, FSM))
749: zlog (peer->log, LOG_DEBUG, "%s [FSM] Hold timer expire", peer->host);
750:
751: /* Send notify to remote peer. */
752: bgp_notify_send (peer, BGP_NOTIFY_HOLD_ERR, 0);
753:
754: /* Sweep if it is temporary peer. */
755: if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
756: {
757: zlog_info ("%s [Event] Accepting BGP peer is deleted", peer->host);
758: peer_delete (peer);
759: return -1;
760: }
761:
762: /* bgp_stop needs to be invoked while in Established state */
763: bgp_stop(peer);
764:
765: return 0;
766: }
767:
768: /* Status goes to Established. Send keepalive packet then make first
769: update information. */
770: static int
771: bgp_establish (struct peer *peer)
772: {
773: struct bgp_notify *notify;
774: afi_t afi;
775: safi_t safi;
776: int nsf_af_count = 0;
777:
778: /* Reset capability open status flag. */
779: if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
780: SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
781:
782: /* Clear last notification data. */
783: notify = &peer->notify;
784: if (notify->data)
785: XFREE (MTYPE_TMP, notify->data);
786: memset (notify, 0, sizeof (struct bgp_notify));
787:
788: /* Clear start timer value to default. */
789: peer->v_start = BGP_INIT_START_TIMER;
790:
791: /* Increment established count. */
792: peer->established++;
793: bgp_fsm_change_status (peer, Established);
794:
795: /* bgp log-neighbor-changes of neighbor Up */
796: if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
797: zlog_info ("%%ADJCHANGE: neighbor %s Up", peer->host);
798:
799: /* graceful restart */
800: UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
801: for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1.1.1.2 misho 802: for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
1.1 misho 803: {
804: if (peer->afc_nego[afi][safi]
805: && CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV)
806: && CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV))
807: {
808: if (peer->nsf[afi][safi]
809: && ! CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV))
810: bgp_clear_stale_route (peer, afi, safi);
811:
812: peer->nsf[afi][safi] = 1;
813: nsf_af_count++;
814: }
815: else
816: {
817: if (peer->nsf[afi][safi])
818: bgp_clear_stale_route (peer, afi, safi);
819: peer->nsf[afi][safi] = 0;
820: }
821: }
822:
823: if (nsf_af_count)
824: SET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
825: else
826: {
827: UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
828: if (peer->t_gr_stale)
829: {
830: BGP_TIMER_OFF (peer->t_gr_stale);
831: if (BGP_DEBUG (events, EVENTS))
832: zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
833: }
834: }
835:
836: if (peer->t_gr_restart)
837: {
838: BGP_TIMER_OFF (peer->t_gr_restart);
839: if (BGP_DEBUG (events, EVENTS))
840: zlog_debug ("%s graceful restart timer stopped", peer->host);
841: }
842:
843: #ifdef HAVE_SNMP
844: bgpTrapEstablished (peer);
845: #endif /* HAVE_SNMP */
846:
847: /* Reset uptime, send keepalive, send current table. */
848: peer->uptime = bgp_clock ();
849:
850: /* Send route-refresh when ORF is enabled */
851: for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
852: for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
853: if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV))
854: {
855: if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
856: bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX,
857: REFRESH_IMMEDIATE, 0);
858: else if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
859: bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX_OLD,
860: REFRESH_IMMEDIATE, 0);
861: }
862:
863: if (peer->v_keepalive)
864: bgp_keepalive_send (peer);
865:
866: /* First update is deferred until ORF or ROUTE-REFRESH is received */
867: for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
868: for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
869: if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV))
870: if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
871: || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
872: SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
873:
874: bgp_announce_route_all (peer);
875:
876: BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, 1);
877:
878: return 0;
879: }
880:
881: /* Keepalive packet is received. */
882: static int
883: bgp_fsm_keepalive (struct peer *peer)
884: {
885: /* peer count update */
886: peer->keepalive_in++;
887:
888: BGP_TIMER_OFF (peer->t_holdtime);
889: return 0;
890: }
891:
892: /* Update packet is received. */
893: static int
894: bgp_fsm_update (struct peer *peer)
895: {
896: BGP_TIMER_OFF (peer->t_holdtime);
897: return 0;
898: }
899:
900: /* This is empty event. */
901: static int
902: bgp_ignore (struct peer *peer)
903: {
904: if (BGP_DEBUG (fsm, FSM))
905: zlog (peer->log, LOG_DEBUG, "%s [FSM] bgp_ignore called", peer->host);
906: return 0;
907: }
908:
909: /* Finite State Machine structure */
910: static const struct {
911: int (*func) (struct peer *);
912: int next_state;
913: } FSM [BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] =
914: {
915: {
916: /* Idle state: In Idle state, all events other than BGP_Start is
917: ignored. With BGP_Start event, finite state machine calls
918: bgp_start(). */
919: {bgp_start, Connect}, /* BGP_Start */
920: {bgp_stop, Idle}, /* BGP_Stop */
921: {bgp_stop, Idle}, /* TCP_connection_open */
922: {bgp_stop, Idle}, /* TCP_connection_closed */
923: {bgp_ignore, Idle}, /* TCP_connection_open_failed */
924: {bgp_stop, Idle}, /* TCP_fatal_error */
925: {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
926: {bgp_ignore, Idle}, /* Hold_Timer_expired */
927: {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
928: {bgp_ignore, Idle}, /* Receive_OPEN_message */
929: {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
930: {bgp_ignore, Idle}, /* Receive_UPDATE_message */
931: {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
932: {bgp_ignore, Idle}, /* Clearing_Completed */
933: },
934: {
935: /* Connect */
936: {bgp_ignore, Connect}, /* BGP_Start */
937: {bgp_stop, Idle}, /* BGP_Stop */
938: {bgp_connect_success, OpenSent}, /* TCP_connection_open */
939: {bgp_stop, Idle}, /* TCP_connection_closed */
940: {bgp_connect_fail, Active}, /* TCP_connection_open_failed */
941: {bgp_connect_fail, Idle}, /* TCP_fatal_error */
942: {bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
943: {bgp_ignore, Idle}, /* Hold_Timer_expired */
944: {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
945: {bgp_ignore, Idle}, /* Receive_OPEN_message */
946: {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
947: {bgp_ignore, Idle}, /* Receive_UPDATE_message */
948: {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
949: {bgp_ignore, Idle}, /* Clearing_Completed */
950: },
951: {
952: /* Active, */
953: {bgp_ignore, Active}, /* BGP_Start */
954: {bgp_stop, Idle}, /* BGP_Stop */
955: {bgp_connect_success, OpenSent}, /* TCP_connection_open */
956: {bgp_stop, Idle}, /* TCP_connection_closed */
957: {bgp_ignore, Active}, /* TCP_connection_open_failed */
958: {bgp_ignore, Idle}, /* TCP_fatal_error */
959: {bgp_start, Connect}, /* ConnectRetry_timer_expired */
960: {bgp_ignore, Idle}, /* Hold_Timer_expired */
961: {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
962: {bgp_ignore, Idle}, /* Receive_OPEN_message */
963: {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
964: {bgp_ignore, Idle}, /* Receive_UPDATE_message */
965: {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
966: {bgp_ignore, Idle}, /* Clearing_Completed */
967: },
968: {
969: /* OpenSent, */
970: {bgp_ignore, OpenSent}, /* BGP_Start */
971: {bgp_stop, Idle}, /* BGP_Stop */
972: {bgp_stop, Active}, /* TCP_connection_open */
973: {bgp_stop, Active}, /* TCP_connection_closed */
974: {bgp_stop, Active}, /* TCP_connection_open_failed */
975: {bgp_stop, Active}, /* TCP_fatal_error */
976: {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
977: {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
978: {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
979: {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
980: {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
981: {bgp_ignore, Idle}, /* Receive_UPDATE_message */
982: {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
983: {bgp_ignore, Idle}, /* Clearing_Completed */
984: },
985: {
986: /* OpenConfirm, */
987: {bgp_ignore, OpenConfirm}, /* BGP_Start */
988: {bgp_stop, Idle}, /* BGP_Stop */
989: {bgp_stop, Idle}, /* TCP_connection_open */
990: {bgp_stop, Idle}, /* TCP_connection_closed */
991: {bgp_stop, Idle}, /* TCP_connection_open_failed */
992: {bgp_stop, Idle}, /* TCP_fatal_error */
993: {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
994: {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
995: {bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
996: {bgp_ignore, Idle}, /* Receive_OPEN_message */
997: {bgp_establish, Established}, /* Receive_KEEPALIVE_message */
998: {bgp_ignore, Idle}, /* Receive_UPDATE_message */
999: {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
1000: {bgp_ignore, Idle}, /* Clearing_Completed */
1001: },
1002: {
1003: /* Established, */
1004: {bgp_ignore, Established}, /* BGP_Start */
1005: {bgp_stop, Clearing}, /* BGP_Stop */
1006: {bgp_stop, Clearing}, /* TCP_connection_open */
1007: {bgp_stop, Clearing}, /* TCP_connection_closed */
1008: {bgp_stop, Clearing}, /* TCP_connection_open_failed */
1009: {bgp_stop, Clearing}, /* TCP_fatal_error */
1010: {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
1011: {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
1012: {bgp_fsm_keepalive_expire, Established}, /* KeepAlive_timer_expired */
1013: {bgp_stop, Clearing}, /* Receive_OPEN_message */
1014: {bgp_fsm_keepalive, Established}, /* Receive_KEEPALIVE_message */
1015: {bgp_fsm_update, Established}, /* Receive_UPDATE_message */
1016: {bgp_stop_with_error, Clearing}, /* Receive_NOTIFICATION_message */
1017: {bgp_ignore, Idle}, /* Clearing_Completed */
1018: },
1019: {
1020: /* Clearing, */
1021: {bgp_ignore, Clearing}, /* BGP_Start */
1022: {bgp_stop, Clearing}, /* BGP_Stop */
1023: {bgp_stop, Clearing}, /* TCP_connection_open */
1024: {bgp_stop, Clearing}, /* TCP_connection_closed */
1025: {bgp_stop, Clearing}, /* TCP_connection_open_failed */
1026: {bgp_stop, Clearing}, /* TCP_fatal_error */
1027: {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
1028: {bgp_stop, Clearing}, /* Hold_Timer_expired */
1029: {bgp_stop, Clearing}, /* KeepAlive_timer_expired */
1030: {bgp_stop, Clearing}, /* Receive_OPEN_message */
1031: {bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
1032: {bgp_stop, Clearing}, /* Receive_UPDATE_message */
1033: {bgp_stop, Clearing}, /* Receive_NOTIFICATION_message */
1034: {bgp_clearing_completed, Idle}, /* Clearing_Completed */
1035: },
1036: {
1037: /* Deleted, */
1038: {bgp_ignore, Deleted}, /* BGP_Start */
1039: {bgp_ignore, Deleted}, /* BGP_Stop */
1040: {bgp_ignore, Deleted}, /* TCP_connection_open */
1041: {bgp_ignore, Deleted}, /* TCP_connection_closed */
1042: {bgp_ignore, Deleted}, /* TCP_connection_open_failed */
1043: {bgp_ignore, Deleted}, /* TCP_fatal_error */
1044: {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
1045: {bgp_ignore, Deleted}, /* Hold_Timer_expired */
1046: {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
1047: {bgp_ignore, Deleted}, /* Receive_OPEN_message */
1048: {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
1049: {bgp_ignore, Deleted}, /* Receive_UPDATE_message */
1050: {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */
1051: {bgp_ignore, Deleted}, /* Clearing_Completed */
1052: },
1053: };
1054:
1055: static const char *bgp_event_str[] =
1056: {
1057: NULL,
1058: "BGP_Start",
1059: "BGP_Stop",
1060: "TCP_connection_open",
1061: "TCP_connection_closed",
1062: "TCP_connection_open_failed",
1063: "TCP_fatal_error",
1064: "ConnectRetry_timer_expired",
1065: "Hold_Timer_expired",
1066: "KeepAlive_timer_expired",
1067: "Receive_OPEN_message",
1068: "Receive_KEEPALIVE_message",
1069: "Receive_UPDATE_message",
1070: "Receive_NOTIFICATION_message",
1071: "Clearing_Completed",
1072: };
1073:
1074: /* Execute event process. */
1075: int
1076: bgp_event (struct thread *thread)
1077: {
1078: int ret = 0;
1079: int event;
1080: int next;
1081: struct peer *peer;
1082:
1083: peer = THREAD_ARG (thread);
1084: event = THREAD_VAL (thread);
1085:
1086: /* Logging this event. */
1087: next = FSM [peer->status -1][event - 1].next_state;
1088:
1089: if (BGP_DEBUG (fsm, FSM) && peer->status != next)
1090: plog_debug (peer->log, "%s [FSM] %s (%s->%s)", peer->host,
1091: bgp_event_str[event],
1092: LOOKUP (bgp_status_msg, peer->status),
1093: LOOKUP (bgp_status_msg, next));
1094:
1095: /* Call function. */
1096: if (FSM [peer->status -1][event - 1].func)
1097: ret = (*(FSM [peer->status - 1][event - 1].func))(peer);
1098:
1099: /* When function do not want proceed next job return -1. */
1100: if (ret >= 0)
1101: {
1102: /* If status is changed. */
1103: if (next != peer->status)
1104: bgp_fsm_change_status (peer, next);
1105:
1106: /* Make sure timer is set. */
1107: bgp_timer_set (peer);
1108: }
1109:
1110: return ret;
1111: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>