]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_fsm.c
Merge pull request #806 from dwalton76/bgpd-set-ipv4-vpn-nexthop
[mirror_frr.git] / bgpd / bgp_fsm.c
CommitLineData
718e3744 1/* BGP-4 Finite State Machine
896014f4
DL
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 along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
718e3744 21
22#include <zebra.h>
23
24#include "linklist.h"
25#include "prefix.h"
718e3744 26#include "sockunion.h"
27#include "thread.h"
28#include "log.h"
29#include "stream.h"
30#include "memory.h"
31#include "plist.h"
f188f2c4 32#include "workqueue.h"
3f9c7369 33#include "queue.h"
039f3a34 34#include "filter.h"
4dcadbef 35#include "command.h"
718e3744 36
856ca177 37#include "lib/json.h"
718e3744 38#include "bgpd/bgpd.h"
39#include "bgpd/bgp_attr.h"
40#include "bgpd/bgp_debug.h"
41#include "bgpd/bgp_fsm.h"
42#include "bgpd/bgp_packet.h"
43#include "bgpd/bgp_network.h"
44#include "bgpd/bgp_route.h"
45#include "bgpd/bgp_dump.h"
46#include "bgpd/bgp_open.h"
f188f2c4 47#include "bgpd/bgp_advertise.h"
3f9c7369 48#include "bgpd/bgp_updgrp.h"
ffd0c037 49#include "bgpd/bgp_nht.h"
c43ed2e4 50#include "bgpd/bgp_bfd.h"
4a1ab8e4 51#include "bgpd/bgp_memory.h"
6b0655a2 52
3012671f
DL
53DEFINE_HOOK(peer_backward_transition, (struct peer *peer), (peer))
54DEFINE_HOOK(peer_established, (struct peer *peer), (peer))
55
6403814c
DS
56/* Definition of display strings corresponding to FSM events. This should be
57 * kept consistent with the events defined in bgpd.h
58 */
59static const char *bgp_event_str[] =
60{
61 NULL,
62 "BGP_Start",
63 "BGP_Stop",
64 "TCP_connection_open",
65 "TCP_connection_closed",
66 "TCP_connection_open_failed",
67 "TCP_fatal_error",
68 "ConnectRetry_timer_expired",
69 "Hold_Timer_expired",
70 "KeepAlive_timer_expired",
71 "Receive_OPEN_message",
72 "Receive_KEEPALIVE_message",
73 "Receive_UPDATE_message",
74 "Receive_NOTIFICATION_message",
75 "Clearing_Completed",
76};
77
718e3744 78/* BGP FSM (finite state machine) has three types of functions. Type
79 one is thread functions. Type two is event functions. Type three
80 is FSM functions. Timer functions are set by bgp_timer_set
81 function. */
82
83/* BGP event function. */
84int bgp_event (struct thread *);
85
86/* BGP thread functions. */
87static int bgp_start_timer (struct thread *);
88static int bgp_connect_timer (struct thread *);
89static int bgp_holdtime_timer (struct thread *);
90static int bgp_keepalive_timer (struct thread *);
91
92/* BGP FSM functions. */
93static int bgp_start (struct peer *);
94
1ff9a340
DS
95static void
96peer_xfer_stats (struct peer *peer_dst, struct peer *peer_src)
97{
98 /* Copy stats over. These are only the pre-established state stats */
99 peer_dst->open_in += peer_src->open_in;
100 peer_dst->open_out += peer_src->open_out;
101 peer_dst->keepalive_in += peer_src->keepalive_in;
102 peer_dst->keepalive_out += peer_src->keepalive_out;
103 peer_dst->notify_in += peer_src->notify_in;
104 peer_dst->notify_out += peer_src->notify_out;
105 peer_dst->dynamic_cap_in += peer_src->dynamic_cap_in;
106 peer_dst->dynamic_cap_out += peer_src->dynamic_cap_out;
107}
108
109static struct peer *
110peer_xfer_conn(struct peer *from_peer)
111{
112 struct peer *peer;
113 afi_t afi;
114 safi_t safi;
115 int fd;
116 int status, pstatus;
6403814c 117 unsigned char last_evt, last_maj_evt;
1ff9a340
DS
118
119 assert(from_peer != NULL);
120
121 peer = from_peer->doppelganger;
122
123 if (!peer || !CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
124 return from_peer;
125
3f9c7369 126 if (bgp_debug_neighbor_events(peer))
5b6dc0dd
DS
127 zlog_debug ("%s: peer transfer %p fd %d -> %p fd %d)", from_peer->host,
128 from_peer, from_peer->fd, peer, peer->fd);
3f9c7369 129
1ff9a340
DS
130 BGP_WRITE_OFF(peer->t_write);
131 BGP_READ_OFF(peer->t_read);
132 BGP_WRITE_OFF(from_peer->t_write);
133 BGP_READ_OFF(from_peer->t_read);
134
3f9c7369
DS
135 BGP_TIMER_OFF(peer->t_routeadv);
136 BGP_TIMER_OFF(from_peer->t_routeadv);
137
1ff9a340
DS
138 fd = peer->fd;
139 peer->fd = from_peer->fd;
140 from_peer->fd = fd;
141 stream_reset(peer->ibuf);
142 stream_fifo_clean(peer->obuf);
143 stream_fifo_clean(from_peer->obuf);
144
0299c004 145 peer->as = from_peer->as;
1ff9a340
DS
146 peer->v_holdtime = from_peer->v_holdtime;
147 peer->v_keepalive = from_peer->v_keepalive;
1ff9a340
DS
148 peer->routeadv = from_peer->routeadv;
149 peer->v_routeadv = from_peer->v_routeadv;
150 peer->v_gr_restart = from_peer->v_gr_restart;
151 peer->cap = from_peer->cap;
152 status = peer->status;
153 pstatus = peer->ostatus;
6403814c
DS
154 last_evt = peer->last_event;
155 last_maj_evt = peer->last_major_event;
1ff9a340
DS
156 peer->status = from_peer->status;
157 peer->ostatus = from_peer->ostatus;
6403814c
DS
158 peer->last_event = from_peer->last_event;
159 peer->last_major_event = from_peer->last_major_event;
1ff9a340
DS
160 from_peer->status = status;
161 from_peer->ostatus = pstatus;
6403814c
DS
162 from_peer->last_event = last_evt;
163 from_peer->last_major_event = last_maj_evt;
1ff9a340 164 peer->remote_id = from_peer->remote_id;
f9e9e073 165
04b6bdc0 166 if (from_peer->hostname != NULL)
f9e9e073
DW
167 {
168 if (peer->hostname)
169 {
4a1ab8e4 170 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
f9e9e073
DW
171 peer->hostname = NULL;
172 }
173
658bbf6d 174 peer->hostname = from_peer->hostname;
f9e9e073
DW
175 from_peer->hostname = NULL;
176 }
177
04b6bdc0 178 if (from_peer->domainname != NULL)
f9e9e073
DW
179 {
180 if (peer->domainname)
181 {
4a1ab8e4 182 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
f9e9e073
DW
183 peer->domainname= NULL;
184 }
185
658bbf6d 186 peer->domainname = from_peer->domainname;
f9e9e073
DW
187 from_peer->domainname = NULL;
188 }
1ff9a340
DS
189
190 for (afi = AFI_IP; afi < AFI_MAX; afi++)
191 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
192 {
193 peer->af_flags[afi][safi] = from_peer->af_flags[afi][safi];
194 peer->af_sflags[afi][safi] = from_peer->af_sflags[afi][safi];
195 peer->af_cap[afi][safi] = from_peer->af_cap[afi][safi];
196 peer->afc_nego[afi][safi] = from_peer->afc_nego[afi][safi];
197 peer->afc_adv[afi][safi] = from_peer->afc_adv[afi][safi];
198 peer->afc_recv[afi][safi] = from_peer->afc_recv[afi][safi];
40d2700d 199 peer->orf_plist[afi][safi] = from_peer->orf_plist[afi][safi];
1ff9a340
DS
200 }
201
202 if (bgp_getsockname(peer) < 0)
203 {
204 zlog_err ("%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
205 (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER) ? "accept" : ""),
206 peer->host, peer->fd, from_peer->fd);
207 bgp_stop(peer);
208 bgp_stop(from_peer);
209 return NULL;
210 }
211 if (from_peer->status > Active)
212 {
213 if (bgp_getsockname(from_peer) < 0)
214 {
215 zlog_err ("%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
216 (CHECK_FLAG (from_peer->sflags, PEER_STATUS_ACCEPT_PEER) ? "accept" : ""),
217 from_peer->host, from_peer->fd, peer->fd);
218 bgp_stop(from_peer);
219 from_peer = NULL;
220 }
221 }
222
223 BGP_READ_ON(peer->t_read, bgp_read, peer->fd);
224 BGP_WRITE_ON(peer->t_write, bgp_write, peer->fd);
225
226 if (from_peer)
227 peer_xfer_stats(peer, from_peer);
228
229 return(peer);
230}
231
718e3744 232/* Hook function called after bgp event is occered. And vty's
233 neighbor command invoke this function after making neighbor
234 structure. */
235void
236bgp_timer_set (struct peer *peer)
237{
718e3744 238 switch (peer->status)
239 {
240 case Idle:
241 /* First entry point of peer's finite state machine. In Idle
242 status start timer is on unless peer is shutdown or peer is
243 inactive. All other timer must be turned off */
ca058a30 244 if (BGP_PEER_START_SUPPRESSED (peer) || ! peer_active (peer))
718e3744 245 {
246 BGP_TIMER_OFF (peer->t_start);
247 }
248 else
249 {
718e3744 250 BGP_TIMER_ON (peer->t_start, bgp_start_timer,
5ca5f1c8 251 peer->v_start);
718e3744 252 }
253 BGP_TIMER_OFF (peer->t_connect);
254 BGP_TIMER_OFF (peer->t_holdtime);
255 BGP_TIMER_OFF (peer->t_keepalive);
718e3744 256 BGP_TIMER_OFF (peer->t_routeadv);
257 break;
258
259 case Connect:
5ca5f1c8 260 /* After start timer is expired, the peer moves to Connect
718e3744 261 status. Make sure start timer is off and connect timer is
262 on. */
263 BGP_TIMER_OFF (peer->t_start);
264 BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
265 BGP_TIMER_OFF (peer->t_holdtime);
266 BGP_TIMER_OFF (peer->t_keepalive);
718e3744 267 BGP_TIMER_OFF (peer->t_routeadv);
268 break;
269
270 case Active:
271 /* Active is waiting connection from remote peer. And if
272 connect timer is expired, change status to Connect. */
273 BGP_TIMER_OFF (peer->t_start);
274 /* If peer is passive mode, do not set connect timer. */
93406d87 275 if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE)
276 || CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
718e3744 277 {
278 BGP_TIMER_OFF (peer->t_connect);
279 }
280 else
281 {
282 BGP_TIMER_ON (peer->t_connect, bgp_connect_timer, peer->v_connect);
283 }
284 BGP_TIMER_OFF (peer->t_holdtime);
285 BGP_TIMER_OFF (peer->t_keepalive);
718e3744 286 BGP_TIMER_OFF (peer->t_routeadv);
287 break;
288
289 case OpenSent:
290 /* OpenSent status. */
291 BGP_TIMER_OFF (peer->t_start);
292 BGP_TIMER_OFF (peer->t_connect);
293 if (peer->v_holdtime != 0)
294 {
295 BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
296 peer->v_holdtime);
297 }
298 else
299 {
300 BGP_TIMER_OFF (peer->t_holdtime);
301 }
302 BGP_TIMER_OFF (peer->t_keepalive);
718e3744 303 BGP_TIMER_OFF (peer->t_routeadv);
304 break;
305
306 case OpenConfirm:
307 /* OpenConfirm status. */
308 BGP_TIMER_OFF (peer->t_start);
309 BGP_TIMER_OFF (peer->t_connect);
310
311 /* If the negotiated Hold Time value is zero, then the Hold Time
312 timer and KeepAlive timers are not started. */
313 if (peer->v_holdtime == 0)
314 {
315 BGP_TIMER_OFF (peer->t_holdtime);
316 BGP_TIMER_OFF (peer->t_keepalive);
317 }
318 else
319 {
320 BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
321 peer->v_holdtime);
322 BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
323 peer->v_keepalive);
324 }
718e3744 325 BGP_TIMER_OFF (peer->t_routeadv);
326 break;
327
328 case Established:
329 /* In Established status start and connect timer is turned
330 off. */
331 BGP_TIMER_OFF (peer->t_start);
332 BGP_TIMER_OFF (peer->t_connect);
333
334 /* Same as OpenConfirm, if holdtime is zero then both holdtime
335 and keepalive must be turned off. */
336 if (peer->v_holdtime == 0)
337 {
338 BGP_TIMER_OFF (peer->t_holdtime);
339 BGP_TIMER_OFF (peer->t_keepalive);
340 }
341 else
342 {
343 BGP_TIMER_ON (peer->t_holdtime, bgp_holdtime_timer,
344 peer->v_holdtime);
345 BGP_TIMER_ON (peer->t_keepalive, bgp_keepalive_timer,
346 peer->v_keepalive);
347 }
718e3744 348 break;
ca058a30
PJ
349 case Deleted:
350 BGP_TIMER_OFF (peer->t_gr_restart);
351 BGP_TIMER_OFF (peer->t_gr_stale);
352 BGP_TIMER_OFF (peer->t_pmax_restart);
353 case Clearing:
354 BGP_TIMER_OFF (peer->t_start);
355 BGP_TIMER_OFF (peer->t_connect);
356 BGP_TIMER_OFF (peer->t_holdtime);
357 BGP_TIMER_OFF (peer->t_keepalive);
ca058a30 358 BGP_TIMER_OFF (peer->t_routeadv);
1ff9a340 359 break;
718e3744 360 }
361}
362
363/* BGP start timer. This function set BGP_Start event to thread value
364 and process event. */
365static int
366bgp_start_timer (struct thread *thread)
367{
368 struct peer *peer;
369
370 peer = THREAD_ARG (thread);
371 peer->t_start = NULL;
372
16286195
DS
373 if (bgp_debug_neighbor_events(peer))
374 zlog_debug("%s [FSM] Timer (start timer expire).", peer->host);
718e3744 375
376 THREAD_VAL (thread) = BGP_Start;
200df115 377 bgp_event (thread); /* bgp_event unlocks peer */
718e3744 378
379 return 0;
380}
381
382/* BGP connect retry timer. */
383static int
384bgp_connect_timer (struct thread *thread)
385{
386 struct peer *peer;
1ff9a340 387 int ret;
718e3744 388
389 peer = THREAD_ARG (thread);
390 peer->t_connect = NULL;
391
16286195
DS
392 if (bgp_debug_neighbor_events(peer))
393 zlog_debug("%s [FSM] Timer (connect timer expire)", peer->host);
718e3744 394
1ff9a340
DS
395 if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
396 {
397 bgp_stop(peer);
398 ret = -1;
399 }
400 else
401 {
402 THREAD_VAL (thread) = ConnectRetry_timer_expired;
403 bgp_event (thread); /* bgp_event unlocks peer */
404 ret = 0;
405 }
718e3744 406
1ff9a340 407 return ret;
718e3744 408}
409
410/* BGP holdtime timer. */
411static int
412bgp_holdtime_timer (struct thread *thread)
413{
414 struct peer *peer;
415
416 peer = THREAD_ARG (thread);
417 peer->t_holdtime = NULL;
418
16286195
DS
419 if (bgp_debug_neighbor_events(peer))
420 zlog_debug ("%s [FSM] Timer (holdtime timer expire)", peer->host);
718e3744 421
422 THREAD_VAL (thread) = Hold_Timer_expired;
200df115 423 bgp_event (thread); /* bgp_event unlocks peer */
718e3744 424
425 return 0;
426}
427
428/* BGP keepalive fire ! */
429static int
430bgp_keepalive_timer (struct thread *thread)
431{
432 struct peer *peer;
433
434 peer = THREAD_ARG (thread);
435 peer->t_keepalive = NULL;
436
16286195
DS
437 if (bgp_debug_neighbor_events(peer))
438 zlog_debug ("%s [FSM] Timer (keepalive timer expire)", peer->host);
718e3744 439
440 THREAD_VAL (thread) = KeepAlive_timer_expired;
200df115 441 bgp_event (thread); /* bgp_event unlocks peer */
718e3744 442
443 return 0;
444}
445
3f9c7369 446int
718e3744 447bgp_routeadv_timer (struct thread *thread)
448{
449 struct peer *peer;
450
451 peer = THREAD_ARG (thread);
452 peer->t_routeadv = NULL;
453
16286195
DS
454 if (bgp_debug_neighbor_events(peer))
455 zlog_debug ("%s [FSM] Timer (routeadv timer expire)", peer->host);
718e3744 456
65957886 457 peer->synctime = bgp_clock ();
718e3744 458
eb821189 459 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
718e3744 460
3f9c7369
DS
461 /* MRAI timer will be started again when FIFO is built, no need to
462 * do it here.
cb1faec9 463 */
718e3744 464 return 0;
465}
466
e0701b79 467/* BGP Peer Down Cause */
fd79ac91 468const char *peer_down_str[] =
e0701b79 469{
470 "",
471 "Router ID changed",
472 "Remote AS changed",
473 "Local AS change",
474 "Cluster ID changed",
475 "Confederation identifier changed",
476 "Confederation peer changed",
477 "RR client config change",
478 "RS client config change",
479 "Update source change",
480 "Address family activated",
481 "Admin. shutdown",
482 "User reset",
483 "BGP Notification received",
484 "BGP Notification send",
485 "Peer closed the session",
486 "Neighbor deleted",
487 "Peer-group add member",
488 "Peer-group delete member",
489 "Capability changed",
490 "Passive config change",
93406d87 491 "Multihop config change",
cceb0bfc 492 "NSF peer closed the session",
7bbc6864 493 "Intf peering v6only config change",
e60480bd
DD
494 "BFD down received",
495 "Interface down",
496 "Neighbor address lost"
e0701b79 497};
498
94f2b392 499static int
93406d87 500bgp_graceful_restart_timer_expire (struct thread *thread)
501{
502 struct peer *peer;
503 afi_t afi;
504 safi_t safi;
505
506 peer = THREAD_ARG (thread);
507 peer->t_gr_restart = NULL;
508
509 /* NSF delete stale route */
510 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
4d5b4f7b 511 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++)
93406d87 512 if (peer->nsf[afi][safi])
513 bgp_clear_stale_route (peer, afi, safi);
514
515 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
516 BGP_TIMER_OFF (peer->t_gr_stale);
517
16286195 518 if (bgp_debug_neighbor_events(peer))
93406d87 519 {
520 zlog_debug ("%s graceful restart timer expired", peer->host);
521 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
522 }
523
524 bgp_timer_set (peer);
525
526 return 0;
527}
528
94f2b392 529static int
93406d87 530bgp_graceful_stale_timer_expire (struct thread *thread)
531{
532 struct peer *peer;
533 afi_t afi;
534 safi_t safi;
535
536 peer = THREAD_ARG (thread);
537 peer->t_gr_stale = NULL;
538
16286195 539 if (bgp_debug_neighbor_events(peer))
93406d87 540 zlog_debug ("%s graceful restart stalepath timer expired", peer->host);
541
542 /* NSF delete stale route */
543 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
4d5b4f7b 544 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++)
93406d87 545 if (peer->nsf[afi][safi])
546 bgp_clear_stale_route (peer, afi, safi);
547
548 return 0;
549}
550
f188f2c4
DS
551static int
552bgp_update_delay_applicable (struct bgp *bgp)
553{
554 /* update_delay_over flag should be reset (set to 0) for any new
555 applicability of the update-delay during BGP process lifetime.
556 And it should be set after an occurence of the update-delay is over)*/
557 if (!bgp->update_delay_over)
558 return 1;
559
560 return 0;
561}
562
563int
564bgp_update_delay_active (struct bgp *bgp)
565{
566 if (bgp->t_update_delay)
567 return 1;
568
569 return 0;
570}
571
572int
573bgp_update_delay_configured (struct bgp *bgp)
574{
575 if (bgp->v_update_delay)
576 return 1;
577
578 return 0;
579}
580
581/* Do the post-processing needed when bgp comes out of the read-only mode
582 on ending the update delay. */
583void
584bgp_update_delay_end (struct bgp *bgp)
585{
f188f2c4
DS
586 THREAD_TIMER_OFF (bgp->t_update_delay);
587 THREAD_TIMER_OFF (bgp->t_establish_wait);
588
589 /* Reset update-delay related state */
590 bgp->update_delay_over = 1;
591 bgp->established = 0;
592 bgp->restarted_peers = 0;
593 bgp->implicit_eors = 0;
594 bgp->explicit_eors = 0;
595
596 quagga_timestamp(3, bgp->update_delay_end_time,
597 sizeof(bgp->update_delay_end_time));
598
cb1faec9
DS
599 /*
600 * Add an end-of-initial-update marker to the main process queues so that
4a16ae86
DS
601 * the route advertisement timer for the peers can be started. Also set
602 * the zebra and peer update hold flags. These flags are used to achieve
603 * three stages in the update-delay post processing:
604 * 1. Finish best-path selection for all the prefixes held on the queues.
605 * (routes in BGP are updated, and peers sync queues are populated too)
606 * 2. As the eoiu mark is reached in the bgp process routine, ship all the
607 * routes to zebra. With that zebra should see updates from BGP close
608 * to each other.
609 * 3. Unblock the peer update writes. With that peer update packing with
610 * the prefixes should be at its maximum.
cb1faec9 611 */
2a3d5731 612 bgp_add_eoiu_mark(bgp);
4a16ae86
DS
613 bgp->main_zebra_update_hold = 1;
614 bgp->main_peers_update_hold = 1;
f188f2c4
DS
615
616 /* Resume the queue processing. This should trigger the event that would take
617 care of processing any work that was queued during the read-only mode. */
618 work_queue_unplug(bm->process_main_queue);
f188f2c4
DS
619}
620
cb1faec9
DS
621/**
622 * see bgp_fsm.h
623 */
624void
625bgp_start_routeadv (struct bgp *bgp)
626{
627 struct listnode *node, *nnode;
628 struct peer *peer;
629
2a3d5731
DW
630 zlog_info("bgp_start_routeadv(), update hold status %d",
631 bgp->main_peers_update_hold);
4a16ae86 632
2a3d5731 633 if (bgp->main_peers_update_hold)
4a16ae86
DS
634 return;
635
636 quagga_timestamp(3, bgp->update_delay_peers_resume_time,
637 sizeof(bgp->update_delay_peers_resume_time));
638
cb1faec9
DS
639 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
640 {
641 if (peer->status != Established)
642 continue;
643 BGP_TIMER_OFF(peer->t_routeadv);
644 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
645 }
646}
647
648/**
649 * see bgp_fsm.h
650 */
651void
652bgp_adjust_routeadv (struct peer *peer)
653{
654 time_t nowtime = bgp_clock();
655 double diff;
656 unsigned long remain;
657
d889623f
DS
658 /* Bypass checks for special case of MRAI being 0 */
659 if (peer->v_routeadv == 0)
660 {
661 /* Stop existing timer, just in case it is running for a different
662 * duration and schedule write thread immediately.
663 */
664 if (peer->t_routeadv)
665 BGP_TIMER_OFF(peer->t_routeadv);
666
667 peer->synctime = bgp_clock ();
668 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
669 return;
670 }
671
d889623f 672
cb1faec9
DS
673 /*
674 * CASE I:
675 * If the last update was written more than MRAI back, expire the timer
676 * instantly so that we can send the update out sooner.
677 *
678 * <------- MRAI --------->
679 * |-----------------|-----------------------|
680 * <------------- m ------------>
681 * ^ ^ ^
682 * | | |
683 * | | current time
684 * | timer start
685 * last write
686 *
687 * m > MRAI
688 */
1ba2a97a 689 diff = difftime(nowtime, peer->last_update);
cb1faec9
DS
690 if (diff > (double) peer->v_routeadv)
691 {
692 BGP_TIMER_OFF(peer->t_routeadv);
693 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
cb1faec9
DS
694 return;
695 }
696
697 /*
698 * CASE II:
699 * - Find when to expire the MRAI timer.
700 * If MRAI timer is not active, assume we can start it now.
701 *
702 * <------- MRAI --------->
703 * |------------|-----------------------|
704 * <-------- m ----------><----- r ----->
705 * ^ ^ ^
706 * | | |
707 * | | current time
708 * | timer start
709 * last write
710 *
711 * (MRAI - m) < r
712 */
713 if (peer->t_routeadv)
714 remain = thread_timer_remain_second(peer->t_routeadv);
715 else
716 remain = peer->v_routeadv;
717 diff = peer->v_routeadv - diff;
718 if (diff <= (double) remain)
719 {
720 BGP_TIMER_OFF(peer->t_routeadv);
721 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, diff);
cb1faec9
DS
722 }
723}
724
abc920f8
DS
725static int
726bgp_maxmed_onstartup_applicable (struct bgp *bgp)
727{
728 if (!bgp->maxmed_onstartup_over)
729 return 1;
730
731 return 0;
732}
733
734int
735bgp_maxmed_onstartup_configured (struct bgp *bgp)
736{
737 if (bgp->v_maxmed_onstartup != BGP_MAXMED_ONSTARTUP_UNCONFIGURED)
738 return 1;
739
740 return 0;
741}
742
743int
744bgp_maxmed_onstartup_active (struct bgp *bgp)
745{
746 if (bgp->t_maxmed_onstartup)
747 return 1;
748
749 return 0;
750}
751
752void
753bgp_maxmed_update (struct bgp *bgp)
754{
abc920f8
DS
755 u_char maxmed_active;
756 u_int32_t maxmed_value;
757
758 if (bgp->v_maxmed_admin)
759 {
760 maxmed_active = 1;
761 maxmed_value = bgp->maxmed_admin_value;
762 }
763 else if (bgp->t_maxmed_onstartup)
764 {
765 maxmed_active = 1;
766 maxmed_value = bgp->maxmed_onstartup_value;
767 }
768 else
769 {
770 maxmed_active = 0;
771 maxmed_value = BGP_MAXMED_VALUE_DEFAULT;
772 }
773
774 if (bgp->maxmed_active != maxmed_active ||
775 bgp->maxmed_value != maxmed_value)
776 {
777 bgp->maxmed_active = maxmed_active;
778 bgp->maxmed_value = maxmed_value;
779
3f9c7369 780 update_group_announce(bgp);
abc920f8
DS
781 }
782}
783
784/* The maxmed onstartup timer expiry callback. */
785static int
786bgp_maxmed_onstartup_timer (struct thread *thread)
787{
788 struct bgp *bgp;
789
790 zlog_info ("Max med on startup ended - timer expired.");
791
792 bgp = THREAD_ARG (thread);
793 THREAD_TIMER_OFF (bgp->t_maxmed_onstartup);
794 bgp->maxmed_onstartup_over = 1;
795
796 bgp_maxmed_update(bgp);
797
798 return 0;
799}
800
801static void
802bgp_maxmed_onstartup_begin (struct bgp *bgp)
803{
804 /* Applicable only once in the process lifetime on the startup */
805 if (bgp->maxmed_onstartup_over)
806 return;
807
808 zlog_info ("Begin maxmed onstartup mode - timer %d seconds",
809 bgp->v_maxmed_onstartup);
810
ffa2c898
QY
811 thread_add_timer(bm->master, bgp_maxmed_onstartup_timer, bgp,
812 bgp->v_maxmed_onstartup, &bgp->t_maxmed_onstartup);
abc920f8
DS
813
814 if (!bgp->v_maxmed_admin)
815 {
816 bgp->maxmed_active = 1;
817 bgp->maxmed_value = bgp->maxmed_onstartup_value;
818 }
819
820 /* Route announce to all peers should happen after this in bgp_establish() */
821}
822
823static void
824bgp_maxmed_onstartup_process_status_change(struct peer *peer)
825{
826 if (peer->status == Established && !peer->bgp->established)
827 {
828 bgp_maxmed_onstartup_begin(peer->bgp);
829 }
830}
831
f188f2c4
DS
832/* The update delay timer expiry callback. */
833static int
834bgp_update_delay_timer (struct thread *thread)
835{
836 struct bgp *bgp;
837
838 zlog_info ("Update delay ended - timer expired.");
839
840 bgp = THREAD_ARG (thread);
841 THREAD_TIMER_OFF (bgp->t_update_delay);
842 bgp_update_delay_end(bgp);
843
844 return 0;
845}
846
847/* The establish wait timer expiry callback. */
848static int
849bgp_establish_wait_timer (struct thread *thread)
850{
851 struct bgp *bgp;
852
853 zlog_info ("Establish wait - timer expired.");
854
855 bgp = THREAD_ARG (thread);
856 THREAD_TIMER_OFF (bgp->t_establish_wait);
857 bgp_check_update_delay(bgp);
858
859 return 0;
860}
861
862/* Steps to begin the update delay:
863 - initialize queues if needed
864 - stop the queue processing
865 - start the timer */
866static void
867bgp_update_delay_begin (struct bgp *bgp)
868{
869 struct listnode *node, *nnode;
870 struct peer *peer;
871
f188f2c4
DS
872 /* Stop the processing of queued work. Enqueue shall continue */
873 work_queue_plug(bm->process_main_queue);
f188f2c4
DS
874
875 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
876 peer->update_delay_over = 0;
877
878 /* Start the update-delay timer */
ffa2c898
QY
879 thread_add_timer(bm->master, bgp_update_delay_timer, bgp,
880 bgp->v_update_delay, &bgp->t_update_delay);
f188f2c4
DS
881
882 if (bgp->v_establish_wait != bgp->v_update_delay)
ffa2c898
QY
883 thread_add_timer(bm->master, bgp_establish_wait_timer, bgp,
884 bgp->v_establish_wait, &bgp->t_establish_wait);
f188f2c4
DS
885
886 quagga_timestamp(3, bgp->update_delay_begin_time,
887 sizeof(bgp->update_delay_begin_time));
888}
889
890static void
891bgp_update_delay_process_status_change(struct peer *peer)
892{
893 if (peer->status == Established)
894 {
895 if (!peer->bgp->established++)
896 {
897 bgp_update_delay_begin(peer->bgp);
898 zlog_info ("Begin read-only mode - update-delay timer %d seconds",
899 peer->bgp->v_update_delay);
900 }
901 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_BIT_RCV))
902 bgp_update_restarted_peers(peer);
903 }
904 if (peer->ostatus == Established && bgp_update_delay_active(peer->bgp))
905 {
906 /* Adjust the update-delay state to account for this flap.
907 NOTE: Intentionally skipping adjusting implicit_eors or explicit_eors
908 counters. Extra sanity check in bgp_check_update_delay() should
909 be enough to take care of any additive discrepancy in bgp eor
910 counters */
911 peer->bgp->established--;
912 peer->update_delay_over = 0;
913 }
914}
915
200df115 916/* Called after event occured, this function change status and reset
917 read/write and timer thread. */
918void
919bgp_fsm_change_status (struct peer *peer, int status)
920{
1ff9a340 921
200df115 922 bgp_dump_state (peer, peer->status, status);
923
f2c31acb
PJ
924 /* Transition into Clearing or Deleted must /always/ clear all routes..
925 * (and must do so before actually changing into Deleted..
926 */
927 if (status >= Clearing)
dc83d712
DS
928 {
929 bgp_clear_route_all (peer);
930
931 /* If no route was queued for the clear-node processing, generate the
932 * completion event here. This is needed because if there are no routes
933 * to trigger the background clear-node thread, the event won't get
934 * generated and the peer would be stuck in Clearing. Note that this
935 * event is for the peer and helps the peer transition out of Clearing
936 * state; it should not be generated per (AFI,SAFI). The event is
937 * directly posted here without calling clear_node_complete() as we
938 * shouldn't do an extra unlock. This event will get processed after
939 * the state change that happens below, so peer will be in Clearing
940 * (or Deleted).
941 */
b4575c00 942 if (!work_queue_is_scheduled (peer->clear_node_queue))
dc83d712
DS
943 BGP_EVENT_ADD (peer, Clearing_Completed);
944 }
f2c31acb 945
200df115 946 /* Preserve old status and change into new status. */
947 peer->ostatus = peer->status;
948 peer->status = status;
f188f2c4 949
6403814c
DS
950 /* Save event that caused status change. */
951 peer->last_major_event = peer->cur_event;
952
1ff9a340
DS
953 if (status == Established)
954 UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
955
abc920f8
DS
956 /* If max-med processing is applicable, do the necessary. */
957 if (status == Established)
958 {
959 if (bgp_maxmed_onstartup_configured(peer->bgp) &&
960 bgp_maxmed_onstartup_applicable(peer->bgp))
961 bgp_maxmed_onstartup_process_status_change(peer);
962 else
963 peer->bgp->maxmed_onstartup_over = 1;
964 }
965
f188f2c4
DS
966 /* If update-delay processing is applicable, do the necessary. */
967 if (bgp_update_delay_configured(peer->bgp) &&
968 bgp_update_delay_applicable(peer->bgp))
969 bgp_update_delay_process_status_change(peer);
970
16286195 971 if (bgp_debug_neighbor_events(peer))
200df115 972 zlog_debug ("%s went from %s to %s",
973 peer->host,
56b40679
QY
974 lookup_msg(bgp_status_msg, peer->ostatus, NULL),
975 lookup_msg(bgp_status_msg, peer->status, NULL));
200df115 976}
977
3117b5c4 978/* Flush the event queue and ensure the peer is shut down */
9e4ca89c 979static int
3117b5c4
SH
980bgp_clearing_completed (struct peer *peer)
981{
982 int rc = bgp_stop(peer);
1ff9a340
DS
983
984 if (rc >= 0)
985 BGP_EVENT_FLUSH (peer);
3117b5c4
SH
986
987 return rc;
988}
989
718e3744 990/* Administrative BGP peer stop event. */
3117b5c4 991/* May be called multiple times for the same peer */
718e3744 992int
993bgp_stop (struct peer *peer)
994{
718e3744 995 afi_t afi;
996 safi_t safi;
997 char orf_name[BUFSIZ];
1ff9a340 998 int ret = 0;
718e3744 999
f14e6fdb
DS
1000 if (peer_dynamic_neighbor(peer) &&
1001 !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE)))
1002 {
1003 if (bgp_debug_neighbor_events(peer))
1004 zlog_debug ("%s (dynamic neighbor) deleted", peer->host);
1005 peer_delete (peer);
1006 return -1;
1007 }
1008
3117b5c4
SH
1009 /* Can't do this in Clearing; events are used for state transitions */
1010 if (peer->status != Clearing)
2158ad23
PJ
1011 {
1012 /* Delete all existing events of the peer */
1013 BGP_EVENT_FLUSH (peer);
1014 }
dcdf399f 1015
718e3744 1016 /* Increment Dropped count. */
1017 if (peer->status == Established)
1018 {
718e3744 1019 peer->dropped++;
848973c7 1020
1021 /* bgp log-neighbor-changes of neighbor Down */
1022 if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
c22767d8
DS
1023 {
1024 struct vrf *vrf = vrf_lookup_by_id (peer->bgp->vrf_id);
1025 zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
1026 peer->host,
1027 (peer->hostname) ? peer->hostname : "Unknown",
2e37f307 1028 vrf ? ((vrf->vrf_id != VRF_DEFAULT) ? vrf->name : "Default") : "",
c22767d8
DS
1029 peer_down_str [(int) peer->last_reset]);
1030 }
848973c7 1031
93406d87 1032 /* graceful restart */
1033 if (peer->t_gr_stale)
1034 {
1035 BGP_TIMER_OFF (peer->t_gr_stale);
16286195 1036 if (bgp_debug_neighbor_events(peer))
93406d87 1037 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
1038 }
1039 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
1040 {
16286195 1041 if (bgp_debug_neighbor_events(peer))
93406d87 1042 {
1043 zlog_debug ("%s graceful restart timer started for %d sec",
1044 peer->host, peer->v_gr_restart);
1045 zlog_debug ("%s graceful restart stalepath timer started for %d sec",
1046 peer->host, peer->bgp->stalepath_time);
1047 }
1048 BGP_TIMER_ON (peer->t_gr_restart, bgp_graceful_restart_timer_expire,
1049 peer->v_gr_restart);
1050 BGP_TIMER_ON (peer->t_gr_stale, bgp_graceful_stale_timer_expire,
1051 peer->bgp->stalepath_time);
1052 }
1053 else
1054 {
1055 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1056
1057 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
4d5b4f7b 1058 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++)
93406d87 1059 peer->nsf[afi][safi] = 0;
1060 }
1061
848973c7 1062 /* set last reset time */
65957886 1063 peer->resettime = peer->uptime = bgp_clock ();
848973c7 1064
3f9c7369
DS
1065 if (BGP_DEBUG (update_groups, UPDATE_GROUPS))
1066 zlog_debug ("%s remove from all update group", peer->host);
1067 update_group_remove_peer_afs(peer);
1068
3012671f 1069 hook_call(peer_backward_transition, peer);
718e3744 1070
f418446b 1071 /* Reset peer synctime */
1072 peer->synctime = 0;
c43ed2e4
DS
1073
1074 bgp_bfd_deregister_peer(peer);
538621f2 1075 }
718e3744 1076
1077 /* Stop read and write threads when exists. */
1078 BGP_READ_OFF (peer->t_read);
1079 BGP_WRITE_OFF (peer->t_write);
1080
1081 /* Stop all timers. */
1082 BGP_TIMER_OFF (peer->t_start);
1083 BGP_TIMER_OFF (peer->t_connect);
1084 BGP_TIMER_OFF (peer->t_holdtime);
1085 BGP_TIMER_OFF (peer->t_keepalive);
718e3744 1086 BGP_TIMER_OFF (peer->t_routeadv);
1087
718e3744 1088 /* Stream reset. */
1089 peer->packet_size = 0;
1090
1091 /* Clear input and output buffer. */
1092 if (peer->ibuf)
1093 stream_reset (peer->ibuf);
1094 if (peer->work)
1095 stream_reset (peer->work);
200df115 1096 if (peer->obuf)
1097 stream_fifo_clean (peer->obuf);
718e3744 1098
eb821189 1099 /* Close of file descriptor. */
1100 if (peer->fd >= 0)
1101 {
1102 close (peer->fd);
1103 peer->fd = -1;
1104 }
718e3744 1105
718e3744 1106 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1107 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1108 {
538621f2 1109 /* Reset all negotiated variables */
1110 peer->afc_nego[afi][safi] = 0;
1111 peer->afc_adv[afi][safi] = 0;
1112 peer->afc_recv[afi][safi] = 0;
1113
718e3744 1114 /* peer address family capability flags*/
1115 peer->af_cap[afi][safi] = 0;
538621f2 1116
718e3744 1117 /* peer address family status flags*/
1118 peer->af_sflags[afi][safi] = 0;
538621f2 1119
718e3744 1120 /* Received ORF prefix-filter */
1121 peer->orf_plist[afi][safi] = NULL;
538621f2 1122
1ff9a340
DS
1123 if ((peer->status == OpenConfirm) || (peer->status == Established)) {
1124 /* ORF received prefix-filter pnt */
1125 sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
c7da3d50 1126 prefix_bgp_orf_remove_all (afi, orf_name);
1ff9a340 1127 }
718e3744 1128 }
1129
1130 /* Reset keepalive and holdtime */
1131 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1132 {
1133 peer->v_keepalive = peer->keepalive;
1134 peer->v_holdtime = peer->holdtime;
1135 }
1136 else
1137 {
1138 peer->v_keepalive = peer->bgp->default_keepalive;
1139 peer->v_holdtime = peer->bgp->default_holdtime;
1140 }
1141
1142 peer->update_time = 0;
1143
1144 /* Until we are sure that there is no problem about prefix count
1145 this should be commented out.*/
1146#if 0
1147 /* Reset prefix count */
1148 peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
1149 peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
cd1964ff 1150 peer->pcount[AFI_IP][SAFI_LABELED_UNICAST] = 0;
718e3744 1151 peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
1152 peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
1153 peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
cd1964ff 1154 peer->pcount[AFI_IP6][SAFI_LABELED_UNICAST] = 0;
718e3744 1155#endif /* 0 */
1156
1ff9a340
DS
1157 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE) &&
1158 !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE)))
1159 {
1160 peer_delete(peer);
1161 ret = -1;
1162 }
a80beece
DS
1163 else
1164 {
1165 bgp_peer_conf_if_to_su_update(peer);
1166 }
1ff9a340
DS
1167
1168 return ret;
718e3744 1169}
1170
1171/* BGP peer is stoped by the error. */
94f2b392 1172static int
718e3744 1173bgp_stop_with_error (struct peer *peer)
1174{
1175 /* Double start timer. */
1176 peer->v_start *= 2;
1177
1178 /* Overflow check. */
1179 if (peer->v_start >= (60 * 2))
1180 peer->v_start = (60 * 2);
1181
f14e6fdb
DS
1182 if (peer_dynamic_neighbor(peer))
1183 {
1184 if (bgp_debug_neighbor_events(peer))
1185 zlog_debug ("%s (dynamic neighbor) deleted", peer->host);
1186 peer_delete (peer);
1187 return -1;
1188 }
1189
1ff9a340 1190 return(bgp_stop (peer));
718e3744 1191}
1192
397b5bde
LR
1193
1194/* something went wrong, send notify and tear down */
1195static int
1196bgp_stop_with_notify (struct peer *peer, u_char code, u_char sub_code)
1197{
1198 /* Send notify to remote peer */
1199 bgp_notify_send (peer, code, sub_code);
1200
f14e6fdb
DS
1201 if (peer_dynamic_neighbor(peer))
1202 {
1203 if (bgp_debug_neighbor_events(peer))
1204 zlog_debug ("%s (dynamic neighbor) deleted", peer->host);
1205 peer_delete (peer);
1206 return -1;
1207 }
1208
397b5bde
LR
1209 /* Clear start timer value to default. */
1210 peer->v_start = BGP_INIT_START_TIMER;
1211
1ff9a340 1212 return(bgp_stop(peer));
397b5bde
LR
1213}
1214
1215
718e3744 1216/* TCP connection open. Next we send open message to remote peer. And
1217 add read thread for reading open message. */
94f2b392 1218static int
718e3744 1219bgp_connect_success (struct peer *peer)
1220{
eb821189 1221 if (peer->fd < 0)
718e3744 1222 {
1223 zlog_err ("bgp_connect_success peer's fd is negative value %d",
eb821189 1224 peer->fd);
1ff9a340 1225 bgp_stop(peer);
718e3744 1226 return -1;
1227 }
718e3744 1228
1ff9a340
DS
1229 if (bgp_getsockname (peer) < 0)
1230 {
5b6dc0dd
DS
1231 zlog_err ("%s: bgp_getsockname(): failed for peer %s, fd %d", __FUNCTION__,
1232 peer->host, peer->fd);
1ff9a340
DS
1233 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR, 0); /* internal error */
1234 return -1;
1235 }
1236
1237 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
f418446b 1238
16286195 1239 if (bgp_debug_neighbor_events(peer))
f418446b 1240 {
682ca04c
JBD
1241 char buf1[SU_ADDRSTRLEN];
1242
f418446b 1243 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1244 zlog_debug ("%s open active, local address %s", peer->host,
1245 sockunion2str (peer->su_local, buf1, SU_ADDRSTRLEN));
1246 else
1247 zlog_debug ("%s passive open", peer->host);
1248 }
718e3744 1249
1ff9a340 1250 bgp_open_send (peer);
718e3744 1251
1252 return 0;
1253}
1254
1255/* TCP connect fail */
94f2b392 1256static int
718e3744 1257bgp_connect_fail (struct peer *peer)
1258{
f14e6fdb
DS
1259 if (peer_dynamic_neighbor(peer))
1260 {
1261 if (bgp_debug_neighbor_events(peer))
1262 zlog_debug ("%s (dynamic neighbor) deleted", peer->host);
1263 peer_delete (peer);
1264 return -1;
1265 }
1266
1ff9a340 1267 return (bgp_stop (peer));
718e3744 1268}
1269
1270/* This function is the first starting point of all BGP connection. It
1271 try to connect to remote peer with non-blocking IO. */
1272int
1273bgp_start (struct peer *peer)
1274{
1275 int status;
fc9a856f 1276 int connected = 0;
718e3744 1277
a80beece
DS
1278 bgp_peer_conf_if_to_su_update(peer);
1279
085567f9 1280 if (peer->su.sa.sa_family == AF_UNSPEC)
1281 {
1282 if (bgp_debug_neighbor_events(peer))
1283 zlog_debug ("%s [FSM] Unable to get neighbor's IP address, waiting...",
1284 peer->host);
1285 return -1;
1286 }
1287
ca058a30
PJ
1288 if (BGP_PEER_START_SUPPRESSED (peer))
1289 {
16286195
DS
1290 if (bgp_debug_neighbor_events(peer))
1291 zlog_err ("%s [FSM] Trying to start suppressed peer"
ca058a30
PJ
1292 " - this is never supposed to happen!", peer->host);
1293 return -1;
1294 }
1295
33d5ab9e
PJ
1296 /* Scrub some information that might be left over from a previous,
1297 * session
1298 */
1299 /* Connection information. */
1300 if (peer->su_local)
1301 {
1302 sockunion_free (peer->su_local);
1303 peer->su_local = NULL;
1304 }
1305
1306 if (peer->su_remote)
1307 {
1308 sockunion_free (peer->su_remote);
1309 peer->su_remote = NULL;
1310 }
1311
1312 /* Clear remote router-id. */
1313 peer->remote_id.s_addr = 0;
1314
1315 /* Clear peer capability flag. */
1316 peer->cap = 0;
1317
718e3744 1318 /* If the peer is passive mode, force to move to Active mode. */
1319 if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
1320 {
1321 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
1322 return 0;
1323 }
1324
fc9a856f 1325 /* Register to be notified on peer up */
c5a5c4ff
DS
1326 if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
1327 ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
1328 && ! bgp_flag_check(peer->bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
fc9a856f 1329 connected = 1;
c5a5c4ff
DS
1330 else
1331 connected = 0;
fc9a856f 1332
65740e1b
DS
1333 if (!bgp_find_or_add_nexthop(peer->bgp, family2afi(peer->su.sa.sa_family),
1334 NULL, peer, connected))
1335 {
4d41dd8b 1336#if defined (HAVE_CUMULUS)
65740e1b 1337 if (bgp_debug_neighbor_events(peer))
c5a5c4ff
DS
1338 zlog_debug ("%s [FSM] Waiting for NHT", peer->host);
1339
1340 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
65740e1b 1341 return 0;
b5826a12 1342#endif
65740e1b
DS
1343 }
1344
718e3744 1345 status = bgp_connect (peer);
1346
1347 switch (status)
1348 {
1349 case connect_error:
16286195
DS
1350 if (bgp_debug_neighbor_events(peer))
1351 zlog_debug ("%s [FSM] Connect error", peer->host);
718e3744 1352 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
1353 break;
1354 case connect_success:
16286195 1355 if (bgp_debug_neighbor_events(peer))
5b6dc0dd
DS
1356 zlog_debug ("%s [FSM] Connect immediately success, fd %d",
1357 peer->host, peer->fd);
718e3744 1358 BGP_EVENT_ADD (peer, TCP_connection_open);
1359 break;
1360 case connect_in_progress:
1361 /* To check nonblocking connect, we wait until socket is
1362 readable or writable. */
16286195 1363 if (bgp_debug_neighbor_events(peer))
5b6dc0dd
DS
1364 zlog_debug ("%s [FSM] Non blocking connect waiting result, fd %d",
1365 peer->host, peer->fd);
eb821189 1366 if (peer->fd < 0)
718e3744 1367 {
1368 zlog_err ("bgp_start peer's fd is negative value %d",
eb821189 1369 peer->fd);
718e3744 1370 return -1;
1371 }
eb821189 1372 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1373 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
718e3744 1374 break;
1375 }
1376 return 0;
1377}
1378
1379/* Connect retry timer is expired when the peer status is Connect. */
94f2b392 1380static int
718e3744 1381bgp_reconnect (struct peer *peer)
1382{
fb98973a
DS
1383 if (bgp_stop (peer) < 0)
1384 return -1;
1ff9a340 1385
fb98973a
DS
1386 bgp_start (peer);
1387 return 0;
718e3744 1388}
1389
94f2b392 1390static int
718e3744 1391bgp_fsm_open (struct peer *peer)
1392{
1393 /* Send keepalive and make keepalive timer */
1394 bgp_keepalive_send (peer);
1395
1396 /* Reset holdtimer value. */
1397 BGP_TIMER_OFF (peer->t_holdtime);
1398
1399 return 0;
1400}
1401
718e3744 1402/* Keepalive send to peer. */
94f2b392 1403static int
718e3744 1404bgp_fsm_keepalive_expire (struct peer *peer)
1405{
1406 bgp_keepalive_send (peer);
1407 return 0;
1408}
1409
397b5bde
LR
1410/* FSM error, unexpected event. This is error of BGP connection. So cut the
1411 peer and change to Idle status. */
1412static int
1413bgp_fsm_event_error (struct peer *peer)
1414{
16286195 1415 zlog_err ("%s [FSM] unexpected packet received in state %s",
56b40679 1416 peer->host, lookup_msg(bgp_status_msg, peer->status, NULL));
397b5bde
LR
1417
1418 return bgp_stop_with_notify (peer, BGP_NOTIFY_FSM_ERR, 0);
1419}
1420
718e3744 1421/* Hold timer expire. This is error of BGP connection. So cut the
1422 peer and change to Idle status. */
94f2b392 1423static int
718e3744 1424bgp_fsm_holdtime_expire (struct peer *peer)
1425{
16286195
DS
1426 if (bgp_debug_neighbor_events(peer))
1427 zlog_debug ("%s [FSM] Hold timer expire", peer->host);
718e3744 1428
397b5bde 1429 return bgp_stop_with_notify (peer, BGP_NOTIFY_HOLD_ERR, 0);
718e3744 1430}
1431
1432/* Status goes to Established. Send keepalive packet then make first
1433 update information. */
94f2b392 1434static int
718e3744 1435bgp_establish (struct peer *peer)
1436{
718e3744 1437 afi_t afi;
1438 safi_t safi;
93406d87 1439 int nsf_af_count = 0;
1ff9a340
DS
1440 int ret = 0;
1441 struct peer *other;
1442
1443 other = peer->doppelganger;
1444 peer = peer_xfer_conn(peer);
1445 if (!peer)
1446 {
1447 zlog_err ("%%Neighbor failed in xfer_conn");
1448 return -1;
1449 }
1450
1451 if (other == peer)
1452 ret = 1; /* bgp_establish specific code when xfer_conn happens. */
718e3744 1453
1454 /* Reset capability open status flag. */
1455 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
1456 SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1457
718e3744 1458 /* Clear start timer value to default. */
1459 peer->v_start = BGP_INIT_START_TIMER;
1460
1461 /* Increment established count. */
1462 peer->established++;
1463 bgp_fsm_change_status (peer, Established);
848973c7 1464
1465 /* bgp log-neighbor-changes of neighbor Up */
1466 if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
c22767d8
DS
1467 {
1468 struct vrf *vrf = vrf_lookup_by_id (peer->bgp->vrf_id);
1469 zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Up",
1470 peer->host,
1471 (peer->hostname) ? peer->hostname : "Unknown",
c2f61344 1472 vrf ? ((vrf->vrf_id != VRF_DEFAULT ) ? vrf->name : "Default") : "");
c22767d8 1473 }
3f9c7369
DS
1474 /* assign update-group/subgroup */
1475 update_group_adjust_peer_afs(peer);
1476
93406d87 1477 /* graceful restart */
1478 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
1479 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
4d5b4f7b 1480 for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_4 ; safi++)
93406d87 1481 {
1482 if (peer->afc_nego[afi][safi]
1483 && CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV)
1484 && CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV))
1485 {
1486 if (peer->nsf[afi][safi]
1487 && ! CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV))
1488 bgp_clear_stale_route (peer, afi, safi);
1489
1490 peer->nsf[afi][safi] = 1;
1491 nsf_af_count++;
1492 }
1493 else
1494 {
1495 if (peer->nsf[afi][safi])
1496 bgp_clear_stale_route (peer, afi, safi);
1497 peer->nsf[afi][safi] = 0;
1498 }
1499 }
1500
1501 if (nsf_af_count)
1502 SET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1503 else
1504 {
1505 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1506 if (peer->t_gr_stale)
1507 {
1508 BGP_TIMER_OFF (peer->t_gr_stale);
16286195 1509 if (bgp_debug_neighbor_events(peer))
93406d87 1510 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
1511 }
1512 }
1513
1514 if (peer->t_gr_restart)
1515 {
1516 BGP_TIMER_OFF (peer->t_gr_restart);
16286195 1517 if (bgp_debug_neighbor_events(peer))
93406d87 1518 zlog_debug ("%s graceful restart timer stopped", peer->host);
1519 }
1520
3012671f 1521 hook_call(peer_established, peer);
718e3744 1522
1523 /* Reset uptime, send keepalive, send current table. */
65957886 1524 peer->uptime = bgp_clock ();
718e3744 1525
1526 /* Send route-refresh when ORF is enabled */
1527 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1528 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1529 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV))
1530 {
1531 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
1532 bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX,
1533 REFRESH_IMMEDIATE, 0);
1534 else if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
1535 bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX_OLD,
1536 REFRESH_IMMEDIATE, 0);
1537 }
1538
718e3744 1539 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1540 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1541 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1542 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV))
1543 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1544 || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
1545 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
1546
3f9c7369 1547 bgp_announce_peer (peer);
718e3744 1548
cb1faec9
DS
1549 /* Start the route advertisement timer to send updates to the peer - if BGP
1550 * is not in read-only mode. If it is, the timer will be started at the end
1551 * of read-only mode.
1552 */
1553 if (!bgp_update_delay_active(peer->bgp))
3f9c7369
DS
1554 {
1555 BGP_TIMER_OFF(peer->t_routeadv);
1556 BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, 0);
1557 }
718e3744 1558
1ff9a340
DS
1559 if (peer->doppelganger && (peer->doppelganger->status != Deleted))
1560 {
16286195 1561 if (bgp_debug_neighbor_events(peer))
1ff9a340
DS
1562 zlog_debug("[Event] Deleting stub connection for peer %s", peer->host);
1563
1564 if (peer->doppelganger->status > Active)
1565 bgp_notify_send (peer->doppelganger, BGP_NOTIFY_CEASE,
1566 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1567 else
1568 peer_delete(peer->doppelganger);
1569 }
1570
c43ed2e4 1571 bgp_bfd_register_peer(peer);
1ff9a340 1572 return ret;
718e3744 1573}
1574
1575/* Keepalive packet is received. */
94f2b392 1576static int
718e3744 1577bgp_fsm_keepalive (struct peer *peer)
1578{
f188f2c4
DS
1579 bgp_update_implicit_eors(peer);
1580
718e3744 1581 /* peer count update */
1582 peer->keepalive_in++;
1583
1584 BGP_TIMER_OFF (peer->t_holdtime);
1585 return 0;
1586}
1587
1588/* Update packet is received. */
94f2b392 1589static int
718e3744 1590bgp_fsm_update (struct peer *peer)
1591{
1592 BGP_TIMER_OFF (peer->t_holdtime);
1593 return 0;
1594}
1595
1596/* This is empty event. */
94f2b392 1597static int
718e3744 1598bgp_ignore (struct peer *peer)
1599{
5b6dc0dd 1600 zlog_err ("%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d",
6403814c 1601 peer->host, bgp_event_str[peer->cur_event],
56b40679 1602 lookup_msg(bgp_status_msg, peer->status, NULL),
6403814c 1603 bgp_event_str[peer->last_event],
5b6dc0dd 1604 bgp_event_str[peer->last_major_event], peer->fd);
718e3744 1605 return 0;
1606}
6b0655a2 1607
6403814c
DS
1608/* This is to handle unexpected events.. */
1609static int
1610bgp_fsm_exeption (struct peer *peer)
1611{
5b6dc0dd 1612 zlog_err ("%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d",
6403814c 1613 peer->host, bgp_event_str[peer->cur_event],
56b40679 1614 lookup_msg(bgp_status_msg, peer->status, NULL),
6403814c 1615 bgp_event_str[peer->last_event],
5b6dc0dd 1616 bgp_event_str[peer->last_major_event], peer->fd);
6403814c
DS
1617 return(bgp_stop (peer));
1618}
1619
fc9a856f
DS
1620void
1621bgp_fsm_nht_update(struct peer *peer, int valid)
1622{
fc9a856f
DS
1623 if (!peer)
1624 return;
1625
1626 switch (peer->status)
1627 {
1628 case Idle:
1629 if (valid)
1630 BGP_EVENT_ADD(peer, BGP_Start);
1631 break;
1632 case Connect:
c5a5c4ff 1633 if (!valid)
fc9a856f
DS
1634 {
1635 BGP_TIMER_OFF(peer->t_connect);
c5a5c4ff 1636 BGP_EVENT_ADD(peer, TCP_fatal_error);
fc9a856f
DS
1637 }
1638 break;
1639 case Active:
1640 if (valid)
1641 {
1642 BGP_TIMER_OFF(peer->t_connect);
1643 BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
1644 }
c5a5c4ff 1645 break;
fc9a856f
DS
1646 case OpenSent:
1647 case OpenConfirm:
1648 case Established:
c5a5c4ff
DS
1649 if (!valid && (peer->gtsm_hops == 1))
1650 BGP_EVENT_ADD(peer, TCP_fatal_error);
fc9a856f
DS
1651 case Clearing:
1652 case Deleted:
1653 default:
1654 break;
1655 }
1656}
1657
1658
718e3744 1659/* Finite State Machine structure */
fda1d3e0 1660static const struct {
66e5cd87 1661 int (*func) (struct peer *);
718e3744 1662 int next_state;
1663} FSM [BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] =
1664{
1665 {
1666 /* Idle state: In Idle state, all events other than BGP_Start is
1667 ignored. With BGP_Start event, finite state machine calls
1668 bgp_start(). */
1669 {bgp_start, Connect}, /* BGP_Start */
1670 {bgp_stop, Idle}, /* BGP_Stop */
1671 {bgp_stop, Idle}, /* TCP_connection_open */
1672 {bgp_stop, Idle}, /* TCP_connection_closed */
1673 {bgp_ignore, Idle}, /* TCP_connection_open_failed */
1674 {bgp_stop, Idle}, /* TCP_fatal_error */
1675 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
1676 {bgp_ignore, Idle}, /* Hold_Timer_expired */
1677 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
1678 {bgp_ignore, Idle}, /* Receive_OPEN_message */
1679 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
1680 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
1681 {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
ca058a30 1682 {bgp_ignore, Idle}, /* Clearing_Completed */
718e3744 1683 },
1684 {
1685 /* Connect */
1686 {bgp_ignore, Connect}, /* BGP_Start */
1687 {bgp_stop, Idle}, /* BGP_Stop */
1688 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
1689 {bgp_stop, Idle}, /* TCP_connection_closed */
1690 {bgp_connect_fail, Active}, /* TCP_connection_open_failed */
1691 {bgp_connect_fail, Idle}, /* TCP_fatal_error */
1692 {bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
6403814c
DS
1693 {bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
1694 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
1695 {bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
1696 {bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
1697 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
718e3744 1698 {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
6403814c 1699 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
718e3744 1700 },
1701 {
1702 /* Active, */
1703 {bgp_ignore, Active}, /* BGP_Start */
1704 {bgp_stop, Idle}, /* BGP_Stop */
1705 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
1706 {bgp_stop, Idle}, /* TCP_connection_closed */
1707 {bgp_ignore, Active}, /* TCP_connection_open_failed */
6403814c 1708 {bgp_fsm_exeption, Idle}, /* TCP_fatal_error */
718e3744 1709 {bgp_start, Connect}, /* ConnectRetry_timer_expired */
6403814c
DS
1710 {bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
1711 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
1712 {bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
1713 {bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
1714 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
1715 {bgp_fsm_exeption, Idle}, /* Receive_NOTIFICATION_message */
1716 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
718e3744 1717 },
1718 {
1719 /* OpenSent, */
1720 {bgp_ignore, OpenSent}, /* BGP_Start */
1721 {bgp_stop, Idle}, /* BGP_Stop */
536792cd 1722 {bgp_stop, Active}, /* TCP_connection_open */
718e3744 1723 {bgp_stop, Active}, /* TCP_connection_closed */
536792cd
PJ
1724 {bgp_stop, Active}, /* TCP_connection_open_failed */
1725 {bgp_stop, Active}, /* TCP_fatal_error */
6403814c 1726 {bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
718e3744 1727 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
6403814c 1728 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
718e3744 1729 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
397b5bde
LR
1730 {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
1731 {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
718e3744 1732 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
6403814c 1733 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
718e3744 1734 },
1735 {
1736 /* OpenConfirm, */
1737 {bgp_ignore, OpenConfirm}, /* BGP_Start */
1738 {bgp_stop, Idle}, /* BGP_Stop */
1739 {bgp_stop, Idle}, /* TCP_connection_open */
1740 {bgp_stop, Idle}, /* TCP_connection_closed */
1741 {bgp_stop, Idle}, /* TCP_connection_open_failed */
1742 {bgp_stop, Idle}, /* TCP_fatal_error */
6403814c 1743 {bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
718e3744 1744 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
1745 {bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
6403814c 1746 {bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
718e3744 1747 {bgp_establish, Established}, /* Receive_KEEPALIVE_message */
6403814c 1748 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
718e3744 1749 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
6403814c 1750 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
718e3744 1751 },
1752 {
1753 /* Established, */
ca058a30
PJ
1754 {bgp_ignore, Established}, /* BGP_Start */
1755 {bgp_stop, Clearing}, /* BGP_Stop */
1756 {bgp_stop, Clearing}, /* TCP_connection_open */
1757 {bgp_stop, Clearing}, /* TCP_connection_closed */
3117b5c4 1758 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
ca058a30 1759 {bgp_stop, Clearing}, /* TCP_fatal_error */
3117b5c4 1760 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
ca058a30 1761 {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
718e3744 1762 {bgp_fsm_keepalive_expire, Established}, /* KeepAlive_timer_expired */
ca058a30
PJ
1763 {bgp_stop, Clearing}, /* Receive_OPEN_message */
1764 {bgp_fsm_keepalive, Established}, /* Receive_KEEPALIVE_message */
1765 {bgp_fsm_update, Established}, /* Receive_UPDATE_message */
1766 {bgp_stop_with_error, Clearing}, /* Receive_NOTIFICATION_message */
6403814c 1767 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
ca058a30
PJ
1768 },
1769 {
1770 /* Clearing, */
1771 {bgp_ignore, Clearing}, /* BGP_Start */
3117b5c4
SH
1772 {bgp_stop, Clearing}, /* BGP_Stop */
1773 {bgp_stop, Clearing}, /* TCP_connection_open */
1774 {bgp_stop, Clearing}, /* TCP_connection_closed */
1775 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
1776 {bgp_stop, Clearing}, /* TCP_fatal_error */
1777 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
1778 {bgp_stop, Clearing}, /* Hold_Timer_expired */
1779 {bgp_stop, Clearing}, /* KeepAlive_timer_expired */
1780 {bgp_stop, Clearing}, /* Receive_OPEN_message */
1781 {bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
1782 {bgp_stop, Clearing}, /* Receive_UPDATE_message */
1783 {bgp_stop, Clearing}, /* Receive_NOTIFICATION_message */
1784 {bgp_clearing_completed, Idle}, /* Clearing_Completed */
ca058a30
PJ
1785 },
1786 {
1787 /* Deleted, */
1788 {bgp_ignore, Deleted}, /* BGP_Start */
1789 {bgp_ignore, Deleted}, /* BGP_Stop */
1790 {bgp_ignore, Deleted}, /* TCP_connection_open */
1791 {bgp_ignore, Deleted}, /* TCP_connection_closed */
1792 {bgp_ignore, Deleted}, /* TCP_connection_open_failed */
1793 {bgp_ignore, Deleted}, /* TCP_fatal_error */
1794 {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
1795 {bgp_ignore, Deleted}, /* Hold_Timer_expired */
1796 {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
1797 {bgp_ignore, Deleted}, /* Receive_OPEN_message */
1798 {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
1799 {bgp_ignore, Deleted}, /* Receive_UPDATE_message */
1800 {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */
1801 {bgp_ignore, Deleted}, /* Clearing_Completed */
718e3744 1802 },
1803};
1804
718e3744 1805/* Execute event process. */
1806int
1807bgp_event (struct thread *thread)
1808{
718e3744 1809 int event;
718e3744 1810 struct peer *peer;
1ff9a340 1811 int ret;
718e3744 1812
1813 peer = THREAD_ARG (thread);
1814 event = THREAD_VAL (thread);
1815
1ff9a340
DS
1816 ret = bgp_event_update(peer, event);
1817
1818 return (ret);
1819}
1820
1821int
1822bgp_event_update (struct peer *peer, int event)
1823{
1824 int next;
1825 int ret = 0;
1826 struct peer *other;
1827 int passive_conn = 0;
f14e6fdb 1828 int dyn_nbr;
1ff9a340
DS
1829
1830 other = peer->doppelganger;
1831 passive_conn = (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) ? 1 : 0;
f14e6fdb 1832 dyn_nbr = peer_dynamic_neighbor(peer);
1ff9a340 1833
718e3744 1834 /* Logging this event. */
1835 next = FSM [peer->status -1][event - 1].next_state;
1836
16286195 1837 if (bgp_debug_neighbor_events(peer) && peer->status != next)
5b6dc0dd 1838 zlog_debug ("%s [FSM] %s (%s->%s), fd %d", peer->host,
718e3744 1839 bgp_event_str[event],
56b40679
QY
1840 lookup_msg(bgp_status_msg, peer->status, NULL),
1841 lookup_msg(bgp_status_msg, next, NULL), peer->fd);
718e3744 1842
6403814c
DS
1843 peer->last_event = peer->cur_event;
1844 peer->cur_event = event;
1845
718e3744 1846 /* Call function. */
ca058a30
PJ
1847 if (FSM [peer->status -1][event - 1].func)
1848 ret = (*(FSM [peer->status - 1][event - 1].func))(peer);
718e3744 1849
1850 /* When function do not want proceed next job return -1. */
200df115 1851 if (ret >= 0)
1852 {
1ff9a340
DS
1853 if (ret == 1 && next == Established)
1854 {
1855 /* The case when doppelganger swap accurred in bgp_establish.
1856 Update the peer pointer accordingly */
1857 peer = other;
1858 }
1859
200df115 1860 /* If status is changed. */
1861 if (next != peer->status)
f2c31acb 1862 bgp_fsm_change_status (peer, next);
95fdcd8a 1863
200df115 1864 /* Make sure timer is set. */
1865 bgp_timer_set (peer);
1ff9a340
DS
1866
1867 }
f14e6fdb 1868 else if (!dyn_nbr && !passive_conn && peer->bgp)
1ff9a340
DS
1869 {
1870 /* If we got a return value of -1, that means there was an error, restart
1871 * the FSM. If the peer structure was deleted
1872 */
5b6dc0dd
DS
1873 zlog_err ("%s [FSM] Failure handling event %s in state %s, "
1874 "prior events %s, %s, fd %d",
6403814c 1875 peer->host, bgp_event_str[peer->cur_event],
56b40679 1876 lookup_msg(bgp_status_msg, peer->status, NULL),
6403814c 1877 bgp_event_str[peer->last_event],
5b6dc0dd 1878 bgp_event_str[peer->last_major_event], peer->fd);
6403814c 1879 bgp_stop (peer);
1ff9a340
DS
1880 bgp_fsm_change_status(peer, Idle);
1881 bgp_timer_set(peer);
200df115 1882 }
200df115 1883 return ret;
718e3744 1884}