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