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