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