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