]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_fsm.c
*: Convert event.h to frrevent.h
[mirror_frr.git] / bgpd / bgp_fsm.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
d62a17ae 2/* BGP-4 Finite State Machine
896014f4
DL
3 * From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
4 * Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
896014f4 5 */
718e3744 6
7#include <zebra.h>
8
9#include "linklist.h"
10#include "prefix.h"
718e3744 11#include "sockunion.h"
24a58196 12#include "frrevent.h"
718e3744 13#include "log.h"
14#include "stream.h"
74ffbfe6 15#include "ringbuf.h"
718e3744 16#include "memory.h"
17#include "plist.h"
f188f2c4 18#include "workqueue.h"
3f9c7369 19#include "queue.h"
039f3a34 20#include "filter.h"
4dcadbef 21#include "command.h"
02705213 22#include "lib_errors.h"
8c48b3b6 23#include "zclient.h"
856ca177 24#include "lib/json.h"
718e3744 25#include "bgpd/bgpd.h"
26#include "bgpd/bgp_attr.h"
27#include "bgpd/bgp_debug.h"
14454c9f 28#include "bgpd/bgp_errors.h"
718e3744 29#include "bgpd/bgp_fsm.h"
30#include "bgpd/bgp_packet.h"
31#include "bgpd/bgp_network.h"
32#include "bgpd/bgp_route.h"
33#include "bgpd/bgp_dump.h"
34#include "bgpd/bgp_open.h"
f188f2c4 35#include "bgpd/bgp_advertise.h"
1479ed2f 36#include "bgpd/bgp_community.h"
3f9c7369 37#include "bgpd/bgp_updgrp.h"
ffd0c037 38#include "bgpd/bgp_nht.h"
c43ed2e4 39#include "bgpd/bgp_bfd.h"
4a1ab8e4 40#include "bgpd/bgp_memory.h"
03014d48 41#include "bgpd/bgp_keepalives.h"
56257a44 42#include "bgpd/bgp_io.h"
c42eab4b 43#include "bgpd/bgp_zebra.h"
3742de8d 44#include "bgpd/bgp_vty.h"
6b0655a2 45
8451921b
DL
46DEFINE_HOOK(peer_backward_transition, (struct peer * peer), (peer));
47DEFINE_HOOK(peer_status_changed, (struct peer * peer), (peer));
3742de8d 48
4da144f3
DS
49enum bgp_fsm_state_progress {
50 BGP_FSM_FAILURE_AND_DELETE = -2,
51 BGP_FSM_FAILURE = -1,
52 BGP_FSM_SUCCESS = 0,
53 BGP_FSM_SUCCESS_STATE_TRANSFER = 1,
54};
55
6403814c
DS
56/* Definition of display strings corresponding to FSM events. This should be
57 * kept consistent with the events defined in bgpd.h
58 */
2b64873d 59static const char *const bgp_event_str[] = {
d62a17ae 60 NULL,
61 "BGP_Start",
62 "BGP_Stop",
63 "TCP_connection_open",
6c537a18 64 "TCP_connection_open_w_delay",
d62a17ae 65 "TCP_connection_closed",
66 "TCP_connection_open_failed",
67 "TCP_fatal_error",
68 "ConnectRetry_timer_expired",
69 "Hold_Timer_expired",
70 "KeepAlive_timer_expired",
6c537a18 71 "DelayOpen_timer_expired",
d62a17ae 72 "Receive_OPEN_message",
73 "Receive_KEEPALIVE_message",
74 "Receive_UPDATE_message",
75 "Receive_NOTIFICATION_message",
76 "Clearing_Completed",
6403814c
DS
77};
78
718e3744 79/* BGP FSM (finite state machine) has three types of functions. Type
80 one is thread functions. Type two is event functions. Type three
81 is FSM functions. Timer functions are set by bgp_timer_set
82 function. */
83
84/* BGP event function. */
e6685141 85void bgp_event(struct event *event);
718e3744 86
87/* BGP thread functions. */
e6685141
DS
88static void bgp_start_timer(struct event *event);
89static void bgp_connect_timer(struct event *event);
90static void bgp_holdtime_timer(struct event *event);
91static void bgp_delayopen_timer(struct event *event);
718e3744 92
93/* BGP FSM functions. */
4da144f3 94static enum bgp_fsm_state_progress bgp_start(struct peer *);
718e3744 95
e2d3a909 96/* Register peer with NHT */
996319e6 97int bgp_peer_reg_with_nht(struct peer *peer)
e2d3a909 98{
99 int connected = 0;
100
c8d6f0d6 101 if (peer->sort == BGP_PEER_EBGP && peer->ttl == BGP_DEFAULT_TTL
e2d3a909 102 && !CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
892fedb6 103 && !CHECK_FLAG(peer->bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
e2d3a909 104 connected = 1;
105
654a5978
PG
106 return bgp_find_or_add_nexthop(
107 peer->bgp, peer->bgp, family2afi(peer->su.sa.sa_family),
108 SAFI_UNICAST, NULL, peer, connected, NULL);
e2d3a909 109}
110
d62a17ae 111static void peer_xfer_stats(struct peer *peer_dst, struct peer *peer_src)
1ff9a340 112{
d62a17ae 113 /* Copy stats over. These are only the pre-established state stats */
114 peer_dst->open_in += peer_src->open_in;
115 peer_dst->open_out += peer_src->open_out;
116 peer_dst->keepalive_in += peer_src->keepalive_in;
117 peer_dst->keepalive_out += peer_src->keepalive_out;
118 peer_dst->notify_in += peer_src->notify_in;
119 peer_dst->notify_out += peer_src->notify_out;
120 peer_dst->dynamic_cap_in += peer_src->dynamic_cap_in;
121 peer_dst->dynamic_cap_out += peer_src->dynamic_cap_out;
1ff9a340
DS
122}
123
d62a17ae 124static struct peer *peer_xfer_conn(struct peer *from_peer)
1ff9a340 125{
d62a17ae 126 struct peer *peer;
127 afi_t afi;
128 safi_t safi;
129 int fd;
8398b5d5 130 enum bgp_fsm_status status, pstatus;
d1060698 131 enum bgp_fsm_events last_evt, last_maj_evt;
d62a17ae 132
133 assert(from_peer != NULL);
134
135 peer = from_peer->doppelganger;
136
137 if (!peer || !CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
138 return from_peer;
139
9bf904cc
DS
140 /*
141 * Let's check that we are not going to loose known configuration
142 * state based upon doppelganger rules.
143 */
144 FOREACH_AFI_SAFI (afi, safi) {
145 if (from_peer->afc[afi][safi] != peer->afc[afi][safi]) {
146 flog_err(
147 EC_BGP_DOPPELGANGER_CONFIG,
148 "from_peer->afc[%d][%d] is not the same as what we are overwriting",
149 afi, safi);
150 return NULL;
151 }
152 }
153
d62a17ae 154 if (bgp_debug_neighbor_events(peer))
155 zlog_debug("%s: peer transfer %p fd %d -> %p fd %d)",
156 from_peer->host, from_peer, from_peer->fd, peer,
157 peer->fd);
158
424ab01d
QY
159 bgp_writes_off(peer);
160 bgp_reads_off(peer);
161 bgp_writes_off(from_peer);
162 bgp_reads_off(from_peer);
d62a17ae 163
74e00a55
S
164 /*
165 * Before exchanging FD remove doppelganger from
166 * keepalive peer hash. It could be possible conf peer
167 * fd is set to -1. If blocked on lock then keepalive
168 * thread can access peer pointer with fd -1.
169 */
170 bgp_keepalives_off(from_peer);
171
e16d030c
DS
172 EVENT_OFF(peer->t_routeadv);
173 EVENT_OFF(peer->t_connect);
174 EVENT_OFF(peer->t_delayopen);
175 EVENT_OFF(peer->t_connect_check_r);
176 EVENT_OFF(peer->t_connect_check_w);
177 EVENT_OFF(from_peer->t_routeadv);
178 EVENT_OFF(from_peer->t_connect);
179 EVENT_OFF(from_peer->t_delayopen);
180 EVENT_OFF(from_peer->t_connect_check_r);
181 EVENT_OFF(from_peer->t_connect_check_w);
182 EVENT_OFF(from_peer->t_process_packet);
d3ecc69e 183
becedef6
QY
184 /*
185 * At this point in time, it is possible that there are packets pending
186 * on various buffers. Those need to be transferred or dropped,
187 * otherwise we'll get spurious failures during session establishment.
188 */
cb1991af 189 frr_with_mutex (&peer->io_mtx, &from_peer->io_mtx) {
424ab01d
QY
190 fd = peer->fd;
191 peer->fd = from_peer->fd;
192 from_peer->fd = fd;
193
194 stream_fifo_clean(peer->ibuf);
d3ecc69e 195 stream_fifo_clean(peer->obuf);
d3ecc69e 196
becedef6
QY
197 /*
198 * this should never happen, since bgp_process_packet() is the
199 * only task that sets and unsets the current packet and it
200 * runs in our pthread.
201 */
424ab01d 202 if (peer->curr) {
af4c2728 203 flog_err(
e50f7cfd 204 EC_BGP_PKT_PROCESS,
424ab01d
QY
205 "[%s] Dropping pending packet on connection transfer:",
206 peer->host);
584470fb
DL
207 /* there used to be a bgp_packet_dump call here, but
208 * that's extremely confusing since there's no way to
209 * identify the packet in MRT dumps or BMP as dropped
210 * due to connection transfer.
211 */
424ab01d
QY
212 stream_free(peer->curr);
213 peer->curr = NULL;
214 }
215
216 // copy each packet from old peer's output queue to new peer
727c4f87
QY
217 while (from_peer->obuf->head)
218 stream_fifo_push(peer->obuf,
219 stream_fifo_pop(from_peer->obuf));
424ab01d
QY
220
221 // copy each packet from old peer's input queue to new peer
222 while (from_peer->ibuf->head)
223 stream_fifo_push(peer->ibuf,
224 stream_fifo_pop(from_peer->ibuf));
7db44ec8 225
74ffbfe6
QY
226 ringbuf_wipe(peer->ibuf_work);
227 ringbuf_copy(peer->ibuf_work, from_peer->ibuf_work,
228 ringbuf_remain(from_peer->ibuf_work));
d3ecc69e 229 }
d62a17ae 230
231 peer->as = from_peer->as;
232 peer->v_holdtime = from_peer->v_holdtime;
233 peer->v_keepalive = from_peer->v_keepalive;
d62a17ae 234 peer->v_routeadv = from_peer->v_routeadv;
6c537a18 235 peer->v_delayopen = from_peer->v_delayopen;
d62a17ae 236 peer->v_gr_restart = from_peer->v_gr_restart;
237 peer->cap = from_peer->cap;
8f2d6021 238 peer->remote_role = from_peer->remote_role;
d62a17ae 239 status = peer->status;
240 pstatus = peer->ostatus;
241 last_evt = peer->last_event;
242 last_maj_evt = peer->last_major_event;
243 peer->status = from_peer->status;
244 peer->ostatus = from_peer->ostatus;
245 peer->last_event = from_peer->last_event;
246 peer->last_major_event = from_peer->last_major_event;
247 from_peer->status = status;
248 from_peer->ostatus = pstatus;
249 from_peer->last_event = last_evt;
250 from_peer->last_major_event = last_maj_evt;
251 peer->remote_id = from_peer->remote_id;
3577f1c5 252 peer->last_reset = from_peer->last_reset;
0db06e37 253 peer->max_packet_size = from_peer->max_packet_size;
d62a17ae 254
36235319
QY
255 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
256 peer->bgp->peer);
8c48b3b6 257
d7b3cda6 258 if (bgp_peer_gr_mode_get(peer) == PEER_DISABLE) {
259
260 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
261
36235319 262 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
d7b3cda6 263 peer_nsf_stop(peer);
264 }
265 }
266
d188b08f
DA
267 if (peer->hostname) {
268 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
269 peer->hostname = NULL;
270 }
d62a17ae 271 if (from_peer->hostname != NULL) {
d62a17ae 272 peer->hostname = from_peer->hostname;
273 from_peer->hostname = NULL;
274 }
275
d188b08f
DA
276 if (peer->domainname) {
277 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
278 peer->domainname = NULL;
279 }
d62a17ae 280 if (from_peer->domainname != NULL) {
d62a17ae 281 peer->domainname = from_peer->domainname;
282 from_peer->domainname = NULL;
283 }
284
234f6fd4
DA
285 if (peer->soft_version) {
286 XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version);
287 peer->soft_version = NULL;
288 }
289 if (from_peer->soft_version) {
290 peer->soft_version = from_peer->soft_version;
291 from_peer->soft_version = NULL;
292 }
293
05c7a1cc 294 FOREACH_AFI_SAFI (afi, safi) {
05c7a1cc
QY
295 peer->af_sflags[afi][safi] = from_peer->af_sflags[afi][safi];
296 peer->af_cap[afi][safi] = from_peer->af_cap[afi][safi];
297 peer->afc_nego[afi][safi] = from_peer->afc_nego[afi][safi];
298 peer->afc_adv[afi][safi] = from_peer->afc_adv[afi][safi];
299 peer->afc_recv[afi][safi] = from_peer->afc_recv[afi][safi];
300 peer->orf_plist[afi][safi] = from_peer->orf_plist[afi][safi];
1479ed2f 301 peer->llgr[afi][safi] = from_peer->llgr[afi][safi];
05c7a1cc 302 }
d62a17ae 303
304 if (bgp_getsockname(peer) < 0) {
af4c2728 305 flog_err(
450971aa 306 EC_LIB_SOCKET,
d62a17ae 307 "%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
308 (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)
309 ? "accept"
310 : ""),
311 peer->host, peer->fd, from_peer->fd);
6c4d8732
SP
312 BGP_EVENT_ADD(peer, BGP_Stop);
313 BGP_EVENT_ADD(from_peer, BGP_Stop);
d62a17ae 314 return NULL;
315 }
316 if (from_peer->status > Active) {
317 if (bgp_getsockname(from_peer) < 0) {
af4c2728 318 flog_err(
450971aa 319 EC_LIB_SOCKET,
d62a17ae 320 "%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
14454c9f 321
d62a17ae 322 (CHECK_FLAG(from_peer->sflags,
323 PEER_STATUS_ACCEPT_PEER)
324 ? "accept"
325 : ""),
326 from_peer->host, from_peer->fd, peer->fd);
327 bgp_stop(from_peer);
328 from_peer = NULL;
329 }
330 }
331
0112e9e0
QY
332
333 // Note: peer_xfer_stats() must be called with I/O turned OFF
334 if (from_peer)
335 peer_xfer_stats(peer, from_peer);
336
e2d3a909 337 /* Register peer for NHT. This is to allow RAs to be enabled when
338 * needed, even on a passive connection.
339 */
340 bgp_peer_reg_with_nht(peer);
996319e6
DS
341 if (from_peer)
342 bgp_replace_nexthop_by_peer(from_peer, peer);
e2d3a909 343
424ab01d
QY
344 bgp_reads_on(peer);
345 bgp_writes_on(peer);
907a2395
DS
346 event_add_event(bm->master, bgp_process_packet, peer, 0,
347 &peer->t_process_packet);
d62a17ae 348
d62a17ae 349 return (peer);
1ff9a340
DS
350}
351
718e3744 352/* Hook function called after bgp event is occered. And vty's
353 neighbor command invoke this function after making neighbor
354 structure. */
d62a17ae 355void bgp_timer_set(struct peer *peer)
718e3744 356{
1479ed2f
DA
357 afi_t afi;
358 safi_t safi;
359
d62a17ae 360 switch (peer->status) {
361 case Idle:
362 /* First entry point of peer's finite state machine. In Idle
363 status start timer is on unless peer is shutdown or peer is
364 inactive. All other timer must be turned off */
f62abc7d 365 if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(peer)
2c1eba8e 366 || peer->bgp->vrf_id == VRF_UNKNOWN) {
e16d030c 367 EVENT_OFF(peer->t_start);
d62a17ae 368 } else {
369 BGP_TIMER_ON(peer->t_start, bgp_start_timer,
370 peer->v_start);
371 }
e16d030c
DS
372 EVENT_OFF(peer->t_connect);
373 EVENT_OFF(peer->t_holdtime);
b72b6f4f 374 bgp_keepalives_off(peer);
e16d030c
DS
375 EVENT_OFF(peer->t_routeadv);
376 EVENT_OFF(peer->t_delayopen);
d62a17ae 377 break;
378
379 case Connect:
380 /* After start timer is expired, the peer moves to Connect
381 status. Make sure start timer is off and connect timer is
382 on. */
e16d030c 383 EVENT_OFF(peer->t_start);
6c537a18
DS
384 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
385 BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
386 (peer->v_delayopen + peer->v_connect));
387 else
388 BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
389 peer->v_connect);
390
e16d030c 391 EVENT_OFF(peer->t_holdtime);
b72b6f4f 392 bgp_keepalives_off(peer);
e16d030c 393 EVENT_OFF(peer->t_routeadv);
d62a17ae 394 break;
395
396 case Active:
397 /* Active is waiting connection from remote peer. And if
398 connect timer is expired, change status to Connect. */
e16d030c 399 EVENT_OFF(peer->t_start);
d62a17ae 400 /* If peer is passive mode, do not set connect timer. */
401 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)
402 || CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
e16d030c 403 EVENT_OFF(peer->t_connect);
d62a17ae 404 } else {
6c537a18
DS
405 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
406 BGP_TIMER_ON(
407 peer->t_connect, bgp_connect_timer,
408 (peer->v_delayopen + peer->v_connect));
409 else
410 BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
411 peer->v_connect);
d62a17ae 412 }
e16d030c 413 EVENT_OFF(peer->t_holdtime);
b72b6f4f 414 bgp_keepalives_off(peer);
e16d030c 415 EVENT_OFF(peer->t_routeadv);
d62a17ae 416 break;
417
418 case OpenSent:
419 /* OpenSent status. */
e16d030c
DS
420 EVENT_OFF(peer->t_start);
421 EVENT_OFF(peer->t_connect);
d62a17ae 422 if (peer->v_holdtime != 0) {
423 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
424 peer->v_holdtime);
425 } else {
e16d030c 426 EVENT_OFF(peer->t_holdtime);
d62a17ae 427 }
b72b6f4f 428 bgp_keepalives_off(peer);
e16d030c
DS
429 EVENT_OFF(peer->t_routeadv);
430 EVENT_OFF(peer->t_delayopen);
d62a17ae 431 break;
432
433 case OpenConfirm:
434 /* OpenConfirm status. */
e16d030c
DS
435 EVENT_OFF(peer->t_start);
436 EVENT_OFF(peer->t_connect);
d62a17ae 437
aa554d4b
DS
438 /*
439 * If the negotiated Hold Time value is zero, then the Hold Time
440 * timer and KeepAlive timers are not started.
441 * Additionally if a different hold timer has been negotiated
442 * than we must stop then start the timer again
443 */
e16d030c 444 EVENT_OFF(peer->t_holdtime);
aa554d4b 445 if (peer->v_holdtime == 0)
b72b6f4f 446 bgp_keepalives_off(peer);
aa554d4b 447 else {
d62a17ae 448 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
449 peer->v_holdtime);
b72b6f4f 450 bgp_keepalives_on(peer);
d62a17ae 451 }
e16d030c
DS
452 EVENT_OFF(peer->t_routeadv);
453 EVENT_OFF(peer->t_delayopen);
d62a17ae 454 break;
455
456 case Established:
457 /* In Established status start and connect timer is turned
458 off. */
e16d030c
DS
459 EVENT_OFF(peer->t_start);
460 EVENT_OFF(peer->t_connect);
461 EVENT_OFF(peer->t_delayopen);
d62a17ae 462
aa554d4b
DS
463 /*
464 * Same as OpenConfirm, if holdtime is zero then both holdtime
465 * and keepalive must be turned off.
466 * Additionally if a different hold timer has been negotiated
467 * then we must stop then start the timer again
468 */
e16d030c 469 EVENT_OFF(peer->t_holdtime);
aa554d4b 470 if (peer->v_holdtime == 0)
bea01226 471 bgp_keepalives_off(peer);
aa554d4b 472 else {
d62a17ae 473 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
474 peer->v_holdtime);
bea01226 475 bgp_keepalives_on(peer);
d62a17ae 476 }
477 break;
478 case Deleted:
e16d030c
DS
479 EVENT_OFF(peer->t_gr_restart);
480 EVENT_OFF(peer->t_gr_stale);
1479ed2f
DA
481
482 FOREACH_AFI_SAFI (afi, safi)
e16d030c 483 EVENT_OFF(peer->t_llgr_stale[afi][safi]);
1479ed2f 484
e16d030c
DS
485 EVENT_OFF(peer->t_pmax_restart);
486 EVENT_OFF(peer->t_refresh_stalepath);
d62a17ae 487 /* fallthru */
488 case Clearing:
e16d030c
DS
489 EVENT_OFF(peer->t_start);
490 EVENT_OFF(peer->t_connect);
491 EVENT_OFF(peer->t_holdtime);
b72b6f4f 492 bgp_keepalives_off(peer);
e16d030c
DS
493 EVENT_OFF(peer->t_routeadv);
494 EVENT_OFF(peer->t_delayopen);
d62a17ae 495 break;
8398b5d5
DS
496 case BGP_STATUS_MAX:
497 flog_err(EC_LIB_DEVELOPMENT,
498 "BGP_STATUS_MAX while a legal state is not valid state for the FSM");
499 break;
718e3744 500 }
718e3744 501}
502
503/* BGP start timer. This function set BGP_Start event to thread value
504 and process event. */
e6685141 505static void bgp_start_timer(struct event *thread)
718e3744 506{
d62a17ae 507 struct peer *peer;
718e3744 508
e16d030c 509 peer = EVENT_ARG(thread);
718e3744 510
d62a17ae 511 if (bgp_debug_neighbor_events(peer))
512 zlog_debug("%s [FSM] Timer (start timer expire).", peer->host);
718e3744 513
e16d030c 514 EVENT_VAL(thread) = BGP_Start;
d62a17ae 515 bgp_event(thread); /* bgp_event unlocks peer */
718e3744 516}
517
518/* BGP connect retry timer. */
e6685141 519static void bgp_connect_timer(struct event *thread)
718e3744 520{
d62a17ae 521 struct peer *peer;
d62a17ae 522
e16d030c 523 peer = EVENT_ARG(thread);
424ab01d 524
6c537a18 525 /* stop the DelayOpenTimer if it is running */
e16d030c 526 EVENT_OFF(peer->t_delayopen);
6c537a18 527
424ab01d
QY
528 assert(!peer->t_write);
529 assert(!peer->t_read);
530
d62a17ae 531 if (bgp_debug_neighbor_events(peer))
532 zlog_debug("%s [FSM] Timer (connect timer expire)", peer->host);
533
cc9f21da 534 if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
d62a17ae 535 bgp_stop(peer);
cc9f21da 536 else {
e16d030c 537 EVENT_VAL(thread) = ConnectRetry_timer_expired;
d62a17ae 538 bgp_event(thread); /* bgp_event unlocks peer */
d62a17ae 539 }
718e3744 540}
541
542/* BGP holdtime timer. */
e6685141 543static void bgp_holdtime_timer(struct event *thread)
718e3744 544{
d0874d19 545 atomic_size_t inq_count;
d62a17ae 546 struct peer *peer;
718e3744 547
e16d030c 548 peer = EVENT_ARG(thread);
718e3744 549
d62a17ae 550 if (bgp_debug_neighbor_events(peer))
551 zlog_debug("%s [FSM] Timer (holdtime timer expire)",
552 peer->host);
718e3744 553
d0874d19
DS
554 /*
555 * Given that we do not have any expectation of ordering
556 * for handling packets from a peer -vs- handling
557 * the hold timer for a peer as that they are both
558 * events on the peer. If we have incoming
559 * data on the peers inq, let's give the system a chance
560 * to handle that data. This can be especially true
561 * for systems where we are heavily loaded for one
562 * reason or another.
563 */
564 inq_count = atomic_load_explicit(&peer->ibuf->count,
565 memory_order_relaxed);
cc9f21da 566 if (inq_count)
d0874d19
DS
567 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
568 peer->v_holdtime);
569
e16d030c 570 EVENT_VAL(thread) = Hold_Timer_expired;
d62a17ae 571 bgp_event(thread); /* bgp_event unlocks peer */
718e3744 572}
573
e6685141 574void bgp_routeadv_timer(struct event *thread)
718e3744 575{
d62a17ae 576 struct peer *peer;
718e3744 577
e16d030c 578 peer = EVENT_ARG(thread);
718e3744 579
d62a17ae 580 if (bgp_debug_neighbor_events(peer))
581 zlog_debug("%s [FSM] Timer (routeadv timer expire)",
582 peer->host);
718e3744 583
083ec940 584 peer->synctime = monotime(NULL);
718e3744 585
907a2395
DS
586 event_add_timer_msec(bm->master, bgp_generate_updgrp_packets, peer, 0,
587 &peer->t_generate_updgrp_packets);
424ab01d 588
d62a17ae 589 /* MRAI timer will be started again when FIFO is built, no need to
590 * do it here.
591 */
718e3744 592}
593
6c537a18 594/* RFC 4271 DelayOpenTimer */
e6685141 595void bgp_delayopen_timer(struct event *thread)
6c537a18
DS
596{
597 struct peer *peer;
598
e16d030c 599 peer = EVENT_ARG(thread);
6c537a18
DS
600
601 if (bgp_debug_neighbor_events(peer))
602 zlog_debug("%s [FSM] Timer (DelayOpentimer expire)",
603 peer->host);
604
e16d030c 605 EVENT_VAL(thread) = DelayOpen_timer_expired;
6c537a18 606 bgp_event(thread); /* bgp_event unlocks peer */
6c537a18
DS
607}
608
e0701b79 609/* BGP Peer Down Cause */
2b64873d 610const char *const peer_down_str[] = {"",
6029afbc
DS
611 "Router ID changed",
612 "Remote AS changed",
613 "Local AS change",
614 "Cluster ID changed",
615 "Confederation identifier changed",
616 "Confederation peer changed",
617 "RR client config change",
618 "RS client config change",
619 "Update source change",
620 "Address family activated",
621 "Admin. shutdown",
622 "User reset",
623 "BGP Notification received",
624 "BGP Notification send",
625 "Peer closed the session",
626 "Neighbor deleted",
627 "Peer-group add member",
628 "Peer-group delete member",
629 "Capability changed",
630 "Passive config change",
631 "Multihop config change",
632 "NSF peer closed the session",
633 "Intf peering v6only config change",
634 "BFD down received",
635 "Interface down",
636 "Neighbor address lost",
637 "No path to specified Neighbor",
638 "Waiting for Peer IPv6 LLA",
639 "Waiting for VRF to be initialized",
640 "No AFI/SAFI activated for peer",
641 "AS Set config change",
642 "Waiting for peer OPEN",
643 "Reached received prefix count",
5597214c
DA
644 "Socket Error",
645 "Admin. shutdown (RTT)"};
d62a17ae 646
1479ed2f 647static void bgp_graceful_restart_timer_off(struct peer *peer)
e0701b79 648{
d62a17ae 649 afi_t afi;
650 safi_t safi;
651
1479ed2f
DA
652 FOREACH_AFI_SAFI (afi, safi)
653 if (CHECK_FLAG(peer->af_sflags[afi][safi],
654 PEER_STATUS_LLGR_WAIT))
655 return;
d62a17ae 656
657 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
e16d030c 658 EVENT_OFF(peer->t_gr_stale);
af8496af
DA
659
660 if (peer_dynamic_neighbor(peer) &&
661 !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
662 if (bgp_debug_neighbor_events(peer))
31afff83
DA
663 zlog_debug("%s (dynamic neighbor) deleted (%s)",
664 peer->host, __func__);
af8496af
DA
665 peer_delete(peer);
666 }
667
1479ed2f
DA
668 bgp_timer_set(peer);
669}
670
e6685141 671static void bgp_llgr_stale_timer_expire(struct event *thread)
1479ed2f
DA
672{
673 struct peer_af *paf;
674 struct peer *peer;
675 afi_t afi;
676 safi_t safi;
677
e16d030c 678 paf = EVENT_ARG(thread);
1479ed2f
DA
679
680 peer = paf->peer;
681 afi = paf->afi;
682 safi = paf->safi;
683
684 /* If the timer for the "Long-lived Stale Time" expires before the
685 * session is re-established, the helper MUST delete all the
686 * stale routes from the neighbor that it is retaining.
687 */
688 if (bgp_debug_neighbor_events(peer))
f70c91dc 689 zlog_debug("%pBP Long-lived stale timer (%s) expired", peer,
1479ed2f
DA
690 get_afi_safi_str(afi, safi, false));
691
692 UNSET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_LLGR_WAIT);
693
694 bgp_clear_stale_route(peer, afi, safi);
695
696 bgp_graceful_restart_timer_off(peer);
1479ed2f
DA
697}
698
699static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi)
700{
701 struct bgp_dest *dest;
702 struct bgp_path_info *pi;
703 struct bgp_table *table;
704 struct attr attr;
705
706 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
707 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
708 dest = bgp_route_next(dest)) {
709 struct bgp_dest *rm;
710
711 table = bgp_dest_get_bgp_table_info(dest);
712 if (!table)
713 continue;
714
715 for (rm = bgp_table_top(table); rm;
716 rm = bgp_route_next(rm))
717 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
718 pi = pi->next) {
719 if (pi->peer != peer)
720 continue;
721
9a706b42 722 if (bgp_attr_get_community(pi->attr) &&
1479ed2f 723 community_include(
9a706b42
DA
724 bgp_attr_get_community(
725 pi->attr),
1479ed2f
DA
726 COMMUNITY_NO_LLGR))
727 continue;
728
729 if (bgp_debug_neighbor_events(peer))
730 zlog_debug(
f70c91dc
DA
731 "%pBP Long-lived set stale community (LLGR_STALE) for: %pFX",
732 peer, &dest->p);
1479ed2f
DA
733
734 attr = *pi->attr;
735 bgp_attr_add_llgr_community(&attr);
736 pi->attr = bgp_attr_intern(&attr);
737 bgp_recalculate_afi_safi_bestpaths(
738 peer->bgp, afi, safi);
739
740 break;
741 }
742 }
743 } else {
744 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
745 dest = bgp_route_next(dest))
746 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
747 pi = pi->next) {
748 if (pi->peer != peer)
749 continue;
750
9a706b42
DA
751 if (bgp_attr_get_community(pi->attr) &&
752 community_include(
753 bgp_attr_get_community(pi->attr),
754 COMMUNITY_NO_LLGR))
1479ed2f
DA
755 continue;
756
757 if (bgp_debug_neighbor_events(peer))
758 zlog_debug(
f70c91dc
DA
759 "%pBP Long-lived set stale community (LLGR_STALE) for: %pFX",
760 peer, &dest->p);
1479ed2f
DA
761
762 attr = *pi->attr;
763 bgp_attr_add_llgr_community(&attr);
764 pi->attr = bgp_attr_intern(&attr);
765 bgp_recalculate_afi_safi_bestpaths(peer->bgp,
766 afi, safi);
767
768 break;
769 }
770 }
771}
772
e6685141 773static void bgp_graceful_restart_timer_expire(struct event *thread)
1479ed2f
DA
774{
775 struct peer *peer, *tmp_peer;
776 struct listnode *node, *nnode;
777 struct peer_af *paf;
778 afi_t afi;
779 safi_t safi;
780
e16d030c 781 peer = EVENT_ARG(thread);
d62a17ae 782
783 if (bgp_debug_neighbor_events(peer)) {
f70c91dc
DA
784 zlog_debug("%pBP graceful restart timer expired", peer);
785 zlog_debug("%pBP graceful restart stalepath timer stopped",
786 peer);
d62a17ae 787 }
93406d87 788
1479ed2f
DA
789 FOREACH_AFI_SAFI (afi, safi) {
790 if (!peer->nsf[afi][safi])
791 continue;
792
793 /* Once the "Restart Time" period ends, the LLGR period is
794 * said to have begun and the following procedures MUST be
795 * performed:
796 *
797 * The helper router MUST start a timer for the
798 * "Long-lived Stale Time".
799 *
800 * The helper router MUST attach the LLGR_STALE community
801 * for the stale routes being retained. Note that this
802 * requirement implies that the routes would need to be
803 * readvertised, to disseminate the modified community.
804 */
805 if (peer->llgr[afi][safi].stale_time) {
806 paf = peer_af_find(peer, afi, safi);
807 if (!paf)
808 continue;
809
810 if (bgp_debug_neighbor_events(peer))
811 zlog_debug(
f70c91dc
DA
812 "%pBP Long-lived stale timer (%s) started for %d sec",
813 peer,
1479ed2f
DA
814 get_afi_safi_str(afi, safi, false),
815 peer->llgr[afi][safi].stale_time);
816
817 SET_FLAG(peer->af_sflags[afi][safi],
818 PEER_STATUS_LLGR_WAIT);
819
820 bgp_set_llgr_stale(peer, afi, safi);
821 bgp_clear_stale_route(peer, afi, safi);
822
907a2395
DS
823 event_add_timer(bm->master, bgp_llgr_stale_timer_expire,
824 paf, peer->llgr[afi][safi].stale_time,
825 &peer->t_llgr_stale[afi][safi]);
1479ed2f
DA
826
827 for (ALL_LIST_ELEMENTS(peer->bgp->peer, node, nnode,
828 tmp_peer))
829 bgp_announce_route(tmp_peer, afi, safi, false);
830 } else {
831 bgp_clear_stale_route(peer, afi, safi);
832 }
833 }
834
835 bgp_graceful_restart_timer_off(peer);
93406d87 836}
837
e6685141 838static void bgp_graceful_stale_timer_expire(struct event *thread)
93406d87 839{
d62a17ae 840 struct peer *peer;
841 afi_t afi;
842 safi_t safi;
93406d87 843
e16d030c 844 peer = EVENT_ARG(thread);
93406d87 845
d62a17ae 846 if (bgp_debug_neighbor_events(peer))
f70c91dc
DA
847 zlog_debug("%pBP graceful restart stalepath timer expired",
848 peer);
93406d87 849
d62a17ae 850 /* NSF delete stale route */
df8d723c
DA
851 FOREACH_AFI_SAFI_NSF (afi, safi)
852 if (peer->nsf[afi][safi])
853 bgp_clear_stale_route(peer, afi, safi);
93406d87 854}
855
f009ff26 856/* Selection deferral timer processing function */
e6685141 857static void bgp_graceful_deferral_timer_expire(struct event *thread)
f009ff26 858{
859 struct afi_safi_info *info;
860 afi_t afi;
861 safi_t safi;
862 struct bgp *bgp;
863
e16d030c 864 info = EVENT_ARG(thread);
f009ff26 865 afi = info->afi;
866 safi = info->safi;
867 bgp = info->bgp;
868
869 if (BGP_DEBUG(update, UPDATE_OUT))
13909c4f
DS
870 zlog_debug(
871 "afi %d, safi %d : graceful restart deferral timer expired",
872 afi, safi);
f009ff26 873
f009ff26 874 bgp->gr_info[afi][safi].eor_required = 0;
875 bgp->gr_info[afi][safi].eor_received = 0;
876 XFREE(MTYPE_TMP, info);
877
878 /* Best path selection */
cc9f21da 879 bgp_best_path_select_defer(bgp, afi, safi);
f009ff26 880}
881
3dc339cd 882static bool bgp_update_delay_applicable(struct bgp *bgp)
f188f2c4 883{
d62a17ae 884 /* update_delay_over flag should be reset (set to 0) for any new
885 applicability of the update-delay during BGP process lifetime.
886 And it should be set after an occurence of the update-delay is
887 over)*/
888 if (!bgp->update_delay_over)
3dc339cd
DA
889 return true;
890 return false;
f188f2c4
DS
891}
892
3dc339cd 893bool bgp_update_delay_active(struct bgp *bgp)
f188f2c4 894{
d62a17ae 895 if (bgp->t_update_delay)
3dc339cd
DA
896 return true;
897 return false;
f188f2c4
DS
898}
899
3dc339cd 900bool bgp_update_delay_configured(struct bgp *bgp)
f188f2c4 901{
d62a17ae 902 if (bgp->v_update_delay)
3dc339cd
DA
903 return true;
904 return false;
f188f2c4
DS
905}
906
907/* Do the post-processing needed when bgp comes out of the read-only mode
908 on ending the update delay. */
d62a17ae 909void bgp_update_delay_end(struct bgp *bgp)
f188f2c4 910{
e16d030c
DS
911 EVENT_OFF(bgp->t_update_delay);
912 EVENT_OFF(bgp->t_establish_wait);
d62a17ae 913
914 /* Reset update-delay related state */
915 bgp->update_delay_over = 1;
916 bgp->established = 0;
917 bgp->restarted_peers = 0;
918 bgp->implicit_eors = 0;
919 bgp->explicit_eors = 0;
920
e36f61b5
DS
921 frr_timestamp(3, bgp->update_delay_end_time,
922 sizeof(bgp->update_delay_end_time));
d62a17ae 923
924 /*
925 * Add an end-of-initial-update marker to the main process queues so
926 * that
927 * the route advertisement timer for the peers can be started. Also set
928 * the zebra and peer update hold flags. These flags are used to achieve
929 * three stages in the update-delay post processing:
930 * 1. Finish best-path selection for all the prefixes held on the
931 * queues.
932 * (routes in BGP are updated, and peers sync queues are populated
933 * too)
934 * 2. As the eoiu mark is reached in the bgp process routine, ship all
935 * the
936 * routes to zebra. With that zebra should see updates from BGP
937 * close
938 * to each other.
939 * 3. Unblock the peer update writes. With that peer update packing
940 * with
941 * the prefixes should be at its maximum.
942 */
943 bgp_add_eoiu_mark(bgp);
944 bgp->main_zebra_update_hold = 1;
945 bgp->main_peers_update_hold = 1;
946
b6c386bb
DS
947 /*
948 * Resume the queue processing. This should trigger the event that would
949 * take care of processing any work that was queued during the read-only
950 * mode.
951 */
952 work_queue_unplug(bgp->process_queue);
f188f2c4
DS
953}
954
cb1faec9
DS
955/**
956 * see bgp_fsm.h
957 */
d62a17ae 958void bgp_start_routeadv(struct bgp *bgp)
cb1faec9 959{
d62a17ae 960 struct listnode *node, *nnode;
961 struct peer *peer;
cb1faec9 962
a10c2872 963 zlog_info("%s, update hold status %d", __func__,
d62a17ae 964 bgp->main_peers_update_hold);
4a16ae86 965
d62a17ae 966 if (bgp->main_peers_update_hold)
967 return;
4a16ae86 968
e36f61b5
DS
969 frr_timestamp(3, bgp->update_delay_peers_resume_time,
970 sizeof(bgp->update_delay_peers_resume_time));
4a16ae86 971
d62a17ae 972 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
feb17238 973 if (!peer_established(peer))
d62a17ae 974 continue;
e16d030c 975 EVENT_OFF(peer->t_routeadv);
d62a17ae 976 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
977 }
cb1faec9
DS
978}
979
980/**
981 * see bgp_fsm.h
982 */
d62a17ae 983void bgp_adjust_routeadv(struct peer *peer)
cb1faec9 984{
083ec940 985 time_t nowtime = monotime(NULL);
d62a17ae 986 double diff;
987 unsigned long remain;
988
989 /* Bypass checks for special case of MRAI being 0 */
990 if (peer->v_routeadv == 0) {
991 /* Stop existing timer, just in case it is running for a
992 * different
993 * duration and schedule write thread immediately.
994 */
e16d030c 995 EVENT_OFF(peer->t_routeadv);
d62a17ae 996
083ec940 997 peer->synctime = monotime(NULL);
a77e2f4b
S
998 /* If suppress fib pending is enabled, route is advertised to
999 * peers when the status is received from the FIB. The delay
1000 * is added to update group packet generate which will allow
1001 * more routes to be sent in the update message
1002 */
1003 BGP_UPDATE_GROUP_TIMER_ON(&peer->t_generate_updgrp_packets,
1004 bgp_generate_updgrp_packets);
d62a17ae 1005 return;
1006 }
1007
1008
1009 /*
1010 * CASE I:
1011 * If the last update was written more than MRAI back, expire the timer
1012 * instantly so that we can send the update out sooner.
1013 *
1014 * <------- MRAI --------->
1015 * |-----------------|-----------------------|
1016 * <------------- m ------------>
1017 * ^ ^ ^
1018 * | | |
1019 * | | current time
1020 * | timer start
1021 * last write
1022 *
1023 * m > MRAI
1024 */
1025 diff = difftime(nowtime, peer->last_update);
1026 if (diff > (double)peer->v_routeadv) {
e16d030c 1027 EVENT_OFF(peer->t_routeadv);
d62a17ae 1028 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
1029 return;
1030 }
1031
1032 /*
1033 * CASE II:
1034 * - Find when to expire the MRAI timer.
1035 * If MRAI timer is not active, assume we can start it now.
1036 *
1037 * <------- MRAI --------->
1038 * |------------|-----------------------|
1039 * <-------- m ----------><----- r ----->
1040 * ^ ^ ^
1041 * | | |
1042 * | | current time
1043 * | timer start
1044 * last write
1045 *
1046 * (MRAI - m) < r
1047 */
1048 if (peer->t_routeadv)
4f830a07 1049 remain = event_timer_remain_second(peer->t_routeadv);
d62a17ae 1050 else
1051 remain = peer->v_routeadv;
1052 diff = peer->v_routeadv - diff;
1053 if (diff <= (double)remain) {
e16d030c 1054 EVENT_OFF(peer->t_routeadv);
d62a17ae 1055 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, diff);
1056 }
cb1faec9
DS
1057}
1058
3dc339cd 1059static bool bgp_maxmed_onstartup_applicable(struct bgp *bgp)
abc920f8 1060{
d62a17ae 1061 if (!bgp->maxmed_onstartup_over)
3dc339cd
DA
1062 return true;
1063 return false;
abc920f8
DS
1064}
1065
3dc339cd 1066bool bgp_maxmed_onstartup_configured(struct bgp *bgp)
abc920f8 1067{
d62a17ae 1068 if (bgp->v_maxmed_onstartup != BGP_MAXMED_ONSTARTUP_UNCONFIGURED)
3dc339cd
DA
1069 return true;
1070 return false;
abc920f8
DS
1071}
1072
3dc339cd 1073bool bgp_maxmed_onstartup_active(struct bgp *bgp)
abc920f8 1074{
d62a17ae 1075 if (bgp->t_maxmed_onstartup)
3dc339cd
DA
1076 return true;
1077 return false;
abc920f8
DS
1078}
1079
d62a17ae 1080void bgp_maxmed_update(struct bgp *bgp)
abc920f8 1081{
d7c0a89a
QY
1082 uint8_t maxmed_active;
1083 uint32_t maxmed_value;
d62a17ae 1084
1085 if (bgp->v_maxmed_admin) {
1086 maxmed_active = 1;
1087 maxmed_value = bgp->maxmed_admin_value;
1088 } else if (bgp->t_maxmed_onstartup) {
1089 maxmed_active = 1;
1090 maxmed_value = bgp->maxmed_onstartup_value;
1091 } else {
1092 maxmed_active = 0;
1093 maxmed_value = BGP_MAXMED_VALUE_DEFAULT;
1094 }
1095
1096 if (bgp->maxmed_active != maxmed_active
1097 || bgp->maxmed_value != maxmed_value) {
1098 bgp->maxmed_active = maxmed_active;
1099 bgp->maxmed_value = maxmed_value;
1100
1101 update_group_announce(bgp);
1102 }
abc920f8
DS
1103}
1104
3893aeee
DA
1105int bgp_fsm_error_subcode(int status)
1106{
1107 int fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_UNSPECIFIC;
1108
1109 switch (status) {
1110 case OpenSent:
1111 fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_OPENSENT;
1112 break;
1113 case OpenConfirm:
1114 fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_OPENCONFIRM;
1115 break;
1116 case Established:
1117 fsm_err_subcode = BGP_NOTIFY_FSM_ERR_SUBCODE_ESTABLISHED;
1118 break;
1119 default:
1120 break;
1121 }
1122
1123 return fsm_err_subcode;
1124}
1125
abc920f8 1126/* The maxmed onstartup timer expiry callback. */
e6685141 1127static void bgp_maxmed_onstartup_timer(struct event *thread)
abc920f8 1128{
d62a17ae 1129 struct bgp *bgp;
abc920f8 1130
d62a17ae 1131 zlog_info("Max med on startup ended - timer expired.");
abc920f8 1132
e16d030c
DS
1133 bgp = EVENT_ARG(thread);
1134 EVENT_OFF(bgp->t_maxmed_onstartup);
d62a17ae 1135 bgp->maxmed_onstartup_over = 1;
abc920f8 1136
d62a17ae 1137 bgp_maxmed_update(bgp);
abc920f8
DS
1138}
1139
d62a17ae 1140static void bgp_maxmed_onstartup_begin(struct bgp *bgp)
abc920f8 1141{
d62a17ae 1142 /* Applicable only once in the process lifetime on the startup */
1143 if (bgp->maxmed_onstartup_over)
1144 return;
abc920f8 1145
d62a17ae 1146 zlog_info("Begin maxmed onstartup mode - timer %d seconds",
1147 bgp->v_maxmed_onstartup);
abc920f8 1148
907a2395
DS
1149 event_add_timer(bm->master, bgp_maxmed_onstartup_timer, bgp,
1150 bgp->v_maxmed_onstartup, &bgp->t_maxmed_onstartup);
abc920f8 1151
d62a17ae 1152 if (!bgp->v_maxmed_admin) {
1153 bgp->maxmed_active = 1;
1154 bgp->maxmed_value = bgp->maxmed_onstartup_value;
1155 }
abc920f8 1156
d62a17ae 1157 /* Route announce to all peers should happen after this in
1158 * bgp_establish() */
abc920f8
DS
1159}
1160
d62a17ae 1161static void bgp_maxmed_onstartup_process_status_change(struct peer *peer)
abc920f8 1162{
feb17238 1163 if (peer_established(peer) && !peer->bgp->established) {
d62a17ae 1164 bgp_maxmed_onstartup_begin(peer->bgp);
1165 }
abc920f8
DS
1166}
1167
f188f2c4 1168/* The update delay timer expiry callback. */
e6685141 1169static void bgp_update_delay_timer(struct event *thread)
f188f2c4 1170{
d62a17ae 1171 struct bgp *bgp;
f188f2c4 1172
d62a17ae 1173 zlog_info("Update delay ended - timer expired.");
f188f2c4 1174
e16d030c
DS
1175 bgp = EVENT_ARG(thread);
1176 EVENT_OFF(bgp->t_update_delay);
d62a17ae 1177 bgp_update_delay_end(bgp);
f188f2c4
DS
1178}
1179
1180/* The establish wait timer expiry callback. */
e6685141 1181static void bgp_establish_wait_timer(struct event *thread)
f188f2c4 1182{
d62a17ae 1183 struct bgp *bgp;
f188f2c4 1184
d62a17ae 1185 zlog_info("Establish wait - timer expired.");
f188f2c4 1186
e16d030c
DS
1187 bgp = EVENT_ARG(thread);
1188 EVENT_OFF(bgp->t_establish_wait);
d62a17ae 1189 bgp_check_update_delay(bgp);
f188f2c4
DS
1190}
1191
1192/* Steps to begin the update delay:
1193 - initialize queues if needed
1194 - stop the queue processing
1195 - start the timer */
d62a17ae 1196static void bgp_update_delay_begin(struct bgp *bgp)
f188f2c4 1197{
d62a17ae 1198 struct listnode *node, *nnode;
1199 struct peer *peer;
f188f2c4 1200
d62a17ae 1201 /* Stop the processing of queued work. Enqueue shall continue */
b6c386bb 1202 work_queue_plug(bgp->process_queue);
f188f2c4 1203
d62a17ae 1204 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
1205 peer->update_delay_over = 0;
f188f2c4 1206
d62a17ae 1207 /* Start the update-delay timer */
907a2395
DS
1208 event_add_timer(bm->master, bgp_update_delay_timer, bgp,
1209 bgp->v_update_delay, &bgp->t_update_delay);
f188f2c4 1210
d62a17ae 1211 if (bgp->v_establish_wait != bgp->v_update_delay)
907a2395
DS
1212 event_add_timer(bm->master, bgp_establish_wait_timer, bgp,
1213 bgp->v_establish_wait, &bgp->t_establish_wait);
f188f2c4 1214
e36f61b5
DS
1215 frr_timestamp(3, bgp->update_delay_begin_time,
1216 sizeof(bgp->update_delay_begin_time));
f188f2c4
DS
1217}
1218
d62a17ae 1219static void bgp_update_delay_process_status_change(struct peer *peer)
f188f2c4 1220{
feb17238 1221 if (peer_established(peer)) {
d62a17ae 1222 if (!peer->bgp->established++) {
1223 bgp_update_delay_begin(peer->bgp);
1224 zlog_info(
1225 "Begin read-only mode - update-delay timer %d seconds",
1226 peer->bgp->v_update_delay);
1227 }
54394daa 1228 if (CHECK_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV))
d62a17ae 1229 bgp_update_restarted_peers(peer);
1230 }
1231 if (peer->ostatus == Established
1232 && bgp_update_delay_active(peer->bgp)) {
1233 /* Adjust the update-delay state to account for this flap.
1234 NOTE: Intentionally skipping adjusting implicit_eors or
1235 explicit_eors
1236 counters. Extra sanity check in bgp_check_update_delay()
1237 should
1238 be enough to take care of any additive discrepancy in bgp eor
1239 counters */
1240 peer->bgp->established--;
1241 peer->update_delay_over = 0;
1242 }
f188f2c4
DS
1243}
1244
0437e105 1245/* Called after event occurred, this function change status and reset
200df115 1246 read/write and timer thread. */
881979e4 1247void bgp_fsm_change_status(struct peer *peer, enum bgp_fsm_status status)
200df115 1248{
36dc7588 1249 struct bgp *bgp;
1250 uint32_t peer_count;
1ff9a340 1251
36dc7588 1252 bgp = peer->bgp;
1253 peer_count = bgp->established_peers;
1254
1255 if (status == Established)
1256 bgp->established_peers++;
feb17238 1257 else if ((peer_established(peer)) && (status != Established))
36dc7588 1258 bgp->established_peers--;
1259
1cfe005d
DS
1260 if (bgp_debug_neighbor_events(peer)) {
1261 struct vrf *vrf = vrf_lookup_by_id(bgp->vrf_id);
1262
1263 zlog_debug("%s : vrf %s(%u), Status: %s established_peers %u", __func__,
1264 vrf ? vrf->name : "Unknown", bgp->vrf_id,
1265 lookup_msg(bgp_status_msg, status, NULL),
1266 bgp->established_peers);
1267 }
1268
36dc7588 1269 /* Set to router ID to the value provided by RIB if there are no peers
1270 * in the established state and peer count did not change
1271 */
1272 if ((peer_count != bgp->established_peers) &&
1273 (bgp->established_peers == 0))
1274 bgp_router_id_zebra_bump(bgp->vrf_id, NULL);
1275
d62a17ae 1276 /* Transition into Clearing or Deleted must /always/ clear all routes..
1277 * (and must do so before actually changing into Deleted..
1278 */
1279 if (status >= Clearing) {
1280 bgp_clear_route_all(peer);
1281
1282 /* If no route was queued for the clear-node processing,
1283 * generate the
1284 * completion event here. This is needed because if there are no
1285 * routes
1286 * to trigger the background clear-node thread, the event won't
1287 * get
1288 * generated and the peer would be stuck in Clearing. Note that
1289 * this
1290 * event is for the peer and helps the peer transition out of
1291 * Clearing
1292 * state; it should not be generated per (AFI,SAFI). The event
1293 * is
1294 * directly posted here without calling clear_node_complete() as
1295 * we
1296 * shouldn't do an extra unlock. This event will get processed
1297 * after
1298 * the state change that happens below, so peer will be in
1299 * Clearing
1300 * (or Deleted).
1301 */
69ef3f31
DS
1302 if (!work_queue_is_scheduled(peer->clear_node_queue) &&
1303 status != Deleted)
d62a17ae 1304 BGP_EVENT_ADD(peer, Clearing_Completed);
1305 }
1306
1307 /* Preserve old status and change into new status. */
1308 peer->ostatus = peer->status;
1309 peer->status = status;
1310
8336c896
DA
1311 /* Reset received keepalives counter on every FSM change */
1312 peer->rtt_keepalive_rcv = 0;
1313
05e68acc 1314 /* Fire backward transition hook if that's the case */
adf552ab 1315 if (peer->ostatus == Established && peer->status != Established)
05e68acc
BC
1316 hook_call(peer_backward_transition, peer);
1317
d62a17ae 1318 /* Save event that caused status change. */
1319 peer->last_major_event = peer->cur_event;
1320
7d8d0eab
MKS
1321 /* Operations after status change */
1322 hook_call(peer_status_changed, peer);
1323
d62a17ae 1324 if (status == Established)
1325 UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
1326
1327 /* If max-med processing is applicable, do the necessary. */
1328 if (status == Established) {
1329 if (bgp_maxmed_onstartup_configured(peer->bgp)
1330 && bgp_maxmed_onstartup_applicable(peer->bgp))
1331 bgp_maxmed_onstartup_process_status_change(peer);
1332 else
1333 peer->bgp->maxmed_onstartup_over = 1;
1334 }
1335
1336 /* If update-delay processing is applicable, do the necessary. */
1337 if (bgp_update_delay_configured(peer->bgp)
1338 && bgp_update_delay_applicable(peer->bgp))
1339 bgp_update_delay_process_status_change(peer);
1340
1341 if (bgp_debug_neighbor_events(peer))
71d276c8 1342 zlog_debug("%s fd %d went from %s to %s", peer->host, peer->fd,
d62a17ae 1343 lookup_msg(bgp_status_msg, peer->ostatus, NULL),
1344 lookup_msg(bgp_status_msg, peer->status, NULL));
200df115 1345}
1346
3117b5c4 1347/* Flush the event queue and ensure the peer is shut down */
4da144f3 1348static enum bgp_fsm_state_progress bgp_clearing_completed(struct peer *peer)
3117b5c4 1349{
4da144f3 1350 enum bgp_fsm_state_progress rc = bgp_stop(peer);
1ff9a340 1351
4da144f3 1352 if (rc >= BGP_FSM_SUCCESS)
d62a17ae 1353 BGP_EVENT_FLUSH(peer);
3117b5c4 1354
d62a17ae 1355 return rc;
3117b5c4
SH
1356}
1357
718e3744 1358/* Administrative BGP peer stop event. */
3117b5c4 1359/* May be called multiple times for the same peer */
4da144f3 1360enum bgp_fsm_state_progress bgp_stop(struct peer *peer)
718e3744 1361{
d62a17ae 1362 afi_t afi;
1363 safi_t safi;
1364 char orf_name[BUFSIZ];
4da144f3 1365 enum bgp_fsm_state_progress ret = BGP_FSM_SUCCESS;
f009ff26 1366 struct bgp *bgp = peer->bgp;
1367 struct graceful_restart_info *gr_info = NULL;
d62a17ae 1368
2ba1fe69 1369 peer->nsf_af_count = 0;
1370
e7db872b 1371 /* deregister peer */
21bfce98
RZ
1372 if (peer->bfd_config
1373 && peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE)
1374 bfd_sess_uninstall(peer->bfd_config->session);
e7db872b 1375
af8496af
DA
1376 if (peer_dynamic_neighbor_no_nsf(peer) &&
1377 !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
d62a17ae 1378 if (bgp_debug_neighbor_events(peer))
31afff83
DA
1379 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1380 peer->host, __func__);
d62a17ae 1381 peer_delete(peer);
4da144f3 1382 return BGP_FSM_FAILURE_AND_DELETE;
c22767d8 1383 }
848973c7 1384
d62a17ae 1385 /* Can't do this in Clearing; events are used for state transitions */
1386 if (peer->status != Clearing) {
1387 /* Delete all existing events of the peer */
1388 BGP_EVENT_FLUSH(peer);
93406d87 1389 }
d62a17ae 1390
1391 /* Increment Dropped count. */
feb17238 1392 if (peer_established(peer)) {
d62a17ae 1393 peer->dropped++;
1394
07753623
DA
1395 /* Notify BGP conditional advertisement process */
1396 peer->advmap_table_change = true;
1397
d62a17ae 1398 /* bgp log-neighbor-changes of neighbor Down */
892fedb6
DA
1399 if (CHECK_FLAG(peer->bgp->flags,
1400 BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
d62a17ae 1401 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
2986cac2 1402
d62a17ae 1403 zlog_info(
f70c91dc
DA
1404 "%%ADJCHANGE: neighbor %pBP in vrf %s Down %s",
1405 peer,
5742e42b 1406 vrf ? ((vrf->vrf_id != VRF_DEFAULT)
a7d91a8c
DA
1407 ? vrf->name
1408 : VRF_DEFAULT_NAME)
d62a17ae 1409 : "",
1410 peer_down_str[(int)peer->last_reset]);
1411 }
1412
1413 /* graceful restart */
1414 if (peer->t_gr_stale) {
e16d030c 1415 EVENT_OFF(peer->t_gr_stale);
d62a17ae 1416 if (bgp_debug_neighbor_events(peer))
1417 zlog_debug(
f70c91dc
DA
1418 "%pBP graceful restart stalepath timer stopped",
1419 peer);
d62a17ae 1420 }
1421 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
1422 if (bgp_debug_neighbor_events(peer)) {
1423 zlog_debug(
f70c91dc
DA
1424 "%pBP graceful restart timer started for %d sec",
1425 peer, peer->v_gr_restart);
d62a17ae 1426 zlog_debug(
f70c91dc
DA
1427 "%pBP graceful restart stalepath timer started for %d sec",
1428 peer, peer->bgp->stalepath_time);
d62a17ae 1429 }
1430 BGP_TIMER_ON(peer->t_gr_restart,
1431 bgp_graceful_restart_timer_expire,
1432 peer->v_gr_restart);
1433 BGP_TIMER_ON(peer->t_gr_stale,
1434 bgp_graceful_stale_timer_expire,
1435 peer->bgp->stalepath_time);
1436 } else {
1437 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
1438
df8d723c
DA
1439 FOREACH_AFI_SAFI_NSF (afi, safi)
1440 peer->nsf[afi][safi] = 0;
d62a17ae 1441 }
1442
9af52ccf
DA
1443 /* Stop route-refresh stalepath timer */
1444 if (peer->t_refresh_stalepath) {
e16d030c 1445 EVENT_OFF(peer->t_refresh_stalepath);
9af52ccf
DA
1446
1447 if (bgp_debug_neighbor_events(peer))
1448 zlog_debug(
f70c91dc
DA
1449 "%pBP route-refresh restart stalepath timer stopped",
1450 peer);
9af52ccf
DA
1451 }
1452
f009ff26 1453 /* If peer reset before receiving EOR, decrement EOR count and
1454 * cancel the selection deferral timer if there are no
1455 * pending EOR messages to be received
1456 */
1457 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
1458 FOREACH_AFI_SAFI (afi, safi) {
13909c4f
DS
1459 if (!peer->afc_nego[afi][safi]
1460 || CHECK_FLAG(peer->af_sflags[afi][safi],
1461 PEER_STATUS_EOR_RECEIVED))
1462 continue;
1463
1464 gr_info = &bgp->gr_info[afi][safi];
1465 if (!gr_info)
1466 continue;
1467
1468 if (gr_info->eor_required)
1469 gr_info->eor_required--;
1470
1471 if (BGP_DEBUG(update, UPDATE_OUT))
1472 zlog_debug("peer %s, EOR_required %d",
1473 peer->host,
1474 gr_info->eor_required);
1475
1476 /* There is no pending EOR message */
1477 if (gr_info->eor_required == 0) {
b96b4f1c 1478 if (gr_info->t_select_deferral) {
e16d030c 1479 void *info = EVENT_ARG(
b96b4f1c
SB
1480 gr_info->t_select_deferral);
1481 XFREE(MTYPE_TMP, info);
1482 }
e16d030c 1483 EVENT_OFF(gr_info->t_select_deferral);
13909c4f 1484 gr_info->eor_received = 0;
f009ff26 1485 }
1486 }
1487 }
1488
d62a17ae 1489 /* set last reset time */
083ec940 1490 peer->resettime = peer->uptime = monotime(NULL);
d62a17ae 1491
1492 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1493 zlog_debug("%s remove from all update group",
1494 peer->host);
1495 update_group_remove_peer_afs(peer);
1496
d62a17ae 1497 /* Reset peer synctime */
1498 peer->synctime = 0;
93406d87 1499 }
93406d87 1500
424ab01d 1501 /* stop keepalives */
b72b6f4f 1502 bgp_keepalives_off(peer);
424ab01d
QY
1503
1504 /* Stop read and write threads. */
1505 bgp_writes_off(peer);
1506 bgp_reads_off(peer);
1507
e16d030c
DS
1508 EVENT_OFF(peer->t_connect_check_r);
1509 EVENT_OFF(peer->t_connect_check_w);
d62a17ae 1510
1511 /* Stop all timers. */
e16d030c
DS
1512 EVENT_OFF(peer->t_start);
1513 EVENT_OFF(peer->t_connect);
1514 EVENT_OFF(peer->t_holdtime);
1515 EVENT_OFF(peer->t_routeadv);
1516 EVENT_OFF(peer->t_delayopen);
d62a17ae 1517
1518 /* Clear input and output buffer. */
cb1991af 1519 frr_with_mutex (&peer->io_mtx) {
424ab01d
QY
1520 if (peer->ibuf)
1521 stream_fifo_clean(peer->ibuf);
d3ecc69e
QY
1522 if (peer->obuf)
1523 stream_fifo_clean(peer->obuf);
424ab01d
QY
1524
1525 if (peer->ibuf_work)
74ffbfe6 1526 ringbuf_wipe(peer->ibuf_work);
424ab01d
QY
1527 if (peer->obuf_work)
1528 stream_reset(peer->obuf_work);
1529
1530 if (peer->curr) {
1531 stream_free(peer->curr);
1532 peer->curr = NULL;
1533 }
d3ecc69e 1534 }
d62a17ae 1535
1536 /* Close of file descriptor. */
1537 if (peer->fd >= 0) {
1538 close(peer->fd);
1539 peer->fd = -1;
93406d87 1540 }
1541
24f569e9
AS
1542 /* Reset capabilities. */
1543 peer->cap = 0;
1544
d864dd9e 1545 /* Resetting neighbor role to the default value */
8f2d6021 1546 peer->remote_role = ROLE_UNDEFINED;
d864dd9e 1547
05c7a1cc
QY
1548 FOREACH_AFI_SAFI (afi, safi) {
1549 /* Reset all negotiated variables */
1550 peer->afc_nego[afi][safi] = 0;
1551 peer->afc_adv[afi][safi] = 0;
1552 peer->afc_recv[afi][safi] = 0;
1553
1554 /* peer address family capability flags*/
1555 peer->af_cap[afi][safi] = 0;
1556
1557 /* peer address family status flags*/
1558 peer->af_sflags[afi][safi] = 0;
1559
1560 /* Received ORF prefix-filter */
1561 peer->orf_plist[afi][safi] = NULL;
1562
feb17238 1563 if ((peer->status == OpenConfirm) || (peer_established(peer))) {
05c7a1cc 1564 /* ORF received prefix-filter pnt */
fc746f1c
QY
1565 snprintf(orf_name, sizeof(orf_name), "%s.%d.%d",
1566 peer->host, afi, safi);
05c7a1cc 1567 prefix_bgp_orf_remove_all(afi, orf_name);
d62a17ae 1568 }
05c7a1cc 1569 }
d62a17ae 1570
1571 /* Reset keepalive and holdtime */
b90a8e13 1572 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) {
d62a17ae 1573 peer->v_keepalive = peer->keepalive;
1574 peer->v_holdtime = peer->holdtime;
1575 } else {
1576 peer->v_keepalive = peer->bgp->default_keepalive;
1577 peer->v_holdtime = peer->bgp->default_holdtime;
1ff9a340 1578 }
d62a17ae 1579
6c537a18
DS
1580 /* Reset DelayOpenTime */
1581 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
1582 peer->v_delayopen = peer->delayopen;
1583 else
1584 peer->v_delayopen = peer->bgp->default_delayopen;
1585
d62a17ae 1586 peer->update_time = 0;
1587
d62a17ae 1588 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)
1589 && !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
1590 peer_delete(peer);
4da144f3 1591 ret = BGP_FSM_FAILURE_AND_DELETE;
d62a17ae 1592 } else {
1593 bgp_peer_conf_if_to_su_update(peer);
1594 }
d62a17ae 1595 return ret;
718e3744 1596}
1597
1598/* BGP peer is stoped by the error. */
4da144f3 1599static enum bgp_fsm_state_progress bgp_stop_with_error(struct peer *peer)
718e3744 1600{
d62a17ae 1601 /* Double start timer. */
1602 peer->v_start *= 2;
1603
1604 /* Overflow check. */
1605 if (peer->v_start >= (60 * 2))
1606 peer->v_start = (60 * 2);
1607
af8496af 1608 if (peer_dynamic_neighbor_no_nsf(peer)) {
d62a17ae 1609 if (bgp_debug_neighbor_events(peer))
31afff83
DA
1610 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1611 peer->host, __func__);
d62a17ae 1612 peer_delete(peer);
4da144f3 1613 return BGP_FSM_FAILURE;
d62a17ae 1614 }
1615
4da144f3 1616 return bgp_stop(peer);
718e3744 1617}
1618
397b5bde
LR
1619
1620/* something went wrong, send notify and tear down */
4da144f3
DS
1621static enum bgp_fsm_state_progress
1622bgp_stop_with_notify(struct peer *peer, uint8_t code, uint8_t sub_code)
397b5bde 1623{
d62a17ae 1624 /* Send notify to remote peer */
1625 bgp_notify_send(peer, code, sub_code);
1626
af8496af 1627 if (peer_dynamic_neighbor_no_nsf(peer)) {
d62a17ae 1628 if (bgp_debug_neighbor_events(peer))
31afff83
DA
1629 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1630 peer->host, __func__);
d62a17ae 1631 peer_delete(peer);
4da144f3 1632 return BGP_FSM_FAILURE;
d62a17ae 1633 }
f14e6fdb 1634
d62a17ae 1635 /* Clear start timer value to default. */
1636 peer->v_start = BGP_INIT_START_TIMER;
397b5bde 1637
4da144f3 1638 return bgp_stop(peer);
397b5bde
LR
1639}
1640
07a16526
QY
1641/**
1642 * Determines whether a TCP session has successfully established for a peer and
1643 * events as appropriate.
1644 *
1645 * This function is called when setting up a new session. After connect() is
387f984e
QY
1646 * called on the peer's socket (in bgp_start()), the fd is passed to poll()
1647 * to wait for connection success or failure. When poll() returns, this
07a16526 1648 * function is called to evaluate the result.
387f984e
QY
1649 *
1650 * Due to differences in behavior of poll() on Linux and BSD - specifically,
1651 * the value of .revents in the case of a closed connection - this function is
1652 * scheduled both for a read and a write event. The write event is triggered
1653 * when the connection is established. A read event is triggered when the
1654 * connection is closed. Thus we need to cancel whichever one did not occur.
07a16526 1655 */
e6685141 1656static void bgp_connect_check(struct event *thread)
07a16526
QY
1657{
1658 int status;
1659 socklen_t slen;
1660 int ret;
1661 struct peer *peer;
1662
e16d030c 1663 peer = EVENT_ARG(thread);
424ab01d
QY
1664 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
1665 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
1666 assert(!peer->t_read);
1667 assert(!peer->t_write);
07a16526 1668
e16d030c
DS
1669 EVENT_OFF(peer->t_connect_check_r);
1670 EVENT_OFF(peer->t_connect_check_w);
dc1188bb 1671
07a16526
QY
1672 /* Check file descriptor. */
1673 slen = sizeof(status);
1674 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *)&status,
1675 &slen);
1676
1677 /* If getsockopt is fail, this is fatal error. */
1678 if (ret < 0) {
4cb5e18b 1679 zlog_err("can't get sockopt for nonblocking connect: %d(%s)",
54ff5e9b 1680 errno, safe_strerror(errno));
07a16526 1681 BGP_EVENT_ADD(peer, TCP_fatal_error);
cc9f21da 1682 return;
07a16526
QY
1683 }
1684
1685 /* When status is 0 then TCP connection is established. */
1686 if (status == 0) {
6c537a18
DS
1687 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
1688 BGP_EVENT_ADD(peer, TCP_connection_open_w_delay);
1689 else
1690 BGP_EVENT_ADD(peer, TCP_connection_open);
cc9f21da 1691 return;
07a16526
QY
1692 } else {
1693 if (bgp_debug_neighbor_events(peer))
54ff5e9b
DS
1694 zlog_debug("%s [Event] Connect failed %d(%s)",
1695 peer->host, status, safe_strerror(status));
07a16526 1696 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
cc9f21da 1697 return;
07a16526
QY
1698 }
1699}
397b5bde 1700
718e3744 1701/* TCP connection open. Next we send open message to remote peer. And
1702 add read thread for reading open message. */
4da144f3 1703static enum bgp_fsm_state_progress bgp_connect_success(struct peer *peer)
718e3744 1704{
d62a17ae 1705 if (peer->fd < 0) {
a10c2872 1706 flog_err(EC_BGP_CONNECT, "%s peer's fd is negative value %d",
1707 __func__, peer->fd);
4da144f3 1708 return bgp_stop(peer);
d62a17ae 1709 }
1710
1711 if (bgp_getsockname(peer) < 0) {
450971aa 1712 flog_err_sys(EC_LIB_SOCKET,
09c866e3 1713 "%s: bgp_getsockname(): failed for peer %s, fd %d",
15569c58 1714 __func__, peer->host, peer->fd);
3893aeee
DA
1715 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
1716 bgp_fsm_error_subcode(peer->status));
424ab01d 1717 bgp_writes_on(peer);
4da144f3 1718 return BGP_FSM_FAILURE;
d62a17ae 1719 }
1720
cea8b655
DS
1721 /*
1722 * If we are doing nht for a peer that ls v6 LL based
1723 * massage the event system to make things happy
1724 */
1725 bgp_nht_interface_events(peer);
1726
424ab01d 1727 bgp_reads_on(peer);
d62a17ae 1728
1729 if (bgp_debug_neighbor_events(peer)) {
d62a17ae 1730 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
c0d72166
DS
1731 zlog_debug("%s open active, local address %pSU",
1732 peer->host, peer->su_local);
d62a17ae 1733 else
1734 zlog_debug("%s passive open", peer->host);
1735 }
1736
6c537a18 1737 /* Send an open message */
d62a17ae 1738 bgp_open_send(peer);
1739
4da144f3 1740 return BGP_FSM_SUCCESS;
718e3744 1741}
1742
6c537a18
DS
1743/* TCP connection open with RFC 4271 optional session attribute DelayOpen flag
1744 * set.
1745 */
4da144f3
DS
1746static enum bgp_fsm_state_progress
1747bgp_connect_success_w_delayopen(struct peer *peer)
6c537a18
DS
1748{
1749 if (peer->fd < 0) {
1750 flog_err(EC_BGP_CONNECT, "%s: peer's fd is negative value %d",
1751 __func__, peer->fd);
4da144f3 1752 return bgp_stop(peer);
6c537a18
DS
1753 }
1754
1755 if (bgp_getsockname(peer) < 0) {
1756 flog_err_sys(EC_LIB_SOCKET,
1757 "%s: bgp_getsockname(): failed for peer %s, fd %d",
1758 __func__, peer->host, peer->fd);
1759 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
1760 bgp_fsm_error_subcode(peer->status));
1761 bgp_writes_on(peer);
4da144f3 1762 return BGP_FSM_FAILURE;
6c537a18
DS
1763 }
1764
cea8b655
DS
1765 /*
1766 * If we are doing nht for a peer that ls v6 LL based
1767 * massage the event system to make things happy
1768 */
1769 bgp_nht_interface_events(peer);
1770
6c537a18
DS
1771 bgp_reads_on(peer);
1772
1773 if (bgp_debug_neighbor_events(peer)) {
6c537a18 1774 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
c0d72166
DS
1775 zlog_debug("%s open active, local address %pSU",
1776 peer->host, peer->su_local);
6c537a18
DS
1777 else
1778 zlog_debug("%s passive open", peer->host);
1779 }
1780
1781 /* set the DelayOpenTime to the inital value */
1782 peer->v_delayopen = peer->delayopen;
1783
1784 /* Start the DelayOpenTimer if it is not already running */
1785 if (!peer->t_delayopen)
1786 BGP_TIMER_ON(peer->t_delayopen, bgp_delayopen_timer,
1787 peer->v_delayopen);
1788
1789 if (bgp_debug_neighbor_events(peer))
1790 zlog_debug("%s [FSM] BGP OPEN message delayed for %d seconds",
1791 peer->host, peer->delayopen);
1792
4da144f3 1793 return BGP_FSM_SUCCESS;
6c537a18
DS
1794}
1795
718e3744 1796/* TCP connect fail */
4da144f3 1797static enum bgp_fsm_state_progress bgp_connect_fail(struct peer *peer)
718e3744 1798{
af8496af 1799 if (peer_dynamic_neighbor_no_nsf(peer)) {
d62a17ae 1800 if (bgp_debug_neighbor_events(peer))
31afff83
DA
1801 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1802 peer->host, __func__);
d62a17ae 1803 peer_delete(peer);
4da144f3 1804 return BGP_FSM_FAILURE_AND_DELETE;
d62a17ae 1805 }
1806
8761cd6d
DS
1807 /*
1808 * If we are doing nht for a peer that ls v6 LL based
1809 * massage the event system to make things happy
1810 */
1811 bgp_nht_interface_events(peer);
1812
4da144f3 1813 return bgp_stop(peer);
718e3744 1814}
1815
1816/* This function is the first starting point of all BGP connection. It
6c537a18
DS
1817 * try to connect to remote peer with non-blocking IO.
1818 */
4da144f3 1819enum bgp_fsm_state_progress bgp_start(struct peer *peer)
718e3744 1820{
d62a17ae 1821 int status;
d62a17ae 1822
1823 bgp_peer_conf_if_to_su_update(peer);
1824
1825 if (peer->su.sa.sa_family == AF_UNSPEC) {
1826 if (bgp_debug_neighbor_events(peer))
1827 zlog_debug(
1828 "%s [FSM] Unable to get neighbor's IP address, waiting...",
1829 peer->host);
3577f1c5 1830 peer->last_reset = PEER_DOWN_NBR_ADDR;
4da144f3 1831 return BGP_FSM_FAILURE;
d62a17ae 1832 }
1833
1834 if (BGP_PEER_START_SUPPRESSED(peer)) {
1835 if (bgp_debug_neighbor_events(peer))
e50f7cfd 1836 flog_err(EC_BGP_FSM,
3efd0893 1837 "%s [FSM] Trying to start suppressed peer - this is never supposed to happen!",
1c50c1c0 1838 peer->host);
5597214c
DA
1839 if (CHECK_FLAG(peer->sflags, PEER_STATUS_RTT_SHUTDOWN))
1840 peer->last_reset = PEER_DOWN_RTT_SHUTDOWN;
1841 else if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
07d1e5d9 1842 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
cb9196e7
DS
1843 else if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHUTDOWN))
1844 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
07d1e5d9
DA
1845 else if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
1846 peer->last_reset = PEER_DOWN_PFX_COUNT;
4da144f3 1847 return BGP_FSM_FAILURE;
d62a17ae 1848 }
1849
1850 /* Scrub some information that might be left over from a previous,
1851 * session
1852 */
1853 /* Connection information. */
1854 if (peer->su_local) {
1855 sockunion_free(peer->su_local);
1856 peer->su_local = NULL;
1857 }
1858
1859 if (peer->su_remote) {
1860 sockunion_free(peer->su_remote);
1861 peer->su_remote = NULL;
1862 }
1863
1864 /* Clear remote router-id. */
975a328e 1865 peer->remote_id.s_addr = INADDR_ANY;
d62a17ae 1866
1867 /* Clear peer capability flag. */
1868 peer->cap = 0;
1869
1870 /* If the peer is passive mode, force to move to Active mode. */
1871 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)) {
1872 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
4da144f3 1873 return BGP_FSM_SUCCESS;
d62a17ae 1874 }
1875
2c1eba8e 1876 if (peer->bgp->vrf_id == VRF_UNKNOWN) {
61cf4b37 1877 if (bgp_debug_neighbor_events(peer))
af4c2728 1878 flog_err(
e50f7cfd 1879 EC_BGP_FSM,
996c9314
LB
1880 "%s [FSM] In a VRF that is not initialised yet",
1881 peer->host);
3577f1c5 1882 peer->last_reset = PEER_DOWN_VRF_UNINIT;
4da144f3 1883 return BGP_FSM_FAILURE;
61cf4b37
PG
1884 }
1885
e2d3a909 1886 /* Register peer for NHT. If next hop is already resolved, proceed
1887 * with connection setup, else wait.
1888 */
1889 if (!bgp_peer_reg_with_nht(peer)) {
c42eab4b
DS
1890 if (bgp_zebra_num_connects()) {
1891 if (bgp_debug_neighbor_events(peer))
6029afbc
DS
1892 zlog_debug(
1893 "%s [FSM] Waiting for NHT, no path to neighbor present",
1894 peer->host);
3577f1c5 1895 peer->last_reset = PEER_DOWN_WAITING_NHT;
c42eab4b 1896 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
4da144f3 1897 return BGP_FSM_SUCCESS;
c42eab4b 1898 }
718e3744 1899 }
d62a17ae 1900
424ab01d
QY
1901 assert(!peer->t_write);
1902 assert(!peer->t_read);
1903 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
1904 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
d62a17ae 1905 status = bgp_connect(peer);
1906
1907 switch (status) {
1908 case connect_error:
1909 if (bgp_debug_neighbor_events(peer))
1910 zlog_debug("%s [FSM] Connect error", peer->host);
1911 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1912 break;
1913 case connect_success:
1914 if (bgp_debug_neighbor_events(peer))
1915 zlog_debug(
1916 "%s [FSM] Connect immediately success, fd %d",
1917 peer->host, peer->fd);
6c537a18 1918
d62a17ae 1919 BGP_EVENT_ADD(peer, TCP_connection_open);
1920 break;
1921 case connect_in_progress:
1922 /* To check nonblocking connect, we wait until socket is
1923 readable or writable. */
1924 if (bgp_debug_neighbor_events(peer))
1925 zlog_debug(
1926 "%s [FSM] Non blocking connect waiting result, fd %d",
1927 peer->host, peer->fd);
1928 if (peer->fd < 0) {
e50f7cfd 1929 flog_err(EC_BGP_FSM,
a10c2872 1930 "%s peer's fd is negative value %d", __func__,
1c50c1c0 1931 peer->fd);
4da144f3 1932 return BGP_FSM_FAILURE;
d62a17ae 1933 }
becedef6 1934 /*
387f984e
QY
1935 * - when the socket becomes ready, poll() will signify POLLOUT
1936 * - if it fails to connect, poll() will signify POLLHUP
1937 * - POLLHUP is handled as a 'read' event by thread.c
1938 *
1939 * therefore, we schedule both a read and a write event with
1940 * bgp_connect_check() as the handler for each and cancel the
1941 * unused event in that function.
becedef6 1942 */
907a2395
DS
1943 event_add_read(bm->master, bgp_connect_check, peer, peer->fd,
1944 &peer->t_connect_check_r);
1945 event_add_write(bm->master, bgp_connect_check, peer, peer->fd,
1946 &peer->t_connect_check_w);
d62a17ae 1947 break;
1948 }
4da144f3 1949 return BGP_FSM_SUCCESS;
718e3744 1950}
1951
1952/* Connect retry timer is expired when the peer status is Connect. */
4da144f3 1953static enum bgp_fsm_state_progress bgp_reconnect(struct peer *peer)
718e3744 1954{
4da144f3
DS
1955 enum bgp_fsm_state_progress ret;
1956
1957 ret = bgp_stop(peer);
1958 if (ret < BGP_FSM_SUCCESS)
1959 return ret;
1ff9a340 1960
8c48b3b6 1961 /* Send graceful restart capabilty */
36235319
QY
1962 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
1963 peer->bgp->peer);
8c48b3b6 1964
4da144f3 1965 return bgp_start(peer);
718e3744 1966}
1967
4da144f3 1968static enum bgp_fsm_state_progress bgp_fsm_open(struct peer *peer)
718e3744 1969{
6c537a18
DS
1970 /* If DelayOpen is active, we may still need to send an open message */
1971 if ((peer->status == Connect) || (peer->status == Active))
1972 bgp_open_send(peer);
1973
d62a17ae 1974 /* Send keepalive and make keepalive timer */
1975 bgp_keepalive_send(peer);
718e3744 1976
4da144f3 1977 return BGP_FSM_SUCCESS;
718e3744 1978}
1979
397b5bde
LR
1980/* FSM error, unexpected event. This is error of BGP connection. So cut the
1981 peer and change to Idle status. */
4da144f3 1982static enum bgp_fsm_state_progress bgp_fsm_event_error(struct peer *peer)
397b5bde 1983{
1c50c1c0
QY
1984 flog_err(EC_BGP_FSM, "%s [FSM] unexpected packet received in state %s",
1985 peer->host, lookup_msg(bgp_status_msg, peer->status, NULL));
397b5bde 1986
3893aeee
DA
1987 return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR,
1988 bgp_fsm_error_subcode(peer->status));
397b5bde
LR
1989}
1990
718e3744 1991/* Hold timer expire. This is error of BGP connection. So cut the
1992 peer and change to Idle status. */
4da144f3 1993static enum bgp_fsm_state_progress bgp_fsm_holdtime_expire(struct peer *peer)
718e3744 1994{
d62a17ae 1995 if (bgp_debug_neighbor_events(peer))
1996 zlog_debug("%s [FSM] Hold timer expire", peer->host);
718e3744 1997
20170775
DA
1998 /* RFC8538 updates RFC 4724 by defining an extension that permits
1999 * the Graceful Restart procedures to be performed when the BGP
2000 * speaker receives a BGP NOTIFICATION message or the Hold Time expires.
2001 */
2002 if (peer_established(peer) &&
2003 bgp_has_graceful_restart_notification(peer))
2004 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE))
2005 SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
2006
d62a17ae 2007 return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0);
718e3744 2008}
2009
6c537a18 2010/* RFC 4271 DelayOpenTimer_Expires event */
4da144f3
DS
2011static enum bgp_fsm_state_progress
2012bgp_fsm_delayopen_timer_expire(struct peer *peer)
6c537a18
DS
2013{
2014 /* Stop the DelayOpenTimer */
e16d030c 2015 EVENT_OFF(peer->t_delayopen);
6c537a18
DS
2016
2017 /* Send open message to peer */
2018 bgp_open_send(peer);
2019
2020 /* Set the HoldTimer to a large value (4 minutes) */
2021 peer->v_holdtime = 245;
2022
4da144f3 2023 return BGP_FSM_SUCCESS;
6c537a18
DS
2024}
2025
f009ff26 2026/* Start the selection deferral timer thread for the specified AFI, SAFI */
2027static int bgp_start_deferral_timer(struct bgp *bgp, afi_t afi, safi_t safi,
36235319 2028 struct graceful_restart_info *gr_info)
f009ff26 2029{
2030 struct afi_safi_info *thread_info;
2031
2032 /* If the deferral timer is active, then increment eor count */
2033 if (gr_info->t_select_deferral) {
2034 gr_info->eor_required++;
2035 return 0;
2036 }
2037
2038 /* Start the deferral timer when the first peer enabled for the graceful
2039 * restart is established
2040 */
2041 if (gr_info->eor_required == 0) {
2042 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
f009ff26 2043
2044 thread_info->afi = afi;
2045 thread_info->safi = safi;
2046 thread_info->bgp = bgp;
2047
907a2395
DS
2048 event_add_timer(bm->master, bgp_graceful_deferral_timer_expire,
2049 thread_info, bgp->select_defer_time,
2050 &gr_info->t_select_deferral);
f009ff26 2051 }
f009ff26 2052 gr_info->eor_required++;
8c48b3b6 2053 /* Send message to RIB indicating route update pending */
2054 if (gr_info->af_enabled[afi][safi] == false) {
2055 gr_info->af_enabled[afi][safi] = true;
2056 /* Send message to RIB */
115ccb9a 2057 bgp_zebra_update(bgp, afi, safi,
8c48b3b6 2058 ZEBRA_CLIENT_ROUTE_UPDATE_PENDING);
2059 }
f009ff26 2060 if (BGP_DEBUG(update, UPDATE_OUT))
2061 zlog_debug("Started the deferral timer for %s eor_required %d",
36235319
QY
2062 get_afi_safi_str(afi, safi, false),
2063 gr_info->eor_required);
f009ff26 2064 return 0;
2065}
2066
2067/* Update the graceful restart information for the specified AFI, SAFI */
2068static int bgp_update_gr_info(struct peer *peer, afi_t afi, safi_t safi)
2069{
2070 struct graceful_restart_info *gr_info;
2071 struct bgp *bgp = peer->bgp;
2072 int ret = 0;
2073
2074 if ((afi < AFI_IP) || (afi >= AFI_MAX)) {
2075 if (BGP_DEBUG(update, UPDATE_OUT))
2076 zlog_debug("%s : invalid afi %d", __func__, afi);
2077 return -1;
2078 }
2079
2080 if ((safi < SAFI_UNICAST) || (safi > SAFI_MPLS_VPN)) {
2081 if (BGP_DEBUG(update, UPDATE_OUT))
2082 zlog_debug("%s : invalid safi %d", __func__, safi);
2083 return -1;
2084 }
2085
2086 /* Restarting router */
36235319
QY
2087 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
2088 && BGP_PEER_RESTARTING_MODE(peer)) {
f009ff26 2089 /* Check if the forwarding state is preserved */
892fedb6 2090 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)) {
f009ff26 2091 gr_info = &(bgp->gr_info[afi][safi]);
2092 ret = bgp_start_deferral_timer(bgp, afi, safi, gr_info);
2093 }
2094 }
2ba1fe69 2095 return ret;
f009ff26 2096}
2097
727c4f87
QY
2098/**
2099 * Transition to Established state.
2100 *
2101 * Convert peer from stub to full fledged peer, set some timers, and generate
2102 * initial updates.
2103 */
4da144f3 2104static enum bgp_fsm_state_progress bgp_establish(struct peer *peer)
718e3744 2105{
d62a17ae 2106 afi_t afi;
2107 safi_t safi;
2108 int nsf_af_count = 0;
4da144f3 2109 enum bgp_fsm_state_progress ret = BGP_FSM_SUCCESS;
d62a17ae 2110 struct peer *other;
f009ff26 2111 int status;
d62a17ae 2112
2113 other = peer->doppelganger;
56b7d690
DS
2114 hash_release(peer->bgp->peerhash, peer);
2115 if (other)
2116 hash_release(peer->bgp->peerhash, other);
2117
d62a17ae 2118 peer = peer_xfer_conn(peer);
2119 if (!peer) {
e50f7cfd 2120 flog_err(EC_BGP_CONNECT, "%%Neighbor failed in xfer_conn");
4da144f3 2121 return BGP_FSM_FAILURE;
93406d87 2122 }
93406d87 2123
d62a17ae 2124 if (other == peer)
4da144f3 2125 ret = BGP_FSM_SUCCESS_STATE_TRANSFER;
d62a17ae 2126
2127 /* Reset capability open status flag. */
2128 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
2129 SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2130
2131 /* Clear start timer value to default. */
2132 peer->v_start = BGP_INIT_START_TIMER;
2133
2134 /* Increment established count. */
2135 peer->established++;
2136 bgp_fsm_change_status(peer, Established);
2137
2138 /* bgp log-neighbor-changes of neighbor Up */
892fedb6 2139 if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
d62a17ae 2140 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
f70c91dc 2141 zlog_info("%%ADJCHANGE: neighbor %pBP in vrf %s Up", peer,
a7d91a8c
DA
2142 vrf ? ((vrf->vrf_id != VRF_DEFAULT)
2143 ? vrf->name
2144 : VRF_DEFAULT_NAME)
2145 : "");
d62a17ae 2146 }
2147 /* assign update-group/subgroup */
2148 update_group_adjust_peer_afs(peer);
2149
2150 /* graceful restart */
2151 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
f009ff26 2152 if (bgp_debug_neighbor_events(peer)) {
2153 if (BGP_PEER_RESTARTING_MODE(peer))
f70c91dc 2154 zlog_debug("%pBP BGP_RESTARTING_MODE", peer);
f009ff26 2155 else if (BGP_PEER_HELPER_MODE(peer))
f70c91dc 2156 zlog_debug("%pBP BGP_HELPER_MODE", peer);
f009ff26 2157 }
df8d723c
DA
2158
2159 FOREACH_AFI_SAFI_NSF (afi, safi) {
2160 if (peer->afc_nego[afi][safi] &&
2161 CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV) &&
2162 CHECK_FLAG(peer->af_cap[afi][safi],
2163 PEER_CAP_RESTART_AF_RCV)) {
2164 if (peer->nsf[afi][safi] &&
2165 !CHECK_FLAG(peer->af_cap[afi][safi],
2166 PEER_CAP_RESTART_AF_PRESERVE_RCV))
2167 bgp_clear_stale_route(peer, afi, safi);
2168
2169 peer->nsf[afi][safi] = 1;
2170 nsf_af_count++;
2171 } else {
2172 if (peer->nsf[afi][safi])
2173 bgp_clear_stale_route(peer, afi, safi);
2174 peer->nsf[afi][safi] = 0;
2175 }
2176 /* Update the graceful restart information */
2177 if (peer->afc_nego[afi][safi]) {
2178 if (!BGP_SELECT_DEFER_DISABLE(peer->bgp)) {
2179 status = bgp_update_gr_info(peer, afi, safi);
2180 if (status < 0)
2181 zlog_err(
2182 "Error in updating graceful restart for %s",
2183 get_afi_safi_str(afi, safi,
2184 false));
d62a17ae 2185 } else {
df8d723c
DA
2186 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer) &&
2187 BGP_PEER_RESTARTING_MODE(peer) &&
2188 CHECK_FLAG(peer->bgp->flags,
2189 BGP_FLAG_GR_PRESERVE_FWD))
2190 peer->bgp->gr_info[afi][safi]
2191 .eor_required++;
f009ff26 2192 }
d62a17ae 2193 }
df8d723c 2194 }
d62a17ae 2195
77b34214
NT
2196 if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
2197 if ((bgp_peer_gr_mode_get(peer) == PEER_GR)
2198 || ((bgp_peer_gr_mode_get(peer) == PEER_GLOBAL_INHERIT)
2199 && (bgp_global_gr_mode_get(peer->bgp) == GLOBAL_GR))) {
2200 FOREACH_AFI_SAFI (afi, safi)
2201 /* Send route processing complete
2202 message to RIB */
2203 bgp_zebra_update(
115ccb9a 2204 peer->bgp, afi, safi,
77b34214
NT
2205 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2206 }
2207 } else {
2208 /* Peer sends R-bit. In this case, we need to send
2209 * ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE to Zebra. */
eea685b6
DA
2210 if (CHECK_FLAG(peer->cap,
2211 PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV)) {
77b34214
NT
2212 FOREACH_AFI_SAFI (afi, safi)
2213 /* Send route processing complete
2214 message to RIB */
2215 bgp_zebra_update(
115ccb9a 2216 peer->bgp, afi, safi,
77b34214
NT
2217 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2218 }
2219 }
2220
794b37d5 2221 peer->nsf_af_count = nsf_af_count;
2222
d62a17ae 2223 if (nsf_af_count)
2224 SET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
2225 else {
2226 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
2227 if (peer->t_gr_stale) {
e16d030c 2228 EVENT_OFF(peer->t_gr_stale);
d62a17ae 2229 if (bgp_debug_neighbor_events(peer))
2230 zlog_debug(
f70c91dc
DA
2231 "%pBP graceful restart stalepath timer stopped",
2232 peer);
d62a17ae 2233 }
2234 }
93406d87 2235
d62a17ae 2236 if (peer->t_gr_restart) {
e16d030c 2237 EVENT_OFF(peer->t_gr_restart);
d62a17ae 2238 if (bgp_debug_neighbor_events(peer))
f70c91dc 2239 zlog_debug("%pBP graceful restart timer stopped", peer);
d62a17ae 2240 }
718e3744 2241
9eb217ff
QY
2242 /* Reset uptime, turn on keepalives, send current table. */
2243 if (!peer->v_holdtime)
2244 bgp_keepalives_on(peer);
2245
083ec940 2246 peer->uptime = monotime(NULL);
d62a17ae 2247
0d4532cd
DA
2248 /* Send route-refresh when ORF is enabled.
2249 * Stop Long-lived Graceful Restart timers.
2250 */
05c7a1cc 2251 FOREACH_AFI_SAFI (afi, safi) {
0d4532cd 2252 if (peer->t_llgr_stale[afi][safi]) {
e16d030c 2253 EVENT_OFF(peer->t_llgr_stale[afi][safi]);
0d4532cd
DA
2254 if (bgp_debug_neighbor_events(peer))
2255 zlog_debug(
f70c91dc
DA
2256 "%pBP Long-lived stale timer stopped for afi/safi: %d/%d",
2257 peer, afi, safi);
0d4532cd
DA
2258 }
2259
05c7a1cc
QY
2260 if (CHECK_FLAG(peer->af_cap[afi][safi],
2261 PEER_CAP_ORF_PREFIX_SM_ADV)) {
d62a17ae 2262 if (CHECK_FLAG(peer->af_cap[afi][safi],
05c7a1cc 2263 PEER_CAP_ORF_PREFIX_RM_RCV))
9af52ccf
DA
2264 bgp_route_refresh_send(
2265 peer, afi, safi, ORF_TYPE_PREFIX,
2266 REFRESH_IMMEDIATE, 0,
2267 BGP_ROUTE_REFRESH_NORMAL);
05c7a1cc
QY
2268 else if (CHECK_FLAG(peer->af_cap[afi][safi],
2269 PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
9af52ccf
DA
2270 bgp_route_refresh_send(
2271 peer, afi, safi, ORF_TYPE_PREFIX_OLD,
2272 REFRESH_IMMEDIATE, 0,
2273 BGP_ROUTE_REFRESH_NORMAL);
05c7a1cc
QY
2274 }
2275 }
d62a17ae 2276
2277 /* First update is deferred until ORF or ROUTE-REFRESH is received */
05c7a1cc
QY
2278 FOREACH_AFI_SAFI (afi, safi) {
2279 if (CHECK_FLAG(peer->af_cap[afi][safi],
2280 PEER_CAP_ORF_PREFIX_RM_ADV))
d62a17ae 2281 if (CHECK_FLAG(peer->af_cap[afi][safi],
05c7a1cc
QY
2282 PEER_CAP_ORF_PREFIX_SM_RCV)
2283 || CHECK_FLAG(peer->af_cap[afi][safi],
2284 PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
2285 SET_FLAG(peer->af_sflags[afi][safi],
2286 PEER_STATUS_ORF_WAIT_REFRESH);
2287 }
d62a17ae 2288
2289 bgp_announce_peer(peer);
2290
2291 /* Start the route advertisement timer to send updates to the peer - if
2292 * BGP
2293 * is not in read-only mode. If it is, the timer will be started at the
2294 * end
2295 * of read-only mode.
2296 */
2297 if (!bgp_update_delay_active(peer->bgp)) {
e16d030c 2298 EVENT_OFF(peer->t_routeadv);
d62a17ae 2299 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
2300 }
718e3744 2301
d62a17ae 2302 if (peer->doppelganger && (peer->doppelganger->status != Deleted)) {
2303 if (bgp_debug_neighbor_events(peer))
2304 zlog_debug(
2305 "[Event] Deleting stub connection for peer %s",
2306 peer->host);
2307
2308 if (peer->doppelganger->status > Active)
2309 bgp_notify_send(peer->doppelganger, BGP_NOTIFY_CEASE,
2310 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
2311 else
2312 peer_delete(peer->doppelganger);
718e3744 2313 }
2314
19bd3dff
DS
2315 /*
2316 * If we are replacing the old peer for a doppelganger
2317 * then switch it around in the bgp->peerhash
2318 * the doppelgangers su and this peer's su are the same
2319 * so the hash_release is the same for either.
2320 */
8e3aae66 2321 (void)hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
19bd3dff 2322
21bfce98
RZ
2323 /* Start BFD peer if not already running. */
2324 if (peer->bfd_config)
2325 bgp_peer_bfd_update_source(peer);
2326
d62a17ae 2327 return ret;
718e3744 2328}
2329
2330/* Keepalive packet is received. */
4da144f3 2331static enum bgp_fsm_state_progress bgp_fsm_keepalive(struct peer *peer)
718e3744 2332{
e16d030c 2333 EVENT_OFF(peer->t_holdtime);
4da144f3 2334 return BGP_FSM_SUCCESS;
718e3744 2335}
2336
2337/* Update packet is received. */
4da144f3 2338static enum bgp_fsm_state_progress bgp_fsm_update(struct peer *peer)
718e3744 2339{
e16d030c 2340 EVENT_OFF(peer->t_holdtime);
4da144f3 2341 return BGP_FSM_SUCCESS;
718e3744 2342}
2343
2344/* This is empty event. */
4da144f3 2345static enum bgp_fsm_state_progress bgp_ignore(struct peer *peer)
718e3744 2346{
af4c2728 2347 flog_err(
e50f7cfd 2348 EC_BGP_FSM,
d62a17ae 2349 "%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d",
2350 peer->host, bgp_event_str[peer->cur_event],
2351 lookup_msg(bgp_status_msg, peer->status, NULL),
2352 bgp_event_str[peer->last_event],
2353 bgp_event_str[peer->last_major_event], peer->fd);
4da144f3 2354 return BGP_FSM_SUCCESS;
718e3744 2355}
6b0655a2 2356
6403814c 2357/* This is to handle unexpected events.. */
4da144f3 2358static enum bgp_fsm_state_progress bgp_fsm_exception(struct peer *peer)
6403814c 2359{
af4c2728 2360 flog_err(
e50f7cfd 2361 EC_BGP_FSM,
d62a17ae 2362 "%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d",
2363 peer->host, bgp_event_str[peer->cur_event],
2364 lookup_msg(bgp_status_msg, peer->status, NULL),
2365 bgp_event_str[peer->last_event],
2366 bgp_event_str[peer->last_major_event], peer->fd);
4da144f3 2367 return bgp_stop(peer);
6403814c
DS
2368}
2369
f8dcd38d 2370void bgp_fsm_nht_update(struct peer *peer, bool has_valid_nexthops)
fc9a856f 2371{
d62a17ae 2372 if (!peer)
2373 return;
2374
2375 switch (peer->status) {
2376 case Idle:
f8dcd38d 2377 if (has_valid_nexthops)
d62a17ae 2378 BGP_EVENT_ADD(peer, BGP_Start);
2379 break;
2380 case Connect:
f8dcd38d 2381 if (!has_valid_nexthops) {
e16d030c 2382 EVENT_OFF(peer->t_connect);
d62a17ae 2383 BGP_EVENT_ADD(peer, TCP_fatal_error);
2384 }
2385 break;
2386 case Active:
f8dcd38d 2387 if (has_valid_nexthops) {
e16d030c 2388 EVENT_OFF(peer->t_connect);
d62a17ae 2389 BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
2390 }
2391 break;
2392 case OpenSent:
2393 case OpenConfirm:
2394 case Established:
f8dcd38d 2395 if (!has_valid_nexthops
f852eb98
PG
2396 && (peer->gtsm_hops == BGP_GTSM_HOPS_CONNECTED
2397 || peer->bgp->fast_convergence))
d62a17ae 2398 BGP_EVENT_ADD(peer, TCP_fatal_error);
2399 case Clearing:
2400 case Deleted:
58cf0823 2401 case BGP_STATUS_MAX:
d62a17ae 2402 break;
fc9a856f 2403 }
fc9a856f
DS
2404}
2405
718e3744 2406/* Finite State Machine structure */
fda1d3e0 2407static const struct {
4da144f3 2408 enum bgp_fsm_state_progress (*func)(struct peer *);
8398b5d5 2409 enum bgp_fsm_status next_state;
d62a17ae 2410} FSM[BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] = {
2411 {
2412 /* Idle state: In Idle state, all events other than BGP_Start is
2413 ignored. With BGP_Start event, finite state machine calls
2414 bgp_start(). */
2415 {bgp_start, Connect}, /* BGP_Start */
2416 {bgp_stop, Idle}, /* BGP_Stop */
2417 {bgp_stop, Idle}, /* TCP_connection_open */
6c537a18 2418 {bgp_stop, Idle}, /* TCP_connection_open_w_delay */
d62a17ae 2419 {bgp_stop, Idle}, /* TCP_connection_closed */
2420 {bgp_ignore, Idle}, /* TCP_connection_open_failed */
2421 {bgp_stop, Idle}, /* TCP_fatal_error */
2422 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
2423 {bgp_ignore, Idle}, /* Hold_Timer_expired */
2424 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
6c537a18 2425 {bgp_ignore, Idle}, /* DelayOpen_timer_expired */
d62a17ae 2426 {bgp_ignore, Idle}, /* Receive_OPEN_message */
2427 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
2428 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
2429 {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
2430 {bgp_ignore, Idle}, /* Clearing_Completed */
2431 },
2432 {
2433 /* Connect */
2434 {bgp_ignore, Connect}, /* BGP_Start */
2435 {bgp_stop, Idle}, /* BGP_Stop */
2436 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
6c537a18
DS
2437 {bgp_connect_success_w_delayopen,
2438 Connect}, /* TCP_connection_open_w_delay */
4da144f3 2439 {bgp_stop, Idle}, /* TCP_connection_closed */
d62a17ae 2440 {bgp_connect_fail, Active}, /* TCP_connection_open_failed */
2441 {bgp_connect_fail, Idle}, /* TCP_fatal_error */
2442 {bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
4da144f3
DS
2443 {bgp_fsm_exception, Idle}, /* Hold_Timer_expired */
2444 {bgp_fsm_exception, Idle}, /* KeepAlive_timer_expired */
6c537a18
DS
2445 {bgp_fsm_delayopen_timer_expire,
2446 OpenSent}, /* DelayOpen_timer_expired */
2447 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
4da144f3
DS
2448 {bgp_fsm_exception, Idle}, /* Receive_KEEPALIVE_message */
2449 {bgp_fsm_exception, Idle}, /* Receive_UPDATE_message */
2450 {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
2451 {bgp_fsm_exception, Idle}, /* Clearing_Completed */
d62a17ae 2452 },
2453 {
2454 /* Active, */
2455 {bgp_ignore, Active}, /* BGP_Start */
2456 {bgp_stop, Idle}, /* BGP_Stop */
2457 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
6c537a18 2458 {bgp_connect_success_w_delayopen,
4da144f3
DS
2459 Active}, /* TCP_connection_open_w_delay */
2460 {bgp_stop, Idle}, /* TCP_connection_closed */
2461 {bgp_ignore, Active}, /* TCP_connection_open_failed */
2462 {bgp_fsm_exception, Idle}, /* TCP_fatal_error */
2463 {bgp_start, Connect}, /* ConnectRetry_timer_expired */
2464 {bgp_fsm_exception, Idle}, /* Hold_Timer_expired */
2465 {bgp_fsm_exception, Idle}, /* KeepAlive_timer_expired */
6c537a18
DS
2466 {bgp_fsm_delayopen_timer_expire,
2467 OpenSent}, /* DelayOpen_timer_expired */
2468 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
4da144f3
DS
2469 {bgp_fsm_exception, Idle}, /* Receive_KEEPALIVE_message */
2470 {bgp_fsm_exception, Idle}, /* Receive_UPDATE_message */
2471 {bgp_fsm_exception, Idle}, /* Receive_NOTIFICATION_message */
2472 {bgp_fsm_exception, Idle}, /* Clearing_Completed */
d62a17ae 2473 },
2474 {
2475 /* OpenSent, */
4da144f3
DS
2476 {bgp_ignore, OpenSent}, /* BGP_Start */
2477 {bgp_stop, Idle}, /* BGP_Stop */
2478 {bgp_stop, Active}, /* TCP_connection_open */
2479 {bgp_fsm_exception, Idle}, /* TCP_connection_open_w_delay */
2480 {bgp_stop, Active}, /* TCP_connection_closed */
2481 {bgp_stop, Active}, /* TCP_connection_open_failed */
2482 {bgp_stop, Active}, /* TCP_fatal_error */
2483 {bgp_fsm_exception, Idle}, /* ConnectRetry_timer_expired */
d62a17ae 2484 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
4da144f3
DS
2485 {bgp_fsm_exception, Idle}, /* KeepAlive_timer_expired */
2486 {bgp_fsm_exception, Idle}, /* DelayOpen_timer_expired */
d62a17ae 2487 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
2488 {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
2489 {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
53b4aaec 2490 {bgp_fsm_event_error, Idle}, /* Receive_NOTIFICATION_message */
4da144f3 2491 {bgp_fsm_exception, Idle}, /* Clearing_Completed */
d62a17ae 2492 },
2493 {
2494 /* OpenConfirm, */
2495 {bgp_ignore, OpenConfirm}, /* BGP_Start */
4da144f3
DS
2496 {bgp_stop, Idle}, /* BGP_Stop */
2497 {bgp_stop, Idle}, /* TCP_connection_open */
2498 {bgp_fsm_exception, Idle}, /* TCP_connection_open_w_delay */
2499 {bgp_stop, Idle}, /* TCP_connection_closed */
2500 {bgp_stop, Idle}, /* TCP_connection_open_failed */
2501 {bgp_stop, Idle}, /* TCP_fatal_error */
2502 {bgp_fsm_exception, Idle}, /* ConnectRetry_timer_expired */
d62a17ae 2503 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
2504 {bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
4da144f3
DS
2505 {bgp_fsm_exception, Idle}, /* DelayOpen_timer_expired */
2506 {bgp_fsm_exception, Idle}, /* Receive_OPEN_message */
d62a17ae 2507 {bgp_establish, Established}, /* Receive_KEEPALIVE_message */
4da144f3 2508 {bgp_fsm_exception, Idle}, /* Receive_UPDATE_message */
d62a17ae 2509 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
4da144f3 2510 {bgp_fsm_exception, Idle}, /* Clearing_Completed */
d62a17ae 2511 },
2512 {
2513 /* Established, */
2514 {bgp_ignore, Established}, /* BGP_Start */
4da144f3
DS
2515 {bgp_stop, Clearing}, /* BGP_Stop */
2516 {bgp_stop, Clearing}, /* TCP_connection_open */
2517 {bgp_fsm_exception, Idle}, /* TCP_connection_open_w_delay */
2518 {bgp_stop, Clearing}, /* TCP_connection_closed */
2519 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
2520 {bgp_stop, Clearing}, /* TCP_fatal_error */
2521 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
d62a17ae 2522 {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
03014d48 2523 {bgp_ignore, Established}, /* KeepAlive_timer_expired */
4da144f3
DS
2524 {bgp_fsm_exception, Idle}, /* DelayOpen_timer_expired */
2525 {bgp_stop, Clearing}, /* Receive_OPEN_message */
d62a17ae 2526 {bgp_fsm_keepalive,
2527 Established}, /* Receive_KEEPALIVE_message */
2528 {bgp_fsm_update, Established}, /* Receive_UPDATE_message */
2529 {bgp_stop_with_error,
4da144f3
DS
2530 Clearing}, /* Receive_NOTIFICATION_message */
2531 {bgp_fsm_exception, Idle}, /* Clearing_Completed */
d62a17ae 2532 },
2533 {
2534 /* Clearing, */
2535 {bgp_ignore, Clearing}, /* BGP_Start */
4da144f3
DS
2536 {bgp_stop, Clearing}, /* BGP_Stop */
2537 {bgp_stop, Clearing}, /* TCP_connection_open */
2538 {bgp_stop, Clearing}, /* TCP_connection_open_w_delay */
2539 {bgp_stop, Clearing}, /* TCP_connection_closed */
2540 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
2541 {bgp_stop, Clearing}, /* TCP_fatal_error */
2542 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
2543 {bgp_stop, Clearing}, /* Hold_Timer_expired */
2544 {bgp_stop, Clearing}, /* KeepAlive_timer_expired */
2545 {bgp_stop, Clearing}, /* DelayOpen_timer_expired */
2546 {bgp_stop, Clearing}, /* Receive_OPEN_message */
2547 {bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
2548 {bgp_stop, Clearing}, /* Receive_UPDATE_message */
2549 {bgp_stop, Clearing}, /* Receive_NOTIFICATION_message */
d62a17ae 2550 {bgp_clearing_completed, Idle}, /* Clearing_Completed */
2551 },
2552 {
2553 /* Deleted, */
2554 {bgp_ignore, Deleted}, /* BGP_Start */
2555 {bgp_ignore, Deleted}, /* BGP_Stop */
2556 {bgp_ignore, Deleted}, /* TCP_connection_open */
6c537a18 2557 {bgp_ignore, Deleted}, /* TCP_connection_open_w_delay */
d62a17ae 2558 {bgp_ignore, Deleted}, /* TCP_connection_closed */
2559 {bgp_ignore, Deleted}, /* TCP_connection_open_failed */
2560 {bgp_ignore, Deleted}, /* TCP_fatal_error */
2561 {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
2562 {bgp_ignore, Deleted}, /* Hold_Timer_expired */
2563 {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
6c537a18 2564 {bgp_ignore, Deleted}, /* DelayOpen_timer_expired */
d62a17ae 2565 {bgp_ignore, Deleted}, /* Receive_OPEN_message */
2566 {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
2567 {bgp_ignore, Deleted}, /* Receive_UPDATE_message */
2568 {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */
2569 {bgp_ignore, Deleted}, /* Clearing_Completed */
2570 },
718e3744 2571};
2572
718e3744 2573/* Execute event process. */
e6685141 2574void bgp_event(struct event *thread)
718e3744 2575{
d1060698 2576 enum bgp_fsm_events event;
d62a17ae 2577 struct peer *peer;
718e3744 2578
e16d030c
DS
2579 peer = EVENT_ARG(thread);
2580 event = EVENT_VAL(thread);
718e3744 2581
69ef3f31 2582 peer_lock(peer);
cc9f21da 2583 bgp_event_update(peer, event);
69ef3f31 2584 peer_unlock(peer);
1ff9a340
DS
2585}
2586
d1060698 2587int bgp_event_update(struct peer *peer, enum bgp_fsm_events event)
1ff9a340 2588{
8398b5d5 2589 enum bgp_fsm_status next;
4da144f3 2590 enum bgp_fsm_state_progress ret = 0;
d62a17ae 2591 struct peer *other;
2592 int passive_conn = 0;
2593 int dyn_nbr;
2594
d8151687
QY
2595 /* default return code */
2596 ret = FSM_PEER_NOOP;
2597
d62a17ae 2598 other = peer->doppelganger;
2599 passive_conn =
2600 (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) ? 1 : 0;
2601 dyn_nbr = peer_dynamic_neighbor(peer);
2602
2603 /* Logging this event. */
2604 next = FSM[peer->status - 1][event - 1].next_state;
2605
2606 if (bgp_debug_neighbor_events(peer) && peer->status != next)
2607 zlog_debug("%s [FSM] %s (%s->%s), fd %d", peer->host,
2608 bgp_event_str[event],
2609 lookup_msg(bgp_status_msg, peer->status, NULL),
2610 lookup_msg(bgp_status_msg, next, NULL), peer->fd);
2611
2612 peer->last_event = peer->cur_event;
2613 peer->cur_event = event;
2614
2615 /* Call function. */
2616 if (FSM[peer->status - 1][event - 1].func)
2617 ret = (*(FSM[peer->status - 1][event - 1].func))(peer);
2618
4da144f3
DS
2619 if (ret >= BGP_FSM_SUCCESS) {
2620 if (ret == BGP_FSM_SUCCESS_STATE_TRANSFER &&
2621 next == Established) {
d62a17ae 2622 /* The case when doppelganger swap accurred in
2623 bgp_establish.
2624 Update the peer pointer accordingly */
d8151687 2625 ret = FSM_PEER_TRANSFERRED;
d62a17ae 2626 peer = other;
2627 }
2628
2629 /* If status is changed. */
d8151687 2630 if (next != peer->status) {
d62a17ae 2631 bgp_fsm_change_status(peer, next);
2632
becedef6
QY
2633 /*
2634 * If we're going to ESTABLISHED then we executed a
2635 * peer transfer. In this case we can either return
2636 * FSM_PEER_TRANSITIONED or FSM_PEER_TRANSFERRED.
2637 * Opting for TRANSFERRED since transfer implies
2638 * session establishment.
2639 */
d8151687
QY
2640 if (ret != FSM_PEER_TRANSFERRED)
2641 ret = FSM_PEER_TRANSITIONED;
2642 }
2643
d62a17ae 2644 /* Make sure timer is set. */
2645 bgp_timer_set(peer);
2646
bea01226 2647 } else {
becedef6
QY
2648 /*
2649 * If we got a return value of -1, that means there was an
2650 * error, restart the FSM. Since bgp_stop() was called on the
2651 * peer. only a few fields are safe to access here. In any case
2652 * we need to indicate that the peer was stopped in the return
2653 * code.
2654 */
4da144f3
DS
2655 if (!dyn_nbr && !passive_conn && peer->bgp &&
2656 ret != BGP_FSM_FAILURE_AND_DELETE) {
af4c2728 2657 flog_err(
e50f7cfd 2658 EC_BGP_FSM,
3efd0893 2659 "%s [FSM] Failure handling event %s in state %s, prior events %s, %s, fd %d",
bea01226
QY
2660 peer->host, bgp_event_str[peer->cur_event],
2661 lookup_msg(bgp_status_msg, peer->status, NULL),
2662 bgp_event_str[peer->last_event],
2663 bgp_event_str[peer->last_major_event],
2664 peer->fd);
2665 bgp_stop(peer);
2666 bgp_fsm_change_status(peer, Idle);
2667 bgp_timer_set(peer);
2668 }
2669 ret = FSM_PEER_STOPPED;
d62a17ae 2670 }
bea01226 2671
d62a17ae 2672 return ret;
718e3744 2673}
794b37d5 2674/* BGP GR Code */
2675
2676int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp,
36235319
QY
2677 enum global_mode global_new_state,
2678 enum global_mode global_old_state)
794b37d5 2679{
2680 struct peer *peer = {0};
2681 struct listnode *node = {0};
2682 struct listnode *nnode = {0};
36235319 2683 enum peer_mode peer_old_state = PEER_INVALID;
794b37d5 2684
2685 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
2686
2687 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
2688 zlog_debug("%s [BGP_GR] Peer: (%s) :", __func__,
2689 peer->host);
794b37d5 2690
2691 peer_old_state = bgp_peer_gr_mode_get(peer);
2692
2693 if (peer_old_state == PEER_GLOBAL_INHERIT) {
2694
36235319
QY
2695 /*
2696 *Reset only these peers and send a
2697 *new open message with the change capabilities.
2698 *Considering the mode to be "global_new_state" and
2699 *do all operation accordingly
2700 */
794b37d5 2701
2702 switch (global_new_state) {
794b37d5 2703 case GLOBAL_HELPER:
794b37d5 2704 BGP_PEER_GR_HELPER_ENABLE(peer);
2705 break;
2706 case GLOBAL_GR:
794b37d5 2707 BGP_PEER_GR_ENABLE(peer);
2708 break;
2709 case GLOBAL_DISABLE:
794b37d5 2710 BGP_PEER_GR_DISABLE(peer);
2711 break;
2712 case GLOBAL_INVALID:
36235319
QY
2713 zlog_debug("%s [BGP_GR] GLOBAL_INVALID",
2714 __func__);
794b37d5 2715 return BGP_ERR_GR_OPERATION_FAILED;
794b37d5 2716 }
2717 }
2718 }
2719
2720 bgp->global_gr_present_state = global_new_state;
2721
794b37d5 2722 return BGP_GR_SUCCESS;
2723}
2724
2ba1fe69 2725int bgp_gr_update_all(struct bgp *bgp, int global_gr_cmd)
794b37d5 2726{
2727 enum global_mode global_new_state = GLOBAL_INVALID;
2728 enum global_mode global_old_state = GLOBAL_INVALID;
2729
2730 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
2731 zlog_debug("%s [BGP_GR]START: global_gr_cmd :%s:", __func__,
2732 print_global_gr_cmd(global_gr_cmd));
794b37d5 2733
2734 global_old_state = bgp_global_gr_mode_get(bgp);
2735
2ba1fe69 2736 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
2737 zlog_debug("[BGP_GR] global_old_gr_state :%s:",
2738 print_global_gr_mode(global_old_state));
794b37d5 2739
2ba1fe69 2740 if (global_old_state != GLOBAL_INVALID) {
794b37d5 2741 global_new_state =
2ba1fe69 2742 bgp->GLOBAL_GR_FSM[global_old_state][global_gr_cmd];
2743
2744 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
2745 zlog_debug("[BGP_GR] global_new_gr_state :%s:",
2746 print_global_gr_mode(global_new_state));
794b37d5 2747 } else {
36235319
QY
2748 zlog_err("%s [BGP_GR] global_old_state == GLOBAL_INVALID",
2749 __func__);
794b37d5 2750 return BGP_ERR_GR_OPERATION_FAILED;
2751 }
2752
2753 if (global_new_state == GLOBAL_INVALID) {
36235319
QY
2754 zlog_err("%s [BGP_GR] global_new_state == GLOBAL_INVALID",
2755 __func__);
794b37d5 2756 return BGP_ERR_GR_INVALID_CMD;
2757 }
2758 if (global_new_state == global_old_state) {
2759 /* Trace msg */
2ba1fe69 2760 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2761 zlog_debug(
36235319
QY
2762 "%s [BGP_GR] global_new_state == global_old_state :%s",
2763 __func__,
2764 print_global_gr_mode(global_new_state));
794b37d5 2765 return BGP_GR_NO_OPERATION;
2766 }
2767
36235319
QY
2768 return bgp_gr_lookup_n_update_all_peer(bgp, global_new_state,
2769 global_old_state);
794b37d5 2770}
2771
2ba1fe69 2772const char *print_peer_gr_mode(enum peer_mode pr_mode)
2773{
2774 const char *peer_gr_mode = NULL;
2775
2776 switch (pr_mode) {
2777 case PEER_HELPER:
2778 peer_gr_mode = "PEER_HELPER";
2779 break;
2780 case PEER_GR:
2781 peer_gr_mode = "PEER_GR";
2782 break;
2783 case PEER_DISABLE:
2784 peer_gr_mode = "PEER_DISABLE";
2785 break;
2786 case PEER_INVALID:
2787 peer_gr_mode = "PEER_INVALID";
2788 break;
2789 case PEER_GLOBAL_INHERIT:
2790 peer_gr_mode = "PEER_GLOBAL_INHERIT";
2791 break;
2792 }
2793
2794 return peer_gr_mode;
2795}
2796
2797const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd)
2798{
2799 const char *peer_gr_cmd = NULL;
2800
2801 switch (pr_gr_cmd) {
2802 case PEER_GR_CMD:
2803 peer_gr_cmd = "PEER_GR_CMD";
2804 break;
2805 case NO_PEER_GR_CMD:
2806 peer_gr_cmd = "NO_PEER_GR_CMD";
2807 break;
2808 case PEER_DISABLE_CMD:
b6e410f7 2809 peer_gr_cmd = "PEER_DISABLE_GR_CMD";
2ba1fe69 2810 break;
2811 case NO_PEER_DISABLE_CMD:
b6e410f7 2812 peer_gr_cmd = "NO_PEER_DISABLE_GR_CMD";
2ba1fe69 2813 break;
2814 case PEER_HELPER_CMD:
2815 peer_gr_cmd = "PEER_HELPER_CMD";
2816 break;
2817 case NO_PEER_HELPER_CMD:
2818 peer_gr_cmd = "NO_PEER_HELPER_CMD";
2819 break;
2820 }
2821
2822 return peer_gr_cmd;
2823}
2824
2825const char *print_global_gr_mode(enum global_mode gl_mode)
2826{
4b216f58 2827 const char *global_gr_mode = "???";
2ba1fe69 2828
2829 switch (gl_mode) {
2830 case GLOBAL_HELPER:
2831 global_gr_mode = "GLOBAL_HELPER";
2832 break;
2833 case GLOBAL_GR:
2834 global_gr_mode = "GLOBAL_GR";
2835 break;
2836 case GLOBAL_DISABLE:
2837 global_gr_mode = "GLOBAL_DISABLE";
2838 break;
2839 case GLOBAL_INVALID:
2840 global_gr_mode = "GLOBAL_INVALID";
2841 break;
2842 }
2843
2844 return global_gr_mode;
2845}
2846
2847const char *print_global_gr_cmd(enum global_gr_command gl_gr_cmd)
2848{
2849 const char *global_gr_cmd = NULL;
2850
2851 switch (gl_gr_cmd) {
2852 case GLOBAL_GR_CMD:
2853 global_gr_cmd = "GLOBAL_GR_CMD";
2854 break;
2855 case NO_GLOBAL_GR_CMD:
2856 global_gr_cmd = "NO_GLOBAL_GR_CMD";
2857 break;
2858 case GLOBAL_DISABLE_CMD:
2859 global_gr_cmd = "GLOBAL_DISABLE_CMD";
2860 break;
2861 case NO_GLOBAL_DISABLE_CMD:
2862 global_gr_cmd = "NO_GLOBAL_DISABLE_CMD";
2863 break;
2864 }
2865
2866 return global_gr_cmd;
2867}
2868
794b37d5 2869enum global_mode bgp_global_gr_mode_get(struct bgp *bgp)
2870{
2871 return bgp->global_gr_present_state;
2872}
2873
2874enum peer_mode bgp_peer_gr_mode_get(struct peer *peer)
2875{
2876 return peer->peer_gr_present_state;
2877}
2878
36235319 2879int bgp_neighbor_graceful_restart(struct peer *peer, int peer_gr_cmd)
794b37d5 2880{
36235319
QY
2881 enum peer_mode peer_new_state = PEER_INVALID;
2882 enum peer_mode peer_old_state = PEER_INVALID;
794b37d5 2883 struct bgp_peer_gr peer_state;
2884 int result = BGP_GR_FAILURE;
2885
2886 /*
2887 * fetch peer_old_state from peer structure also
2888 * fetch global_old_state from bgp structure,
2889 * peer had a back pointer to bgpo struct ;
2890 */
2891
2892 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
2893 zlog_debug("%s [BGP_GR] START:Peer: (%s) : peer_gr_cmd :%s:",
2894 __func__, peer->host,
2895 print_peer_gr_cmd(peer_gr_cmd));
794b37d5 2896
2897 peer_old_state = bgp_peer_gr_mode_get(peer);
2898
2899 if (peer_old_state == PEER_INVALID) {
36235319 2900 zlog_debug("[BGP_GR] peer_old_state == Invalid state !");
794b37d5 2901 return BGP_ERR_GR_OPERATION_FAILED;
2902 }
2903
2ba1fe69 2904 peer_state = peer->PEER_GR_FSM[peer_old_state][peer_gr_cmd];
794b37d5 2905 peer_new_state = peer_state.next_state;
2906
2907 if (peer_new_state == PEER_INVALID) {
794b37d5 2908 zlog_debug(
2ba1fe69 2909 "[BGP_GR] Invalid bgp graceful restart command used !");
794b37d5 2910 return BGP_ERR_GR_INVALID_CMD;
2911 }
2912
2913 if (peer_new_state != peer_old_state) {
36235319
QY
2914 result = peer_state.action_fun(peer, peer_old_state,
2915 peer_new_state);
794b37d5 2916 } else {
2ba1fe69 2917 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2918 zlog_debug(
36235319 2919 "[BGP_GR] peer_old_state == peer_new_state !");
794b37d5 2920 return BGP_GR_NO_OPERATION;
2921 }
2922
2923 if (result == BGP_GR_SUCCESS) {
2924
2925 /* Update the mode i.e peer_new_state into the peer structure */
2926 peer->peer_gr_present_state = peer_new_state;
794b37d5 2927 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319 2928 zlog_debug(
2089dd80 2929 "[BGP_GR] Successfully change the state of the peer to : %s : !",
36235319 2930 print_peer_gr_mode(peer_new_state));
794b37d5 2931
2932 return BGP_GR_SUCCESS;
2933 }
2934
2935 return result;
2936}
2937
36235319
QY
2938unsigned int bgp_peer_gr_action(struct peer *peer, int old_peer_state,
2939 int new_peer_state)
794b37d5 2940{
2941 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2942 zlog_debug(
2ba1fe69 2943 "%s [BGP_GR] Move peer from old_peer_state :%s: to new_peer_state :%s: !!!!",
2944 __func__, print_peer_gr_mode(old_peer_state),
2945 print_peer_gr_mode(new_peer_state));
794b37d5 2946
2947 int bgp_gr_global_mode = GLOBAL_INVALID;
2948 unsigned int ret = BGP_GR_FAILURE;
2949
2950 if (old_peer_state == new_peer_state) {
36235319
QY
2951 /* Nothing to do over here as the present and old state is the
2952 * same */
794b37d5 2953 return BGP_GR_NO_OPERATION;
2954 }
36235319
QY
2955 if ((old_peer_state == PEER_INVALID)
2956 || (new_peer_state == PEER_INVALID)) {
2957 /* something bad happend , print error message */
794b37d5 2958 return BGP_ERR_GR_INVALID_CMD;
2959 }
2960
2961 bgp_gr_global_mode = bgp_global_gr_mode_get(peer->bgp);
2962
36235319
QY
2963 if ((old_peer_state == PEER_GLOBAL_INHERIT)
2964 && (new_peer_state != PEER_GLOBAL_INHERIT)) {
794b37d5 2965
2966 /* fetch the Mode running in the Global state machine
2967 *from the bgp structure into a variable called
2968 *bgp_gr_global_mode
2969 */
2970
2971 /* Here we are checking if the
2972 *1. peer_new_state == global_mode == helper_mode
2973 *2. peer_new_state == global_mode == GR_mode
2974 *3. peer_new_state == global_mode == disabled_mode
2975 */
2976
2977 BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer);
2978
2979 if (new_peer_state == bgp_gr_global_mode) {
36235319
QY
2980 /*This is incremental updates i.e no tear down
2981 *of the existing session
2982 *as the peer is already working in the same mode.
2983 */
794b37d5 2984 ret = BGP_GR_SUCCESS;
2985 } else {
2986 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2987 zlog_debug(
2ba1fe69 2988 "[BGP_GR] Peer state changed from :%s ",
2989 print_peer_gr_mode(old_peer_state));
794b37d5 2990
2991 bgp_peer_move_to_gr_mode(peer, new_peer_state);
2992
2993 ret = BGP_GR_SUCCESS;
2994 }
2995 }
2996 /* In the case below peer is going into Global inherit mode i.e.
2997 * the peer would work as the mode configured at the global level
2998 */
36235319
QY
2999 else if ((new_peer_state == PEER_GLOBAL_INHERIT)
3000 && (old_peer_state != PEER_GLOBAL_INHERIT)) {
794b37d5 3001 /* Here in this case it would be destructive
3002 * in all the cases except one case when,
3003 * Global GR is configured Disabled
3004 * and present_peer_state is not disable
3005 */
3006
3007 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
3008
3009 if (old_peer_state == bgp_gr_global_mode) {
3010
3011 /* This is incremental updates
3012 *i.e no tear down of the existing session
3013 *as the peer is already working in the same mode.
3014 */
3015 ret = BGP_GR_SUCCESS;
3016 } else {
3017 /* Destructive always */
3018 /* Tear down the old session
3019 * and send the new capability
3020 * as per the bgp_gr_global_mode
3021 */
3022
3023 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
3024 zlog_debug(
3025 "[BGP_GR] Peer state changed from :%s",
2ba1fe69 3026 print_peer_gr_mode(old_peer_state));
794b37d5 3027
3028 bgp_peer_move_to_gr_mode(peer, bgp_gr_global_mode);
3029
3030 ret = BGP_GR_SUCCESS;
3031 }
3032 } else {
3033 /*
3034 *This else case, it include all the cases except -->
3035 *(new_peer_state != Peer_Global) &&
3036 *( old_peer_state != Peer_Global )
3037 */
3038 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2ba1fe69 3039 zlog_debug("[BGP_GR] Peer state changed from :%s",
36235319 3040 print_peer_gr_mode(old_peer_state));
794b37d5 3041
3042 bgp_peer_move_to_gr_mode(peer, new_peer_state);
3043
3044 ret = BGP_GR_SUCCESS;
3045 }
3046
3047 return ret;
3048}
3049
3050inline void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state)
3051
3052{
3053 int bgp_global_gr_mode = bgp_global_gr_mode_get(peer->bgp);
3054
3055 switch (new_state) {
794b37d5 3056 case PEER_HELPER:
3057 BGP_PEER_GR_HELPER_ENABLE(peer);
3058 break;
794b37d5 3059 case PEER_GR:
3060 BGP_PEER_GR_ENABLE(peer);
3061 break;
794b37d5 3062 case PEER_DISABLE:
3063 BGP_PEER_GR_DISABLE(peer);
3064 break;
794b37d5 3065 case PEER_GLOBAL_INHERIT:
3066 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
3067
3068 if (bgp_global_gr_mode == GLOBAL_HELPER) {
3069 BGP_PEER_GR_HELPER_ENABLE(peer);
36235319 3070 } else if (bgp_global_gr_mode == GLOBAL_GR) {
794b37d5 3071 BGP_PEER_GR_ENABLE(peer);
3072 } else if (bgp_global_gr_mode == GLOBAL_DISABLE) {
3073 BGP_PEER_GR_DISABLE(peer);
3074 } else {
2ba1fe69 3075 zlog_err(
36235319 3076 "[BGP_GR] Default switch inherit mode ::: SOMETHING IS WRONG !!!");
794b37d5 3077 }
3078 break;
3079 default:
36235319
QY
3080 zlog_err(
3081 "[BGP_GR] Default switch mode ::: SOMETHING IS WRONG !!!");
794b37d5 3082 break;
3083 }
3084 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2ba1fe69 3085 zlog_debug("[BGP_GR] Peer state changed --to--> : %d : !",
36235319 3086 new_state);
794b37d5 3087}
3088
3089void bgp_peer_gr_flags_update(struct peer *peer)
3090{
3091 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319 3092 zlog_debug("%s [BGP_GR] called !", __func__);
794b37d5 3093 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
36235319
QY
3094 PEER_GRACEFUL_RESTART_NEW_STATE_HELPER))
3095 SET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER);
794b37d5 3096 else
36235319 3097 UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER);
794b37d5 3098 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3099 zlog_debug(
2ba1fe69 3100 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !",
794b37d5 3101 peer->host,
2986cac2 3102 (CHECK_FLAG(peer->flags,
36235319
QY
3103 PEER_FLAG_GRACEFUL_RESTART_HELPER)
3104 ? "Set"
3105 : "UnSet"));
794b37d5 3106 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
36235319
QY
3107 PEER_GRACEFUL_RESTART_NEW_STATE_RESTART))
3108 SET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART);
794b37d5 3109 else
36235319 3110 UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART);
794b37d5 3111 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3112 zlog_debug(
2ba1fe69 3113 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !",
794b37d5 3114 peer->host,
36235319
QY
3115 (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
3116 ? "Set"
3117 : "UnSet"));
794b37d5 3118 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
36235319 3119 PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT))
2986cac2 3120 SET_FLAG(peer->flags,
36235319 3121 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
794b37d5 3122 else
2986cac2 3123 UNSET_FLAG(peer->flags,
36235319 3124 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
794b37d5 3125 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3126 zlog_debug(
36235319 3127 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !",
794b37d5 3128 peer->host,
2986cac2 3129 (CHECK_FLAG(peer->flags,
36235319
QY
3130 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT)
3131 ? "Set"
3132 : "UnSet"));
d7b3cda6 3133
36235319
QY
3134 if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
3135 && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)) {
3136 zlog_debug("[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_MODE!",
3137 peer->host);
d7b3cda6 3138
3139 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
3140
36235319 3141 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
d7b3cda6 3142
3143 peer_nsf_stop(peer);
3144 zlog_debug(
2ba1fe69 3145 "[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_WAIT!",
d7b3cda6 3146 peer->host);
3147 }
3148 }
794b37d5 3149}