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