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