]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_fsm.c
Merge pull request #12205 from proelbtn/fix-ipv4-vpn-nexthop-over-ipv6-peer
[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
fa5806c3
DS
180 THREAD_OFF(peer->t_routeadv);
181 THREAD_OFF(peer->t_connect);
182 THREAD_OFF(peer->t_delayopen);
183 THREAD_OFF(peer->t_connect_check_r);
184 THREAD_OFF(peer->t_connect_check_w);
185 THREAD_OFF(from_peer->t_routeadv);
186 THREAD_OFF(from_peer->t_connect);
187 THREAD_OFF(from_peer->t_delayopen);
188 THREAD_OFF(from_peer->t_connect_check_r);
189 THREAD_OFF(from_peer->t_connect_check_w);
190 THREAD_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 */
cb1991af 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) {
fa5806c3 368 THREAD_OFF(peer->t_start);
d62a17ae 369 } else {
370 BGP_TIMER_ON(peer->t_start, bgp_start_timer,
371 peer->v_start);
372 }
fa5806c3
DS
373 THREAD_OFF(peer->t_connect);
374 THREAD_OFF(peer->t_holdtime);
b72b6f4f 375 bgp_keepalives_off(peer);
fa5806c3
DS
376 THREAD_OFF(peer->t_routeadv);
377 THREAD_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. */
fa5806c3 384 THREAD_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
fa5806c3 392 THREAD_OFF(peer->t_holdtime);
b72b6f4f 393 bgp_keepalives_off(peer);
fa5806c3 394 THREAD_OFF(peer->t_routeadv);
d62a17ae 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. */
fa5806c3 400 THREAD_OFF(peer->t_start);
d62a17ae 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)) {
fa5806c3 404 THREAD_OFF(peer->t_connect);
d62a17ae 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 }
fa5806c3 414 THREAD_OFF(peer->t_holdtime);
b72b6f4f 415 bgp_keepalives_off(peer);
fa5806c3 416 THREAD_OFF(peer->t_routeadv);
d62a17ae 417 break;
418
419 case OpenSent:
420 /* OpenSent status. */
fa5806c3
DS
421 THREAD_OFF(peer->t_start);
422 THREAD_OFF(peer->t_connect);
d62a17ae 423 if (peer->v_holdtime != 0) {
424 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
425 peer->v_holdtime);
426 } else {
fa5806c3 427 THREAD_OFF(peer->t_holdtime);
d62a17ae 428 }
b72b6f4f 429 bgp_keepalives_off(peer);
fa5806c3
DS
430 THREAD_OFF(peer->t_routeadv);
431 THREAD_OFF(peer->t_delayopen);
d62a17ae 432 break;
433
434 case OpenConfirm:
435 /* OpenConfirm status. */
fa5806c3
DS
436 THREAD_OFF(peer->t_start);
437 THREAD_OFF(peer->t_connect);
d62a17ae 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) {
fa5806c3 442 THREAD_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 }
fa5806c3
DS
449 THREAD_OFF(peer->t_routeadv);
450 THREAD_OFF(peer->t_delayopen);
d62a17ae 451 break;
452
453 case Established:
454 /* In Established status start and connect timer is turned
455 off. */
fa5806c3
DS
456 THREAD_OFF(peer->t_start);
457 THREAD_OFF(peer->t_connect);
458 THREAD_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) {
fa5806c3 463 THREAD_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:
fa5806c3
DS
472 THREAD_OFF(peer->t_gr_restart);
473 THREAD_OFF(peer->t_gr_stale);
1479ed2f
DA
474
475 FOREACH_AFI_SAFI (afi, safi)
fa5806c3 476 THREAD_OFF(peer->t_llgr_stale[afi][safi]);
1479ed2f 477
fa5806c3
DS
478 THREAD_OFF(peer->t_pmax_restart);
479 THREAD_OFF(peer->t_refresh_stalepath);
d62a17ae 480 /* fallthru */
481 case Clearing:
fa5806c3
DS
482 THREAD_OFF(peer->t_start);
483 THREAD_OFF(peer->t_connect);
484 THREAD_OFF(peer->t_holdtime);
b72b6f4f 485 bgp_keepalives_off(peer);
fa5806c3
DS
486 THREAD_OFF(peer->t_routeadv);
487 THREAD_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 */
fa5806c3 519 THREAD_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
083ec940 577 peer->synctime = monotime(NULL);
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);
fa5806c3 650 THREAD_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
a10c2872 956 zlog_info("%s, update hold status %d", __func__,
d62a17ae 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;
fa5806c3 968 THREAD_OFF(peer->t_routeadv);
d62a17ae 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{
083ec940 978 time_t nowtime = monotime(NULL);
d62a17ae 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 */
fa5806c3 988 THREAD_OFF(peer->t_routeadv);
d62a17ae 989
083ec940 990 peer->synctime = monotime(NULL);
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) {
fa5806c3 1020 THREAD_OFF(peer->t_routeadv);
d62a17ae 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) {
fa5806c3 1047 THREAD_OFF(peer->t_routeadv);
d62a17ae 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
70cd87ca
MK
1333 /* BGP ORR : Update Active Root */
1334 bgp_peer_update_orr_active_roots(peer);
1335
d62a17ae 1336 if (bgp_debug_neighbor_events(peer))
1337 zlog_debug("%s went from %s to %s", peer->host,
1338 lookup_msg(bgp_status_msg, peer->ostatus, NULL),
1339 lookup_msg(bgp_status_msg, peer->status, NULL));
200df115 1340}
1341
3117b5c4 1342/* Flush the event queue and ensure the peer is shut down */
d62a17ae 1343static int bgp_clearing_completed(struct peer *peer)
3117b5c4 1344{
d62a17ae 1345 int rc = bgp_stop(peer);
1ff9a340 1346
d62a17ae 1347 if (rc >= 0)
1348 BGP_EVENT_FLUSH(peer);
3117b5c4 1349
d62a17ae 1350 return rc;
3117b5c4
SH
1351}
1352
718e3744 1353/* Administrative BGP peer stop event. */
3117b5c4 1354/* May be called multiple times for the same peer */
d62a17ae 1355int bgp_stop(struct peer *peer)
718e3744 1356{
d62a17ae 1357 afi_t afi;
1358 safi_t safi;
1359 char orf_name[BUFSIZ];
1360 int ret = 0;
f009ff26 1361 struct bgp *bgp = peer->bgp;
1362 struct graceful_restart_info *gr_info = NULL;
d62a17ae 1363
2ba1fe69 1364 peer->nsf_af_count = 0;
1365
e7db872b 1366 /* deregister peer */
21bfce98
RZ
1367 if (peer->bfd_config
1368 && peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE)
1369 bfd_sess_uninstall(peer->bfd_config->session);
e7db872b 1370
af8496af
DA
1371 if (peer_dynamic_neighbor_no_nsf(peer) &&
1372 !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
d62a17ae 1373 if (bgp_debug_neighbor_events(peer))
31afff83
DA
1374 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1375 peer->host, __func__);
d62a17ae 1376 peer_delete(peer);
1377 return -1;
c22767d8 1378 }
848973c7 1379
d62a17ae 1380 /* Can't do this in Clearing; events are used for state transitions */
1381 if (peer->status != Clearing) {
1382 /* Delete all existing events of the peer */
1383 BGP_EVENT_FLUSH(peer);
93406d87 1384 }
d62a17ae 1385
1386 /* Increment Dropped count. */
feb17238 1387 if (peer_established(peer)) {
d62a17ae 1388 peer->dropped++;
1389
1390 /* bgp log-neighbor-changes of neighbor Down */
892fedb6
DA
1391 if (CHECK_FLAG(peer->bgp->flags,
1392 BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
d62a17ae 1393 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
2986cac2 1394
d62a17ae 1395 zlog_info(
f70c91dc
DA
1396 "%%ADJCHANGE: neighbor %pBP in vrf %s Down %s",
1397 peer,
5742e42b 1398 vrf ? ((vrf->vrf_id != VRF_DEFAULT)
a7d91a8c
DA
1399 ? vrf->name
1400 : VRF_DEFAULT_NAME)
d62a17ae 1401 : "",
1402 peer_down_str[(int)peer->last_reset]);
1403 }
1404
1405 /* graceful restart */
1406 if (peer->t_gr_stale) {
fa5806c3 1407 THREAD_OFF(peer->t_gr_stale);
d62a17ae 1408 if (bgp_debug_neighbor_events(peer))
1409 zlog_debug(
f70c91dc
DA
1410 "%pBP graceful restart stalepath timer stopped",
1411 peer);
d62a17ae 1412 }
1413 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
1414 if (bgp_debug_neighbor_events(peer)) {
1415 zlog_debug(
f70c91dc
DA
1416 "%pBP graceful restart timer started for %d sec",
1417 peer, peer->v_gr_restart);
d62a17ae 1418 zlog_debug(
f70c91dc
DA
1419 "%pBP graceful restart stalepath timer started for %d sec",
1420 peer, peer->bgp->stalepath_time);
d62a17ae 1421 }
1422 BGP_TIMER_ON(peer->t_gr_restart,
1423 bgp_graceful_restart_timer_expire,
1424 peer->v_gr_restart);
1425 BGP_TIMER_ON(peer->t_gr_stale,
1426 bgp_graceful_stale_timer_expire,
1427 peer->bgp->stalepath_time);
1428 } else {
1429 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
1430
df8d723c
DA
1431 FOREACH_AFI_SAFI_NSF (afi, safi)
1432 peer->nsf[afi][safi] = 0;
d62a17ae 1433 }
1434
9af52ccf
DA
1435 /* Stop route-refresh stalepath timer */
1436 if (peer->t_refresh_stalepath) {
fa5806c3 1437 THREAD_OFF(peer->t_refresh_stalepath);
9af52ccf
DA
1438
1439 if (bgp_debug_neighbor_events(peer))
1440 zlog_debug(
f70c91dc
DA
1441 "%pBP route-refresh restart stalepath timer stopped",
1442 peer);
9af52ccf
DA
1443 }
1444
f009ff26 1445 /* If peer reset before receiving EOR, decrement EOR count and
1446 * cancel the selection deferral timer if there are no
1447 * pending EOR messages to be received
1448 */
1449 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
1450 FOREACH_AFI_SAFI (afi, safi) {
13909c4f
DS
1451 if (!peer->afc_nego[afi][safi]
1452 || CHECK_FLAG(peer->af_sflags[afi][safi],
1453 PEER_STATUS_EOR_RECEIVED))
1454 continue;
1455
1456 gr_info = &bgp->gr_info[afi][safi];
1457 if (!gr_info)
1458 continue;
1459
1460 if (gr_info->eor_required)
1461 gr_info->eor_required--;
1462
1463 if (BGP_DEBUG(update, UPDATE_OUT))
1464 zlog_debug("peer %s, EOR_required %d",
1465 peer->host,
1466 gr_info->eor_required);
1467
1468 /* There is no pending EOR message */
1469 if (gr_info->eor_required == 0) {
b96b4f1c
SB
1470 if (gr_info->t_select_deferral) {
1471 void *info = THREAD_ARG(
1472 gr_info->t_select_deferral);
1473 XFREE(MTYPE_TMP, info);
1474 }
fa5806c3 1475 THREAD_OFF(gr_info->t_select_deferral);
13909c4f 1476 gr_info->eor_received = 0;
f009ff26 1477 }
1478 }
1479 }
1480
d62a17ae 1481 /* set last reset time */
083ec940 1482 peer->resettime = peer->uptime = monotime(NULL);
d62a17ae 1483
1484 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1485 zlog_debug("%s remove from all update group",
1486 peer->host);
1487 update_group_remove_peer_afs(peer);
1488
d62a17ae 1489 /* Reset peer synctime */
1490 peer->synctime = 0;
93406d87 1491 }
93406d87 1492
424ab01d 1493 /* stop keepalives */
b72b6f4f 1494 bgp_keepalives_off(peer);
424ab01d
QY
1495
1496 /* Stop read and write threads. */
1497 bgp_writes_off(peer);
1498 bgp_reads_off(peer);
1499
387f984e
QY
1500 THREAD_OFF(peer->t_connect_check_r);
1501 THREAD_OFF(peer->t_connect_check_w);
d62a17ae 1502
1503 /* Stop all timers. */
fa5806c3
DS
1504 THREAD_OFF(peer->t_start);
1505 THREAD_OFF(peer->t_connect);
1506 THREAD_OFF(peer->t_holdtime);
1507 THREAD_OFF(peer->t_routeadv);
1508 THREAD_OFF(peer->t_delayopen);
d62a17ae 1509
1510 /* Clear input and output buffer. */
cb1991af 1511 frr_with_mutex (&peer->io_mtx) {
424ab01d
QY
1512 if (peer->ibuf)
1513 stream_fifo_clean(peer->ibuf);
d3ecc69e
QY
1514 if (peer->obuf)
1515 stream_fifo_clean(peer->obuf);
424ab01d
QY
1516
1517 if (peer->ibuf_work)
74ffbfe6 1518 ringbuf_wipe(peer->ibuf_work);
424ab01d
QY
1519 if (peer->obuf_work)
1520 stream_reset(peer->obuf_work);
1521
1522 if (peer->curr) {
1523 stream_free(peer->curr);
1524 peer->curr = NULL;
1525 }
d3ecc69e 1526 }
d62a17ae 1527
1528 /* Close of file descriptor. */
1529 if (peer->fd >= 0) {
1530 close(peer->fd);
1531 peer->fd = -1;
93406d87 1532 }
1533
24f569e9
AS
1534 /* Reset capabilities. */
1535 peer->cap = 0;
1536
d864dd9e 1537 /* Resetting neighbor role to the default value */
8f2d6021 1538 peer->remote_role = ROLE_UNDEFINED;
d864dd9e 1539
05c7a1cc
QY
1540 FOREACH_AFI_SAFI (afi, safi) {
1541 /* Reset all negotiated variables */
1542 peer->afc_nego[afi][safi] = 0;
1543 peer->afc_adv[afi][safi] = 0;
1544 peer->afc_recv[afi][safi] = 0;
1545
1546 /* peer address family capability flags*/
1547 peer->af_cap[afi][safi] = 0;
1548
1549 /* peer address family status flags*/
1550 peer->af_sflags[afi][safi] = 0;
1551
1552 /* Received ORF prefix-filter */
1553 peer->orf_plist[afi][safi] = NULL;
1554
feb17238 1555 if ((peer->status == OpenConfirm) || (peer_established(peer))) {
05c7a1cc 1556 /* ORF received prefix-filter pnt */
fc746f1c
QY
1557 snprintf(orf_name, sizeof(orf_name), "%s.%d.%d",
1558 peer->host, afi, safi);
05c7a1cc 1559 prefix_bgp_orf_remove_all(afi, orf_name);
d62a17ae 1560 }
05c7a1cc 1561 }
d62a17ae 1562
1563 /* Reset keepalive and holdtime */
b90a8e13 1564 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) {
d62a17ae 1565 peer->v_keepalive = peer->keepalive;
1566 peer->v_holdtime = peer->holdtime;
1567 } else {
1568 peer->v_keepalive = peer->bgp->default_keepalive;
1569 peer->v_holdtime = peer->bgp->default_holdtime;
1ff9a340 1570 }
d62a17ae 1571
6c537a18
DS
1572 /* Reset DelayOpenTime */
1573 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
1574 peer->v_delayopen = peer->delayopen;
1575 else
1576 peer->v_delayopen = peer->bgp->default_delayopen;
1577
d62a17ae 1578 peer->update_time = 0;
1579
d62a17ae 1580 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)
1581 && !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
1582 peer_delete(peer);
1583 ret = -1;
1584 } else {
1585 bgp_peer_conf_if_to_su_update(peer);
1586 }
d62a17ae 1587 return ret;
718e3744 1588}
1589
1590/* BGP peer is stoped by the error. */
d62a17ae 1591static int bgp_stop_with_error(struct peer *peer)
718e3744 1592{
d62a17ae 1593 /* Double start timer. */
1594 peer->v_start *= 2;
1595
1596 /* Overflow check. */
1597 if (peer->v_start >= (60 * 2))
1598 peer->v_start = (60 * 2);
1599
af8496af 1600 if (peer_dynamic_neighbor_no_nsf(peer)) {
d62a17ae 1601 if (bgp_debug_neighbor_events(peer))
31afff83
DA
1602 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1603 peer->host, __func__);
d62a17ae 1604 peer_delete(peer);
1605 return -1;
1606 }
1607
1608 return (bgp_stop(peer));
718e3744 1609}
1610
397b5bde
LR
1611
1612/* something went wrong, send notify and tear down */
d7c0a89a
QY
1613static int bgp_stop_with_notify(struct peer *peer, uint8_t code,
1614 uint8_t sub_code)
397b5bde 1615{
d62a17ae 1616 /* Send notify to remote peer */
1617 bgp_notify_send(peer, code, sub_code);
1618
af8496af 1619 if (peer_dynamic_neighbor_no_nsf(peer)) {
d62a17ae 1620 if (bgp_debug_neighbor_events(peer))
31afff83
DA
1621 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1622 peer->host, __func__);
d62a17ae 1623 peer_delete(peer);
1624 return -1;
1625 }
f14e6fdb 1626
d62a17ae 1627 /* Clear start timer value to default. */
1628 peer->v_start = BGP_INIT_START_TIMER;
397b5bde 1629
d62a17ae 1630 return (bgp_stop(peer));
397b5bde
LR
1631}
1632
07a16526
QY
1633/**
1634 * Determines whether a TCP session has successfully established for a peer and
1635 * events as appropriate.
1636 *
1637 * This function is called when setting up a new session. After connect() is
387f984e
QY
1638 * called on the peer's socket (in bgp_start()), the fd is passed to poll()
1639 * to wait for connection success or failure. When poll() returns, this
07a16526 1640 * function is called to evaluate the result.
387f984e
QY
1641 *
1642 * Due to differences in behavior of poll() on Linux and BSD - specifically,
1643 * the value of .revents in the case of a closed connection - this function is
1644 * scheduled both for a read and a write event. The write event is triggered
1645 * when the connection is established. A read event is triggered when the
1646 * connection is closed. Thus we need to cancel whichever one did not occur.
07a16526 1647 */
cc9f21da 1648static void bgp_connect_check(struct thread *thread)
07a16526
QY
1649{
1650 int status;
1651 socklen_t slen;
1652 int ret;
1653 struct peer *peer;
1654
1655 peer = THREAD_ARG(thread);
424ab01d
QY
1656 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
1657 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
1658 assert(!peer->t_read);
1659 assert(!peer->t_write);
07a16526 1660
387f984e
QY
1661 THREAD_OFF(peer->t_connect_check_r);
1662 THREAD_OFF(peer->t_connect_check_w);
dc1188bb 1663
07a16526
QY
1664 /* Check file descriptor. */
1665 slen = sizeof(status);
1666 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *)&status,
1667 &slen);
1668
1669 /* If getsockopt is fail, this is fatal error. */
1670 if (ret < 0) {
4cb5e18b 1671 zlog_err("can't get sockopt for nonblocking connect: %d(%s)",
54ff5e9b 1672 errno, safe_strerror(errno));
07a16526 1673 BGP_EVENT_ADD(peer, TCP_fatal_error);
cc9f21da 1674 return;
07a16526
QY
1675 }
1676
1677 /* When status is 0 then TCP connection is established. */
1678 if (status == 0) {
6c537a18
DS
1679 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
1680 BGP_EVENT_ADD(peer, TCP_connection_open_w_delay);
1681 else
1682 BGP_EVENT_ADD(peer, TCP_connection_open);
cc9f21da 1683 return;
07a16526
QY
1684 } else {
1685 if (bgp_debug_neighbor_events(peer))
54ff5e9b
DS
1686 zlog_debug("%s [Event] Connect failed %d(%s)",
1687 peer->host, status, safe_strerror(status));
07a16526 1688 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
cc9f21da 1689 return;
07a16526
QY
1690 }
1691}
397b5bde 1692
718e3744 1693/* TCP connection open. Next we send open message to remote peer. And
1694 add read thread for reading open message. */
d62a17ae 1695static int bgp_connect_success(struct peer *peer)
718e3744 1696{
d62a17ae 1697 if (peer->fd < 0) {
a10c2872 1698 flog_err(EC_BGP_CONNECT, "%s peer's fd is negative value %d",
1699 __func__, peer->fd);
d62a17ae 1700 bgp_stop(peer);
1701 return -1;
1702 }
1703
1704 if (bgp_getsockname(peer) < 0) {
450971aa 1705 flog_err_sys(EC_LIB_SOCKET,
09c866e3 1706 "%s: bgp_getsockname(): failed for peer %s, fd %d",
15569c58 1707 __func__, peer->host, peer->fd);
3893aeee
DA
1708 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
1709 bgp_fsm_error_subcode(peer->status));
424ab01d 1710 bgp_writes_on(peer);
d62a17ae 1711 return -1;
1712 }
1713
cea8b655
DS
1714 /*
1715 * If we are doing nht for a peer that ls v6 LL based
1716 * massage the event system to make things happy
1717 */
1718 bgp_nht_interface_events(peer);
1719
424ab01d 1720 bgp_reads_on(peer);
d62a17ae 1721
1722 if (bgp_debug_neighbor_events(peer)) {
d62a17ae 1723 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
c0d72166
DS
1724 zlog_debug("%s open active, local address %pSU",
1725 peer->host, peer->su_local);
d62a17ae 1726 else
1727 zlog_debug("%s passive open", peer->host);
1728 }
1729
6c537a18 1730 /* Send an open message */
d62a17ae 1731 bgp_open_send(peer);
1732
1733 return 0;
718e3744 1734}
1735
6c537a18
DS
1736/* TCP connection open with RFC 4271 optional session attribute DelayOpen flag
1737 * set.
1738 */
1739static int bgp_connect_success_w_delayopen(struct peer *peer)
1740{
1741 if (peer->fd < 0) {
1742 flog_err(EC_BGP_CONNECT, "%s: peer's fd is negative value %d",
1743 __func__, peer->fd);
1744 bgp_stop(peer);
1745 return -1;
1746 }
1747
1748 if (bgp_getsockname(peer) < 0) {
1749 flog_err_sys(EC_LIB_SOCKET,
1750 "%s: bgp_getsockname(): failed for peer %s, fd %d",
1751 __func__, peer->host, peer->fd);
1752 bgp_notify_send(peer, BGP_NOTIFY_FSM_ERR,
1753 bgp_fsm_error_subcode(peer->status));
1754 bgp_writes_on(peer);
1755 return -1;
1756 }
1757
cea8b655
DS
1758 /*
1759 * If we are doing nht for a peer that ls v6 LL based
1760 * massage the event system to make things happy
1761 */
1762 bgp_nht_interface_events(peer);
1763
6c537a18
DS
1764 bgp_reads_on(peer);
1765
1766 if (bgp_debug_neighbor_events(peer)) {
6c537a18 1767 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
c0d72166
DS
1768 zlog_debug("%s open active, local address %pSU",
1769 peer->host, peer->su_local);
6c537a18
DS
1770 else
1771 zlog_debug("%s passive open", peer->host);
1772 }
1773
1774 /* set the DelayOpenTime to the inital value */
1775 peer->v_delayopen = peer->delayopen;
1776
1777 /* Start the DelayOpenTimer if it is not already running */
1778 if (!peer->t_delayopen)
1779 BGP_TIMER_ON(peer->t_delayopen, bgp_delayopen_timer,
1780 peer->v_delayopen);
1781
1782 if (bgp_debug_neighbor_events(peer))
1783 zlog_debug("%s [FSM] BGP OPEN message delayed for %d seconds",
1784 peer->host, peer->delayopen);
1785
1786 return 0;
1787}
1788
718e3744 1789/* TCP connect fail */
d62a17ae 1790static int bgp_connect_fail(struct peer *peer)
718e3744 1791{
af8496af 1792 if (peer_dynamic_neighbor_no_nsf(peer)) {
d62a17ae 1793 if (bgp_debug_neighbor_events(peer))
31afff83
DA
1794 zlog_debug("%s (dynamic neighbor) deleted (%s)",
1795 peer->host, __func__);
d62a17ae 1796 peer_delete(peer);
1797 return -1;
1798 }
1799
8761cd6d
DS
1800 /*
1801 * If we are doing nht for a peer that ls v6 LL based
1802 * massage the event system to make things happy
1803 */
1804 bgp_nht_interface_events(peer);
1805
d62a17ae 1806 return (bgp_stop(peer));
718e3744 1807}
1808
1809/* This function is the first starting point of all BGP connection. It
6c537a18
DS
1810 * try to connect to remote peer with non-blocking IO.
1811 */
d62a17ae 1812int bgp_start(struct peer *peer)
718e3744 1813{
d62a17ae 1814 int status;
d62a17ae 1815
1816 bgp_peer_conf_if_to_su_update(peer);
1817
1818 if (peer->su.sa.sa_family == AF_UNSPEC) {
1819 if (bgp_debug_neighbor_events(peer))
1820 zlog_debug(
1821 "%s [FSM] Unable to get neighbor's IP address, waiting...",
1822 peer->host);
3577f1c5 1823 peer->last_reset = PEER_DOWN_NBR_ADDR;
d62a17ae 1824 return -1;
1825 }
1826
1827 if (BGP_PEER_START_SUPPRESSED(peer)) {
1828 if (bgp_debug_neighbor_events(peer))
e50f7cfd 1829 flog_err(EC_BGP_FSM,
3efd0893 1830 "%s [FSM] Trying to start suppressed peer - this is never supposed to happen!",
1c50c1c0 1831 peer->host);
07d1e5d9
DA
1832 if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
1833 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
cb9196e7
DS
1834 else if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHUTDOWN))
1835 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
07d1e5d9
DA
1836 else if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
1837 peer->last_reset = PEER_DOWN_PFX_COUNT;
d62a17ae 1838 return -1;
1839 }
1840
1841 /* Scrub some information that might be left over from a previous,
1842 * session
1843 */
1844 /* Connection information. */
1845 if (peer->su_local) {
1846 sockunion_free(peer->su_local);
1847 peer->su_local = NULL;
1848 }
1849
1850 if (peer->su_remote) {
1851 sockunion_free(peer->su_remote);
1852 peer->su_remote = NULL;
1853 }
1854
1855 /* Clear remote router-id. */
975a328e 1856 peer->remote_id.s_addr = INADDR_ANY;
d62a17ae 1857
1858 /* Clear peer capability flag. */
1859 peer->cap = 0;
1860
1861 /* If the peer is passive mode, force to move to Active mode. */
1862 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)) {
1863 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1864 return 0;
1865 }
1866
2c1eba8e 1867 if (peer->bgp->vrf_id == VRF_UNKNOWN) {
61cf4b37 1868 if (bgp_debug_neighbor_events(peer))
af4c2728 1869 flog_err(
e50f7cfd 1870 EC_BGP_FSM,
996c9314
LB
1871 "%s [FSM] In a VRF that is not initialised yet",
1872 peer->host);
3577f1c5 1873 peer->last_reset = PEER_DOWN_VRF_UNINIT;
61cf4b37
PG
1874 return -1;
1875 }
1876
e2d3a909 1877 /* Register peer for NHT. If next hop is already resolved, proceed
1878 * with connection setup, else wait.
1879 */
1880 if (!bgp_peer_reg_with_nht(peer)) {
c42eab4b
DS
1881 if (bgp_zebra_num_connects()) {
1882 if (bgp_debug_neighbor_events(peer))
1883 zlog_debug("%s [FSM] Waiting for NHT",
1884 peer->host);
3577f1c5 1885 peer->last_reset = PEER_DOWN_WAITING_NHT;
c42eab4b
DS
1886 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1887 return 0;
1888 }
718e3744 1889 }
d62a17ae 1890
424ab01d
QY
1891 assert(!peer->t_write);
1892 assert(!peer->t_read);
1893 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
1894 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
d62a17ae 1895 status = bgp_connect(peer);
1896
1897 switch (status) {
1898 case connect_error:
1899 if (bgp_debug_neighbor_events(peer))
1900 zlog_debug("%s [FSM] Connect error", peer->host);
1901 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1902 break;
1903 case connect_success:
1904 if (bgp_debug_neighbor_events(peer))
1905 zlog_debug(
1906 "%s [FSM] Connect immediately success, fd %d",
1907 peer->host, peer->fd);
6c537a18 1908
d62a17ae 1909 BGP_EVENT_ADD(peer, TCP_connection_open);
1910 break;
1911 case connect_in_progress:
1912 /* To check nonblocking connect, we wait until socket is
1913 readable or writable. */
1914 if (bgp_debug_neighbor_events(peer))
1915 zlog_debug(
1916 "%s [FSM] Non blocking connect waiting result, fd %d",
1917 peer->host, peer->fd);
1918 if (peer->fd < 0) {
e50f7cfd 1919 flog_err(EC_BGP_FSM,
a10c2872 1920 "%s peer's fd is negative value %d", __func__,
1c50c1c0 1921 peer->fd);
d62a17ae 1922 return -1;
1923 }
becedef6 1924 /*
387f984e
QY
1925 * - when the socket becomes ready, poll() will signify POLLOUT
1926 * - if it fails to connect, poll() will signify POLLHUP
1927 * - POLLHUP is handled as a 'read' event by thread.c
1928 *
1929 * therefore, we schedule both a read and a write event with
1930 * bgp_connect_check() as the handler for each and cancel the
1931 * unused event in that function.
becedef6 1932 */
424ab01d 1933 thread_add_read(bm->master, bgp_connect_check, peer, peer->fd,
387f984e
QY
1934 &peer->t_connect_check_r);
1935 thread_add_write(bm->master, bgp_connect_check, peer, peer->fd,
1936 &peer->t_connect_check_w);
d62a17ae 1937 break;
1938 }
1939 return 0;
718e3744 1940}
1941
1942/* Connect retry timer is expired when the peer status is Connect. */
d62a17ae 1943static int bgp_reconnect(struct peer *peer)
718e3744 1944{
d62a17ae 1945 if (bgp_stop(peer) < 0)
1946 return -1;
1ff9a340 1947
8c48b3b6 1948 /* Send graceful restart capabilty */
36235319
QY
1949 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
1950 peer->bgp->peer);
8c48b3b6 1951
d62a17ae 1952 bgp_start(peer);
1953 return 0;
718e3744 1954}
1955
d62a17ae 1956static int bgp_fsm_open(struct peer *peer)
718e3744 1957{
6c537a18
DS
1958 /* If DelayOpen is active, we may still need to send an open message */
1959 if ((peer->status == Connect) || (peer->status == Active))
1960 bgp_open_send(peer);
1961
d62a17ae 1962 /* Send keepalive and make keepalive timer */
1963 bgp_keepalive_send(peer);
718e3744 1964
d62a17ae 1965 return 0;
718e3744 1966}
1967
397b5bde
LR
1968/* FSM error, unexpected event. This is error of BGP connection. So cut the
1969 peer and change to Idle status. */
d62a17ae 1970static int bgp_fsm_event_error(struct peer *peer)
397b5bde 1971{
1c50c1c0
QY
1972 flog_err(EC_BGP_FSM, "%s [FSM] unexpected packet received in state %s",
1973 peer->host, lookup_msg(bgp_status_msg, peer->status, NULL));
397b5bde 1974
3893aeee
DA
1975 return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR,
1976 bgp_fsm_error_subcode(peer->status));
397b5bde
LR
1977}
1978
718e3744 1979/* Hold timer expire. This is error of BGP connection. So cut the
1980 peer and change to Idle status. */
d62a17ae 1981static int bgp_fsm_holdtime_expire(struct peer *peer)
718e3744 1982{
d62a17ae 1983 if (bgp_debug_neighbor_events(peer))
1984 zlog_debug("%s [FSM] Hold timer expire", peer->host);
718e3744 1985
20170775
DA
1986 /* RFC8538 updates RFC 4724 by defining an extension that permits
1987 * the Graceful Restart procedures to be performed when the BGP
1988 * speaker receives a BGP NOTIFICATION message or the Hold Time expires.
1989 */
1990 if (peer_established(peer) &&
1991 bgp_has_graceful_restart_notification(peer))
1992 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE))
1993 SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
1994
d62a17ae 1995 return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0);
718e3744 1996}
1997
6c537a18
DS
1998/* RFC 4271 DelayOpenTimer_Expires event */
1999static int bgp_fsm_delayopen_timer_expire(struct peer *peer)
2000{
2001 /* Stop the DelayOpenTimer */
fa5806c3 2002 THREAD_OFF(peer->t_delayopen);
6c537a18
DS
2003
2004 /* Send open message to peer */
2005 bgp_open_send(peer);
2006
2007 /* Set the HoldTimer to a large value (4 minutes) */
2008 peer->v_holdtime = 245;
2009
2010 return 0;
2011}
2012
f009ff26 2013/* Start the selection deferral timer thread for the specified AFI, SAFI */
2014static int bgp_start_deferral_timer(struct bgp *bgp, afi_t afi, safi_t safi,
36235319 2015 struct graceful_restart_info *gr_info)
f009ff26 2016{
2017 struct afi_safi_info *thread_info;
2018
2019 /* If the deferral timer is active, then increment eor count */
2020 if (gr_info->t_select_deferral) {
2021 gr_info->eor_required++;
2022 return 0;
2023 }
2024
2025 /* Start the deferral timer when the first peer enabled for the graceful
2026 * restart is established
2027 */
2028 if (gr_info->eor_required == 0) {
2029 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
f009ff26 2030
2031 thread_info->afi = afi;
2032 thread_info->safi = safi;
2033 thread_info->bgp = bgp;
2034
13909c4f
DS
2035 thread_add_timer(bm->master, bgp_graceful_deferral_timer_expire,
2036 thread_info, bgp->select_defer_time,
2037 &gr_info->t_select_deferral);
f009ff26 2038 }
f009ff26 2039 gr_info->eor_required++;
8c48b3b6 2040 /* Send message to RIB indicating route update pending */
2041 if (gr_info->af_enabled[afi][safi] == false) {
2042 gr_info->af_enabled[afi][safi] = true;
2043 /* Send message to RIB */
2044 bgp_zebra_update(afi, safi, bgp->vrf_id,
2045 ZEBRA_CLIENT_ROUTE_UPDATE_PENDING);
2046 }
f009ff26 2047 if (BGP_DEBUG(update, UPDATE_OUT))
2048 zlog_debug("Started the deferral timer for %s eor_required %d",
36235319
QY
2049 get_afi_safi_str(afi, safi, false),
2050 gr_info->eor_required);
f009ff26 2051 return 0;
2052}
2053
2054/* Update the graceful restart information for the specified AFI, SAFI */
2055static int bgp_update_gr_info(struct peer *peer, afi_t afi, safi_t safi)
2056{
2057 struct graceful_restart_info *gr_info;
2058 struct bgp *bgp = peer->bgp;
2059 int ret = 0;
2060
2061 if ((afi < AFI_IP) || (afi >= AFI_MAX)) {
2062 if (BGP_DEBUG(update, UPDATE_OUT))
2063 zlog_debug("%s : invalid afi %d", __func__, afi);
2064 return -1;
2065 }
2066
2067 if ((safi < SAFI_UNICAST) || (safi > SAFI_MPLS_VPN)) {
2068 if (BGP_DEBUG(update, UPDATE_OUT))
2069 zlog_debug("%s : invalid safi %d", __func__, safi);
2070 return -1;
2071 }
2072
2073 /* Restarting router */
36235319
QY
2074 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
2075 && BGP_PEER_RESTARTING_MODE(peer)) {
f009ff26 2076 /* Check if the forwarding state is preserved */
892fedb6 2077 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)) {
f009ff26 2078 gr_info = &(bgp->gr_info[afi][safi]);
2079 ret = bgp_start_deferral_timer(bgp, afi, safi, gr_info);
2080 }
2081 }
2ba1fe69 2082 return ret;
f009ff26 2083}
2084
727c4f87
QY
2085/**
2086 * Transition to Established state.
2087 *
2088 * Convert peer from stub to full fledged peer, set some timers, and generate
2089 * initial updates.
2090 */
d62a17ae 2091static int bgp_establish(struct peer *peer)
718e3744 2092{
d62a17ae 2093 afi_t afi;
2094 safi_t safi;
2095 int nsf_af_count = 0;
2096 int ret = 0;
2097 struct peer *other;
f009ff26 2098 int status;
d62a17ae 2099
2100 other = peer->doppelganger;
2101 peer = peer_xfer_conn(peer);
2102 if (!peer) {
e50f7cfd 2103 flog_err(EC_BGP_CONNECT, "%%Neighbor failed in xfer_conn");
d62a17ae 2104 return -1;
93406d87 2105 }
93406d87 2106
d62a17ae 2107 if (other == peer)
996c9314
LB
2108 ret = 1; /* bgp_establish specific code when xfer_conn
2109 happens. */
d62a17ae 2110
2111 /* Reset capability open status flag. */
2112 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
2113 SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2114
2115 /* Clear start timer value to default. */
2116 peer->v_start = BGP_INIT_START_TIMER;
2117
2118 /* Increment established count. */
2119 peer->established++;
2120 bgp_fsm_change_status(peer, Established);
2121
2122 /* bgp log-neighbor-changes of neighbor Up */
892fedb6 2123 if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
d62a17ae 2124 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
f70c91dc 2125 zlog_info("%%ADJCHANGE: neighbor %pBP in vrf %s Up", peer,
a7d91a8c
DA
2126 vrf ? ((vrf->vrf_id != VRF_DEFAULT)
2127 ? vrf->name
2128 : VRF_DEFAULT_NAME)
2129 : "");
d62a17ae 2130 }
2131 /* assign update-group/subgroup */
2132 update_group_adjust_peer_afs(peer);
2133
2134 /* graceful restart */
2135 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
f009ff26 2136 if (bgp_debug_neighbor_events(peer)) {
2137 if (BGP_PEER_RESTARTING_MODE(peer))
f70c91dc 2138 zlog_debug("%pBP BGP_RESTARTING_MODE", peer);
f009ff26 2139 else if (BGP_PEER_HELPER_MODE(peer))
f70c91dc 2140 zlog_debug("%pBP BGP_HELPER_MODE", peer);
f009ff26 2141 }
df8d723c
DA
2142
2143 FOREACH_AFI_SAFI_NSF (afi, safi) {
2144 if (peer->afc_nego[afi][safi] &&
2145 CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV) &&
2146 CHECK_FLAG(peer->af_cap[afi][safi],
2147 PEER_CAP_RESTART_AF_RCV)) {
2148 if (peer->nsf[afi][safi] &&
2149 !CHECK_FLAG(peer->af_cap[afi][safi],
2150 PEER_CAP_RESTART_AF_PRESERVE_RCV))
2151 bgp_clear_stale_route(peer, afi, safi);
2152
2153 peer->nsf[afi][safi] = 1;
2154 nsf_af_count++;
2155 } else {
2156 if (peer->nsf[afi][safi])
2157 bgp_clear_stale_route(peer, afi, safi);
2158 peer->nsf[afi][safi] = 0;
2159 }
2160 /* Update the graceful restart information */
2161 if (peer->afc_nego[afi][safi]) {
2162 if (!BGP_SELECT_DEFER_DISABLE(peer->bgp)) {
2163 status = bgp_update_gr_info(peer, afi, safi);
2164 if (status < 0)
2165 zlog_err(
2166 "Error in updating graceful restart for %s",
2167 get_afi_safi_str(afi, safi,
2168 false));
d62a17ae 2169 } else {
df8d723c
DA
2170 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer) &&
2171 BGP_PEER_RESTARTING_MODE(peer) &&
2172 CHECK_FLAG(peer->bgp->flags,
2173 BGP_FLAG_GR_PRESERVE_FWD))
2174 peer->bgp->gr_info[afi][safi]
2175 .eor_required++;
f009ff26 2176 }
d62a17ae 2177 }
df8d723c 2178 }
d62a17ae 2179
77b34214
NT
2180 if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
2181 if ((bgp_peer_gr_mode_get(peer) == PEER_GR)
2182 || ((bgp_peer_gr_mode_get(peer) == PEER_GLOBAL_INHERIT)
2183 && (bgp_global_gr_mode_get(peer->bgp) == GLOBAL_GR))) {
2184 FOREACH_AFI_SAFI (afi, safi)
2185 /* Send route processing complete
2186 message to RIB */
2187 bgp_zebra_update(
2188 afi, safi, peer->bgp->vrf_id,
2189 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2190 }
2191 } else {
2192 /* Peer sends R-bit. In this case, we need to send
2193 * ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE to Zebra. */
eea685b6
DA
2194 if (CHECK_FLAG(peer->cap,
2195 PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV)) {
77b34214
NT
2196 FOREACH_AFI_SAFI (afi, safi)
2197 /* Send route processing complete
2198 message to RIB */
2199 bgp_zebra_update(
2200 afi, safi, peer->bgp->vrf_id,
2201 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2202 }
2203 }
2204
794b37d5 2205 peer->nsf_af_count = nsf_af_count;
2206
d62a17ae 2207 if (nsf_af_count)
2208 SET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
2209 else {
2210 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
2211 if (peer->t_gr_stale) {
fa5806c3 2212 THREAD_OFF(peer->t_gr_stale);
d62a17ae 2213 if (bgp_debug_neighbor_events(peer))
2214 zlog_debug(
f70c91dc
DA
2215 "%pBP graceful restart stalepath timer stopped",
2216 peer);
d62a17ae 2217 }
2218 }
93406d87 2219
d62a17ae 2220 if (peer->t_gr_restart) {
fa5806c3 2221 THREAD_OFF(peer->t_gr_restart);
d62a17ae 2222 if (bgp_debug_neighbor_events(peer))
f70c91dc 2223 zlog_debug("%pBP graceful restart timer stopped", peer);
d62a17ae 2224 }
718e3744 2225
9eb217ff
QY
2226 /* Reset uptime, turn on keepalives, send current table. */
2227 if (!peer->v_holdtime)
2228 bgp_keepalives_on(peer);
2229
083ec940 2230 peer->uptime = monotime(NULL);
d62a17ae 2231
0d4532cd
DA
2232 /* Send route-refresh when ORF is enabled.
2233 * Stop Long-lived Graceful Restart timers.
2234 */
05c7a1cc 2235 FOREACH_AFI_SAFI (afi, safi) {
0d4532cd 2236 if (peer->t_llgr_stale[afi][safi]) {
fa5806c3 2237 THREAD_OFF(peer->t_llgr_stale[afi][safi]);
0d4532cd
DA
2238 if (bgp_debug_neighbor_events(peer))
2239 zlog_debug(
f70c91dc
DA
2240 "%pBP Long-lived stale timer stopped for afi/safi: %d/%d",
2241 peer, afi, safi);
0d4532cd
DA
2242 }
2243
05c7a1cc
QY
2244 if (CHECK_FLAG(peer->af_cap[afi][safi],
2245 PEER_CAP_ORF_PREFIX_SM_ADV)) {
d62a17ae 2246 if (CHECK_FLAG(peer->af_cap[afi][safi],
05c7a1cc 2247 PEER_CAP_ORF_PREFIX_RM_RCV))
9af52ccf
DA
2248 bgp_route_refresh_send(
2249 peer, afi, safi, ORF_TYPE_PREFIX,
2250 REFRESH_IMMEDIATE, 0,
2251 BGP_ROUTE_REFRESH_NORMAL);
05c7a1cc
QY
2252 else if (CHECK_FLAG(peer->af_cap[afi][safi],
2253 PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
9af52ccf
DA
2254 bgp_route_refresh_send(
2255 peer, afi, safi, ORF_TYPE_PREFIX_OLD,
2256 REFRESH_IMMEDIATE, 0,
2257 BGP_ROUTE_REFRESH_NORMAL);
05c7a1cc
QY
2258 }
2259 }
d62a17ae 2260
2261 /* First update is deferred until ORF or ROUTE-REFRESH is received */
05c7a1cc
QY
2262 FOREACH_AFI_SAFI (afi, safi) {
2263 if (CHECK_FLAG(peer->af_cap[afi][safi],
2264 PEER_CAP_ORF_PREFIX_RM_ADV))
d62a17ae 2265 if (CHECK_FLAG(peer->af_cap[afi][safi],
05c7a1cc
QY
2266 PEER_CAP_ORF_PREFIX_SM_RCV)
2267 || CHECK_FLAG(peer->af_cap[afi][safi],
2268 PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
2269 SET_FLAG(peer->af_sflags[afi][safi],
2270 PEER_STATUS_ORF_WAIT_REFRESH);
2271 }
d62a17ae 2272
2273 bgp_announce_peer(peer);
2274
2275 /* Start the route advertisement timer to send updates to the peer - if
2276 * BGP
2277 * is not in read-only mode. If it is, the timer will be started at the
2278 * end
2279 * of read-only mode.
2280 */
2281 if (!bgp_update_delay_active(peer->bgp)) {
fa5806c3 2282 THREAD_OFF(peer->t_routeadv);
d62a17ae 2283 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
2284 }
718e3744 2285
d62a17ae 2286 if (peer->doppelganger && (peer->doppelganger->status != Deleted)) {
2287 if (bgp_debug_neighbor_events(peer))
2288 zlog_debug(
2289 "[Event] Deleting stub connection for peer %s",
2290 peer->host);
2291
2292 if (peer->doppelganger->status > Active)
2293 bgp_notify_send(peer->doppelganger, BGP_NOTIFY_CEASE,
2294 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
2295 else
2296 peer_delete(peer->doppelganger);
718e3744 2297 }
2298
19bd3dff
DS
2299 /*
2300 * If we are replacing the old peer for a doppelganger
2301 * then switch it around in the bgp->peerhash
2302 * the doppelgangers su and this peer's su are the same
2303 * so the hash_release is the same for either.
2304 */
2305 hash_release(peer->bgp->peerhash, peer);
8e3aae66 2306 (void)hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
19bd3dff 2307
21bfce98
RZ
2308 /* Start BFD peer if not already running. */
2309 if (peer->bfd_config)
2310 bgp_peer_bfd_update_source(peer);
2311
d62a17ae 2312 return ret;
718e3744 2313}
2314
2315/* Keepalive packet is received. */
d62a17ae 2316static int bgp_fsm_keepalive(struct peer *peer)
718e3744 2317{
fa5806c3 2318 THREAD_OFF(peer->t_holdtime);
d62a17ae 2319 return 0;
718e3744 2320}
2321
2322/* Update packet is received. */
d62a17ae 2323static int bgp_fsm_update(struct peer *peer)
718e3744 2324{
fa5806c3 2325 THREAD_OFF(peer->t_holdtime);
d62a17ae 2326 return 0;
718e3744 2327}
2328
2329/* This is empty event. */
d62a17ae 2330static int bgp_ignore(struct peer *peer)
718e3744 2331{
af4c2728 2332 flog_err(
e50f7cfd 2333 EC_BGP_FSM,
d62a17ae 2334 "%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d",
2335 peer->host, bgp_event_str[peer->cur_event],
2336 lookup_msg(bgp_status_msg, peer->status, NULL),
2337 bgp_event_str[peer->last_event],
2338 bgp_event_str[peer->last_major_event], peer->fd);
2339 return 0;
718e3744 2340}
6b0655a2 2341
6403814c 2342/* This is to handle unexpected events.. */
d62a17ae 2343static int bgp_fsm_exeption(struct peer *peer)
6403814c 2344{
af4c2728 2345 flog_err(
e50f7cfd 2346 EC_BGP_FSM,
d62a17ae 2347 "%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d",
2348 peer->host, bgp_event_str[peer->cur_event],
2349 lookup_msg(bgp_status_msg, peer->status, NULL),
2350 bgp_event_str[peer->last_event],
2351 bgp_event_str[peer->last_major_event], peer->fd);
2352 return (bgp_stop(peer));
6403814c
DS
2353}
2354
f8dcd38d 2355void bgp_fsm_nht_update(struct peer *peer, bool has_valid_nexthops)
fc9a856f 2356{
d62a17ae 2357 if (!peer)
2358 return;
2359
2360 switch (peer->status) {
2361 case Idle:
f8dcd38d 2362 if (has_valid_nexthops)
d62a17ae 2363 BGP_EVENT_ADD(peer, BGP_Start);
2364 break;
2365 case Connect:
f8dcd38d 2366 if (!has_valid_nexthops) {
fa5806c3 2367 THREAD_OFF(peer->t_connect);
d62a17ae 2368 BGP_EVENT_ADD(peer, TCP_fatal_error);
2369 }
2370 break;
2371 case Active:
f8dcd38d 2372 if (has_valid_nexthops) {
fa5806c3 2373 THREAD_OFF(peer->t_connect);
d62a17ae 2374 BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
2375 }
2376 break;
2377 case OpenSent:
2378 case OpenConfirm:
2379 case Established:
f8dcd38d 2380 if (!has_valid_nexthops
f852eb98
PG
2381 && (peer->gtsm_hops == BGP_GTSM_HOPS_CONNECTED
2382 || peer->bgp->fast_convergence))
d62a17ae 2383 BGP_EVENT_ADD(peer, TCP_fatal_error);
2384 case Clearing:
2385 case Deleted:
2386 default:
2387 break;
fc9a856f 2388 }
fc9a856f
DS
2389}
2390
718e3744 2391/* Finite State Machine structure */
fda1d3e0 2392static const struct {
d62a17ae 2393 int (*func)(struct peer *);
8398b5d5 2394 enum bgp_fsm_status next_state;
d62a17ae 2395} FSM[BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] = {
2396 {
2397 /* Idle state: In Idle state, all events other than BGP_Start is
2398 ignored. With BGP_Start event, finite state machine calls
2399 bgp_start(). */
2400 {bgp_start, Connect}, /* BGP_Start */
2401 {bgp_stop, Idle}, /* BGP_Stop */
2402 {bgp_stop, Idle}, /* TCP_connection_open */
6c537a18 2403 {bgp_stop, Idle}, /* TCP_connection_open_w_delay */
d62a17ae 2404 {bgp_stop, Idle}, /* TCP_connection_closed */
2405 {bgp_ignore, Idle}, /* TCP_connection_open_failed */
2406 {bgp_stop, Idle}, /* TCP_fatal_error */
2407 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
2408 {bgp_ignore, Idle}, /* Hold_Timer_expired */
2409 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
6c537a18 2410 {bgp_ignore, Idle}, /* DelayOpen_timer_expired */
d62a17ae 2411 {bgp_ignore, Idle}, /* Receive_OPEN_message */
2412 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
2413 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
2414 {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
2415 {bgp_ignore, Idle}, /* Clearing_Completed */
2416 },
2417 {
2418 /* Connect */
2419 {bgp_ignore, Connect}, /* BGP_Start */
2420 {bgp_stop, Idle}, /* BGP_Stop */
2421 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
6c537a18
DS
2422 {bgp_connect_success_w_delayopen,
2423 Connect}, /* TCP_connection_open_w_delay */
d62a17ae 2424 {bgp_stop, Idle}, /* TCP_connection_closed */
2425 {bgp_connect_fail, Active}, /* TCP_connection_open_failed */
2426 {bgp_connect_fail, Idle}, /* TCP_fatal_error */
2427 {bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
2428 {bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
2429 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
6c537a18
DS
2430 {bgp_fsm_delayopen_timer_expire,
2431 OpenSent}, /* DelayOpen_timer_expired */
2432 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
2433 {bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
2434 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
2435 {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
2436 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
d62a17ae 2437 },
2438 {
2439 /* Active, */
2440 {bgp_ignore, Active}, /* BGP_Start */
2441 {bgp_stop, Idle}, /* BGP_Stop */
2442 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
6c537a18
DS
2443 {bgp_connect_success_w_delayopen,
2444 Active}, /* TCP_connection_open_w_delay */
d62a17ae 2445 {bgp_stop, Idle}, /* TCP_connection_closed */
2446 {bgp_ignore, Active}, /* TCP_connection_open_failed */
2447 {bgp_fsm_exeption, Idle}, /* TCP_fatal_error */
2448 {bgp_start, Connect}, /* ConnectRetry_timer_expired */
2449 {bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
2450 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
6c537a18
DS
2451 {bgp_fsm_delayopen_timer_expire,
2452 OpenSent}, /* DelayOpen_timer_expired */
2453 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
2454 {bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
2455 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
2456 {bgp_fsm_exeption, Idle}, /* Receive_NOTIFICATION_message */
2457 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
d62a17ae 2458 },
2459 {
2460 /* OpenSent, */
2461 {bgp_ignore, OpenSent}, /* BGP_Start */
2462 {bgp_stop, Idle}, /* BGP_Stop */
2463 {bgp_stop, Active}, /* TCP_connection_open */
6c537a18 2464 {bgp_fsm_exeption, Idle}, /* TCP_connection_open_w_delay */
d62a17ae 2465 {bgp_stop, Active}, /* TCP_connection_closed */
2466 {bgp_stop, Active}, /* TCP_connection_open_failed */
2467 {bgp_stop, Active}, /* TCP_fatal_error */
2468 {bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
2469 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
2470 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
6c537a18 2471 {bgp_fsm_exeption, Idle}, /* DelayOpen_timer_expired */
d62a17ae 2472 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
2473 {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
2474 {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
53b4aaec 2475 {bgp_fsm_event_error, Idle}, /* Receive_NOTIFICATION_message */
d62a17ae 2476 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
2477 },
2478 {
2479 /* OpenConfirm, */
2480 {bgp_ignore, OpenConfirm}, /* BGP_Start */
2481 {bgp_stop, Idle}, /* BGP_Stop */
2482 {bgp_stop, Idle}, /* TCP_connection_open */
6c537a18 2483 {bgp_fsm_exeption, Idle}, /* TCP_connection_open_w_delay */
d62a17ae 2484 {bgp_stop, Idle}, /* TCP_connection_closed */
2485 {bgp_stop, Idle}, /* TCP_connection_open_failed */
2486 {bgp_stop, Idle}, /* TCP_fatal_error */
2487 {bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
2488 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
2489 {bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
6c537a18 2490 {bgp_fsm_exeption, Idle}, /* DelayOpen_timer_expired */
d62a17ae 2491 {bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
2492 {bgp_establish, Established}, /* Receive_KEEPALIVE_message */
2493 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
2494 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
2495 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
2496 },
2497 {
2498 /* Established, */
2499 {bgp_ignore, Established}, /* BGP_Start */
2500 {bgp_stop, Clearing}, /* BGP_Stop */
2501 {bgp_stop, Clearing}, /* TCP_connection_open */
6c537a18 2502 {bgp_fsm_exeption, Idle}, /* TCP_connection_open_w_delay */
d62a17ae 2503 {bgp_stop, Clearing}, /* TCP_connection_closed */
2504 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
2505 {bgp_stop, Clearing}, /* TCP_fatal_error */
2506 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
2507 {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
03014d48 2508 {bgp_ignore, Established}, /* KeepAlive_timer_expired */
6c537a18 2509 {bgp_fsm_exeption, Idle}, /* DelayOpen_timer_expired */
03014d48 2510 {bgp_stop, Clearing}, /* Receive_OPEN_message */
d62a17ae 2511 {bgp_fsm_keepalive,
2512 Established}, /* Receive_KEEPALIVE_message */
2513 {bgp_fsm_update, Established}, /* Receive_UPDATE_message */
2514 {bgp_stop_with_error,
2515 Clearing}, /* Receive_NOTIFICATION_message */
2516 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
2517 },
2518 {
2519 /* Clearing, */
2520 {bgp_ignore, Clearing}, /* BGP_Start */
2521 {bgp_stop, Clearing}, /* BGP_Stop */
2522 {bgp_stop, Clearing}, /* TCP_connection_open */
6c537a18 2523 {bgp_stop, Clearing}, /* TCP_connection_open_w_delay */
d62a17ae 2524 {bgp_stop, Clearing}, /* TCP_connection_closed */
2525 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
2526 {bgp_stop, Clearing}, /* TCP_fatal_error */
2527 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
2528 {bgp_stop, Clearing}, /* Hold_Timer_expired */
2529 {bgp_stop, Clearing}, /* KeepAlive_timer_expired */
6c537a18 2530 {bgp_stop, Clearing}, /* DelayOpen_timer_expired */
d62a17ae 2531 {bgp_stop, Clearing}, /* Receive_OPEN_message */
2532 {bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
2533 {bgp_stop, Clearing}, /* Receive_UPDATE_message */
2534 {bgp_stop, Clearing}, /* Receive_NOTIFICATION_message */
2535 {bgp_clearing_completed, Idle}, /* Clearing_Completed */
2536 },
2537 {
2538 /* Deleted, */
2539 {bgp_ignore, Deleted}, /* BGP_Start */
2540 {bgp_ignore, Deleted}, /* BGP_Stop */
2541 {bgp_ignore, Deleted}, /* TCP_connection_open */
6c537a18 2542 {bgp_ignore, Deleted}, /* TCP_connection_open_w_delay */
d62a17ae 2543 {bgp_ignore, Deleted}, /* TCP_connection_closed */
2544 {bgp_ignore, Deleted}, /* TCP_connection_open_failed */
2545 {bgp_ignore, Deleted}, /* TCP_fatal_error */
2546 {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
2547 {bgp_ignore, Deleted}, /* Hold_Timer_expired */
2548 {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
6c537a18 2549 {bgp_ignore, Deleted}, /* DelayOpen_timer_expired */
d62a17ae 2550 {bgp_ignore, Deleted}, /* Receive_OPEN_message */
2551 {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
2552 {bgp_ignore, Deleted}, /* Receive_UPDATE_message */
2553 {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */
2554 {bgp_ignore, Deleted}, /* Clearing_Completed */
2555 },
718e3744 2556};
2557
718e3744 2558/* Execute event process. */
cc9f21da 2559void bgp_event(struct thread *thread)
718e3744 2560{
d1060698 2561 enum bgp_fsm_events event;
d62a17ae 2562 struct peer *peer;
718e3744 2563
d62a17ae 2564 peer = THREAD_ARG(thread);
2565 event = THREAD_VAL(thread);
718e3744 2566
cc9f21da 2567 bgp_event_update(peer, event);
1ff9a340
DS
2568}
2569
d1060698 2570int bgp_event_update(struct peer *peer, enum bgp_fsm_events event)
1ff9a340 2571{
8398b5d5 2572 enum bgp_fsm_status next;
d62a17ae 2573 int ret = 0;
2574 struct peer *other;
2575 int passive_conn = 0;
2576 int dyn_nbr;
2577
d8151687
QY
2578 /* default return code */
2579 ret = FSM_PEER_NOOP;
2580
d62a17ae 2581 other = peer->doppelganger;
2582 passive_conn =
2583 (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) ? 1 : 0;
2584 dyn_nbr = peer_dynamic_neighbor(peer);
2585
2586 /* Logging this event. */
2587 next = FSM[peer->status - 1][event - 1].next_state;
2588
2589 if (bgp_debug_neighbor_events(peer) && peer->status != next)
2590 zlog_debug("%s [FSM] %s (%s->%s), fd %d", peer->host,
2591 bgp_event_str[event],
2592 lookup_msg(bgp_status_msg, peer->status, NULL),
2593 lookup_msg(bgp_status_msg, next, NULL), peer->fd);
2594
2595 peer->last_event = peer->cur_event;
2596 peer->cur_event = event;
2597
2598 /* Call function. */
2599 if (FSM[peer->status - 1][event - 1].func)
2600 ret = (*(FSM[peer->status - 1][event - 1].func))(peer);
2601
d62a17ae 2602 if (ret >= 0) {
2603 if (ret == 1 && next == Established) {
2604 /* The case when doppelganger swap accurred in
2605 bgp_establish.
2606 Update the peer pointer accordingly */
d8151687 2607 ret = FSM_PEER_TRANSFERRED;
d62a17ae 2608 peer = other;
2609 }
2610
2611 /* If status is changed. */
d8151687 2612 if (next != peer->status) {
d62a17ae 2613 bgp_fsm_change_status(peer, next);
2614
becedef6
QY
2615 /*
2616 * If we're going to ESTABLISHED then we executed a
2617 * peer transfer. In this case we can either return
2618 * FSM_PEER_TRANSITIONED or FSM_PEER_TRANSFERRED.
2619 * Opting for TRANSFERRED since transfer implies
2620 * session establishment.
2621 */
d8151687
QY
2622 if (ret != FSM_PEER_TRANSFERRED)
2623 ret = FSM_PEER_TRANSITIONED;
2624 }
2625
d62a17ae 2626 /* Make sure timer is set. */
2627 bgp_timer_set(peer);
2628
bea01226 2629 } else {
becedef6
QY
2630 /*
2631 * If we got a return value of -1, that means there was an
2632 * error, restart the FSM. Since bgp_stop() was called on the
2633 * peer. only a few fields are safe to access here. In any case
2634 * we need to indicate that the peer was stopped in the return
2635 * code.
2636 */
bea01226 2637 if (!dyn_nbr && !passive_conn && peer->bgp) {
af4c2728 2638 flog_err(
e50f7cfd 2639 EC_BGP_FSM,
3efd0893 2640 "%s [FSM] Failure handling event %s in state %s, prior events %s, %s, fd %d",
bea01226
QY
2641 peer->host, bgp_event_str[peer->cur_event],
2642 lookup_msg(bgp_status_msg, peer->status, NULL),
2643 bgp_event_str[peer->last_event],
2644 bgp_event_str[peer->last_major_event],
2645 peer->fd);
2646 bgp_stop(peer);
2647 bgp_fsm_change_status(peer, Idle);
2648 bgp_timer_set(peer);
2649 }
2650 ret = FSM_PEER_STOPPED;
d62a17ae 2651 }
bea01226 2652
d62a17ae 2653 return ret;
718e3744 2654}
794b37d5 2655/* BGP GR Code */
2656
2657int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp,
36235319
QY
2658 enum global_mode global_new_state,
2659 enum global_mode global_old_state)
794b37d5 2660{
2661 struct peer *peer = {0};
2662 struct listnode *node = {0};
2663 struct listnode *nnode = {0};
36235319 2664 enum peer_mode peer_old_state = PEER_INVALID;
794b37d5 2665
2666 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
2667
2668 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
2669 zlog_debug("%s [BGP_GR] Peer: (%s) :", __func__,
2670 peer->host);
794b37d5 2671
2672 peer_old_state = bgp_peer_gr_mode_get(peer);
2673
2674 if (peer_old_state == PEER_GLOBAL_INHERIT) {
2675
36235319
QY
2676 /*
2677 *Reset only these peers and send a
2678 *new open message with the change capabilities.
2679 *Considering the mode to be "global_new_state" and
2680 *do all operation accordingly
2681 */
794b37d5 2682
2683 switch (global_new_state) {
794b37d5 2684 case GLOBAL_HELPER:
794b37d5 2685 BGP_PEER_GR_HELPER_ENABLE(peer);
2686 break;
2687 case GLOBAL_GR:
794b37d5 2688 BGP_PEER_GR_ENABLE(peer);
2689 break;
2690 case GLOBAL_DISABLE:
794b37d5 2691 BGP_PEER_GR_DISABLE(peer);
2692 break;
2693 case GLOBAL_INVALID:
36235319
QY
2694 zlog_debug("%s [BGP_GR] GLOBAL_INVALID",
2695 __func__);
794b37d5 2696 return BGP_ERR_GR_OPERATION_FAILED;
794b37d5 2697 }
2698 }
2699 }
2700
2701 bgp->global_gr_present_state = global_new_state;
2702
794b37d5 2703 return BGP_GR_SUCCESS;
2704}
2705
2ba1fe69 2706int bgp_gr_update_all(struct bgp *bgp, int global_gr_cmd)
794b37d5 2707{
2708 enum global_mode global_new_state = GLOBAL_INVALID;
2709 enum global_mode global_old_state = GLOBAL_INVALID;
2710
2711 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
2712 zlog_debug("%s [BGP_GR]START: global_gr_cmd :%s:", __func__,
2713 print_global_gr_cmd(global_gr_cmd));
794b37d5 2714
2715 global_old_state = bgp_global_gr_mode_get(bgp);
2716
2ba1fe69 2717 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
2718 zlog_debug("[BGP_GR] global_old_gr_state :%s:",
2719 print_global_gr_mode(global_old_state));
794b37d5 2720
2ba1fe69 2721 if (global_old_state != GLOBAL_INVALID) {
794b37d5 2722 global_new_state =
2ba1fe69 2723 bgp->GLOBAL_GR_FSM[global_old_state][global_gr_cmd];
2724
2725 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
2726 zlog_debug("[BGP_GR] global_new_gr_state :%s:",
2727 print_global_gr_mode(global_new_state));
794b37d5 2728 } else {
36235319
QY
2729 zlog_err("%s [BGP_GR] global_old_state == GLOBAL_INVALID",
2730 __func__);
794b37d5 2731 return BGP_ERR_GR_OPERATION_FAILED;
2732 }
2733
2734 if (global_new_state == GLOBAL_INVALID) {
36235319
QY
2735 zlog_err("%s [BGP_GR] global_new_state == GLOBAL_INVALID",
2736 __func__);
794b37d5 2737 return BGP_ERR_GR_INVALID_CMD;
2738 }
2739 if (global_new_state == global_old_state) {
2740 /* Trace msg */
2ba1fe69 2741 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2742 zlog_debug(
36235319
QY
2743 "%s [BGP_GR] global_new_state == global_old_state :%s",
2744 __func__,
2745 print_global_gr_mode(global_new_state));
794b37d5 2746 return BGP_GR_NO_OPERATION;
2747 }
2748
36235319
QY
2749 return bgp_gr_lookup_n_update_all_peer(bgp, global_new_state,
2750 global_old_state);
794b37d5 2751}
2752
2ba1fe69 2753const char *print_peer_gr_mode(enum peer_mode pr_mode)
2754{
2755 const char *peer_gr_mode = NULL;
2756
2757 switch (pr_mode) {
2758 case PEER_HELPER:
2759 peer_gr_mode = "PEER_HELPER";
2760 break;
2761 case PEER_GR:
2762 peer_gr_mode = "PEER_GR";
2763 break;
2764 case PEER_DISABLE:
2765 peer_gr_mode = "PEER_DISABLE";
2766 break;
2767 case PEER_INVALID:
2768 peer_gr_mode = "PEER_INVALID";
2769 break;
2770 case PEER_GLOBAL_INHERIT:
2771 peer_gr_mode = "PEER_GLOBAL_INHERIT";
2772 break;
2773 }
2774
2775 return peer_gr_mode;
2776}
2777
2778const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd)
2779{
2780 const char *peer_gr_cmd = NULL;
2781
2782 switch (pr_gr_cmd) {
2783 case PEER_GR_CMD:
2784 peer_gr_cmd = "PEER_GR_CMD";
2785 break;
2786 case NO_PEER_GR_CMD:
2787 peer_gr_cmd = "NO_PEER_GR_CMD";
2788 break;
2789 case PEER_DISABLE_CMD:
b6e410f7 2790 peer_gr_cmd = "PEER_DISABLE_GR_CMD";
2ba1fe69 2791 break;
2792 case NO_PEER_DISABLE_CMD:
b6e410f7 2793 peer_gr_cmd = "NO_PEER_DISABLE_GR_CMD";
2ba1fe69 2794 break;
2795 case PEER_HELPER_CMD:
2796 peer_gr_cmd = "PEER_HELPER_CMD";
2797 break;
2798 case NO_PEER_HELPER_CMD:
2799 peer_gr_cmd = "NO_PEER_HELPER_CMD";
2800 break;
2801 }
2802
2803 return peer_gr_cmd;
2804}
2805
2806const char *print_global_gr_mode(enum global_mode gl_mode)
2807{
2808 const char *global_gr_mode = NULL;
2809
2810 switch (gl_mode) {
2811 case GLOBAL_HELPER:
2812 global_gr_mode = "GLOBAL_HELPER";
2813 break;
2814 case GLOBAL_GR:
2815 global_gr_mode = "GLOBAL_GR";
2816 break;
2817 case GLOBAL_DISABLE:
2818 global_gr_mode = "GLOBAL_DISABLE";
2819 break;
2820 case GLOBAL_INVALID:
2821 global_gr_mode = "GLOBAL_INVALID";
2822 break;
2823 }
2824
2825 return global_gr_mode;
2826}
2827
2828const char *print_global_gr_cmd(enum global_gr_command gl_gr_cmd)
2829{
2830 const char *global_gr_cmd = NULL;
2831
2832 switch (gl_gr_cmd) {
2833 case GLOBAL_GR_CMD:
2834 global_gr_cmd = "GLOBAL_GR_CMD";
2835 break;
2836 case NO_GLOBAL_GR_CMD:
2837 global_gr_cmd = "NO_GLOBAL_GR_CMD";
2838 break;
2839 case GLOBAL_DISABLE_CMD:
2840 global_gr_cmd = "GLOBAL_DISABLE_CMD";
2841 break;
2842 case NO_GLOBAL_DISABLE_CMD:
2843 global_gr_cmd = "NO_GLOBAL_DISABLE_CMD";
2844 break;
2845 }
2846
2847 return global_gr_cmd;
2848}
2849
794b37d5 2850enum global_mode bgp_global_gr_mode_get(struct bgp *bgp)
2851{
2852 return bgp->global_gr_present_state;
2853}
2854
2855enum peer_mode bgp_peer_gr_mode_get(struct peer *peer)
2856{
2857 return peer->peer_gr_present_state;
2858}
2859
36235319 2860int bgp_neighbor_graceful_restart(struct peer *peer, int peer_gr_cmd)
794b37d5 2861{
36235319
QY
2862 enum peer_mode peer_new_state = PEER_INVALID;
2863 enum peer_mode peer_old_state = PEER_INVALID;
794b37d5 2864 struct bgp_peer_gr peer_state;
2865 int result = BGP_GR_FAILURE;
2866
2867 /*
2868 * fetch peer_old_state from peer structure also
2869 * fetch global_old_state from bgp structure,
2870 * peer had a back pointer to bgpo struct ;
2871 */
2872
2873 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
2874 zlog_debug("%s [BGP_GR] START:Peer: (%s) : peer_gr_cmd :%s:",
2875 __func__, peer->host,
2876 print_peer_gr_cmd(peer_gr_cmd));
794b37d5 2877
2878 peer_old_state = bgp_peer_gr_mode_get(peer);
2879
2880 if (peer_old_state == PEER_INVALID) {
36235319 2881 zlog_debug("[BGP_GR] peer_old_state == Invalid state !");
794b37d5 2882 return BGP_ERR_GR_OPERATION_FAILED;
2883 }
2884
2ba1fe69 2885 peer_state = peer->PEER_GR_FSM[peer_old_state][peer_gr_cmd];
794b37d5 2886 peer_new_state = peer_state.next_state;
2887
2888 if (peer_new_state == PEER_INVALID) {
794b37d5 2889 zlog_debug(
2ba1fe69 2890 "[BGP_GR] Invalid bgp graceful restart command used !");
794b37d5 2891 return BGP_ERR_GR_INVALID_CMD;
2892 }
2893
2894 if (peer_new_state != peer_old_state) {
36235319
QY
2895 result = peer_state.action_fun(peer, peer_old_state,
2896 peer_new_state);
794b37d5 2897 } else {
2ba1fe69 2898 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2899 zlog_debug(
36235319 2900 "[BGP_GR] peer_old_state == peer_new_state !");
794b37d5 2901 return BGP_GR_NO_OPERATION;
2902 }
2903
2904 if (result == BGP_GR_SUCCESS) {
2905
2906 /* Update the mode i.e peer_new_state into the peer structure */
2907 peer->peer_gr_present_state = peer_new_state;
794b37d5 2908 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319 2909 zlog_debug(
2089dd80 2910 "[BGP_GR] Successfully change the state of the peer to : %s : !",
36235319 2911 print_peer_gr_mode(peer_new_state));
794b37d5 2912
2913 return BGP_GR_SUCCESS;
2914 }
2915
2916 return result;
2917}
2918
36235319
QY
2919unsigned int bgp_peer_gr_action(struct peer *peer, int old_peer_state,
2920 int new_peer_state)
794b37d5 2921{
2922 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2923 zlog_debug(
2ba1fe69 2924 "%s [BGP_GR] Move peer from old_peer_state :%s: to new_peer_state :%s: !!!!",
2925 __func__, print_peer_gr_mode(old_peer_state),
2926 print_peer_gr_mode(new_peer_state));
794b37d5 2927
2928 int bgp_gr_global_mode = GLOBAL_INVALID;
2929 unsigned int ret = BGP_GR_FAILURE;
2930
2931 if (old_peer_state == new_peer_state) {
36235319
QY
2932 /* Nothing to do over here as the present and old state is the
2933 * same */
794b37d5 2934 return BGP_GR_NO_OPERATION;
2935 }
36235319
QY
2936 if ((old_peer_state == PEER_INVALID)
2937 || (new_peer_state == PEER_INVALID)) {
2938 /* something bad happend , print error message */
794b37d5 2939 return BGP_ERR_GR_INVALID_CMD;
2940 }
2941
2942 bgp_gr_global_mode = bgp_global_gr_mode_get(peer->bgp);
2943
36235319
QY
2944 if ((old_peer_state == PEER_GLOBAL_INHERIT)
2945 && (new_peer_state != PEER_GLOBAL_INHERIT)) {
794b37d5 2946
2947 /* fetch the Mode running in the Global state machine
2948 *from the bgp structure into a variable called
2949 *bgp_gr_global_mode
2950 */
2951
2952 /* Here we are checking if the
2953 *1. peer_new_state == global_mode == helper_mode
2954 *2. peer_new_state == global_mode == GR_mode
2955 *3. peer_new_state == global_mode == disabled_mode
2956 */
2957
2958 BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer);
2959
2960 if (new_peer_state == bgp_gr_global_mode) {
36235319
QY
2961 /*This is incremental updates i.e no tear down
2962 *of the existing session
2963 *as the peer is already working in the same mode.
2964 */
794b37d5 2965 ret = BGP_GR_SUCCESS;
2966 } else {
2967 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2968 zlog_debug(
2ba1fe69 2969 "[BGP_GR] Peer state changed from :%s ",
2970 print_peer_gr_mode(old_peer_state));
794b37d5 2971
2972 bgp_peer_move_to_gr_mode(peer, new_peer_state);
2973
2974 ret = BGP_GR_SUCCESS;
2975 }
2976 }
2977 /* In the case below peer is going into Global inherit mode i.e.
2978 * the peer would work as the mode configured at the global level
2979 */
36235319
QY
2980 else if ((new_peer_state == PEER_GLOBAL_INHERIT)
2981 && (old_peer_state != PEER_GLOBAL_INHERIT)) {
794b37d5 2982 /* Here in this case it would be destructive
2983 * in all the cases except one case when,
2984 * Global GR is configured Disabled
2985 * and present_peer_state is not disable
2986 */
2987
2988 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
2989
2990 if (old_peer_state == bgp_gr_global_mode) {
2991
2992 /* This is incremental updates
2993 *i.e no tear down of the existing session
2994 *as the peer is already working in the same mode.
2995 */
2996 ret = BGP_GR_SUCCESS;
2997 } else {
2998 /* Destructive always */
2999 /* Tear down the old session
3000 * and send the new capability
3001 * as per the bgp_gr_global_mode
3002 */
3003
3004 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319
QY
3005 zlog_debug(
3006 "[BGP_GR] Peer state changed from :%s",
2ba1fe69 3007 print_peer_gr_mode(old_peer_state));
794b37d5 3008
3009 bgp_peer_move_to_gr_mode(peer, bgp_gr_global_mode);
3010
3011 ret = BGP_GR_SUCCESS;
3012 }
3013 } else {
3014 /*
3015 *This else case, it include all the cases except -->
3016 *(new_peer_state != Peer_Global) &&
3017 *( old_peer_state != Peer_Global )
3018 */
3019 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2ba1fe69 3020 zlog_debug("[BGP_GR] Peer state changed from :%s",
36235319 3021 print_peer_gr_mode(old_peer_state));
794b37d5 3022
3023 bgp_peer_move_to_gr_mode(peer, new_peer_state);
3024
3025 ret = BGP_GR_SUCCESS;
3026 }
3027
3028 return ret;
3029}
3030
3031inline void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state)
3032
3033{
3034 int bgp_global_gr_mode = bgp_global_gr_mode_get(peer->bgp);
3035
3036 switch (new_state) {
794b37d5 3037 case PEER_HELPER:
3038 BGP_PEER_GR_HELPER_ENABLE(peer);
3039 break;
794b37d5 3040 case PEER_GR:
3041 BGP_PEER_GR_ENABLE(peer);
3042 break;
794b37d5 3043 case PEER_DISABLE:
3044 BGP_PEER_GR_DISABLE(peer);
3045 break;
794b37d5 3046 case PEER_GLOBAL_INHERIT:
3047 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
3048
3049 if (bgp_global_gr_mode == GLOBAL_HELPER) {
3050 BGP_PEER_GR_HELPER_ENABLE(peer);
36235319 3051 } else if (bgp_global_gr_mode == GLOBAL_GR) {
794b37d5 3052 BGP_PEER_GR_ENABLE(peer);
3053 } else if (bgp_global_gr_mode == GLOBAL_DISABLE) {
3054 BGP_PEER_GR_DISABLE(peer);
3055 } else {
2ba1fe69 3056 zlog_err(
36235319 3057 "[BGP_GR] Default switch inherit mode ::: SOMETHING IS WRONG !!!");
794b37d5 3058 }
3059 break;
3060 default:
36235319
QY
3061 zlog_err(
3062 "[BGP_GR] Default switch mode ::: SOMETHING IS WRONG !!!");
794b37d5 3063 break;
3064 }
3065 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2ba1fe69 3066 zlog_debug("[BGP_GR] Peer state changed --to--> : %d : !",
36235319 3067 new_state);
794b37d5 3068}
3069
3070void bgp_peer_gr_flags_update(struct peer *peer)
3071{
3072 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
36235319 3073 zlog_debug("%s [BGP_GR] called !", __func__);
794b37d5 3074 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
36235319
QY
3075 PEER_GRACEFUL_RESTART_NEW_STATE_HELPER))
3076 SET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER);
794b37d5 3077 else
36235319 3078 UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER);
794b37d5 3079 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3080 zlog_debug(
2ba1fe69 3081 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !",
794b37d5 3082 peer->host,
2986cac2 3083 (CHECK_FLAG(peer->flags,
36235319
QY
3084 PEER_FLAG_GRACEFUL_RESTART_HELPER)
3085 ? "Set"
3086 : "UnSet"));
794b37d5 3087 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
36235319
QY
3088 PEER_GRACEFUL_RESTART_NEW_STATE_RESTART))
3089 SET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART);
794b37d5 3090 else
36235319 3091 UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART);
794b37d5 3092 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3093 zlog_debug(
2ba1fe69 3094 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !",
794b37d5 3095 peer->host,
36235319
QY
3096 (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
3097 ? "Set"
3098 : "UnSet"));
794b37d5 3099 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
36235319 3100 PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT))
2986cac2 3101 SET_FLAG(peer->flags,
36235319 3102 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
794b37d5 3103 else
2986cac2 3104 UNSET_FLAG(peer->flags,
36235319 3105 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
794b37d5 3106 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
3107 zlog_debug(
36235319 3108 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !",
794b37d5 3109 peer->host,
2986cac2 3110 (CHECK_FLAG(peer->flags,
36235319
QY
3111 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT)
3112 ? "Set"
3113 : "UnSet"));
d7b3cda6 3114
36235319
QY
3115 if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
3116 && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)) {
3117 zlog_debug("[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_MODE!",
3118 peer->host);
d7b3cda6 3119
3120 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
3121
36235319 3122 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
d7b3cda6 3123
3124 peer_nsf_stop(peer);
3125 zlog_debug(
2ba1fe69 3126 "[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_WAIT!",
d7b3cda6 3127 peer->host);
3128 }
3129 }
794b37d5 3130}