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