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