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