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