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