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