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