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