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