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