]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_fsm.c
*: make frr_yang_module_info const
[mirror_frr.git] / bgpd / bgp_fsm.c
CommitLineData
d62a17ae 1/* BGP-4 Finite State Machine
896014f4
DL
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 */
718e3744 21
22#include <zebra.h>
23
24#include "linklist.h"
25#include "prefix.h"
718e3744 26#include "sockunion.h"
27#include "thread.h"
28#include "log.h"
29#include "stream.h"
74ffbfe6 30#include "ringbuf.h"
718e3744 31#include "memory.h"
32#include "plist.h"
f188f2c4 33#include "workqueue.h"
3f9c7369 34#include "queue.h"
039f3a34 35#include "filter.h"
4dcadbef 36#include "command.h"
02705213 37#include "lib_errors.h"
718e3744 38
856ca177 39#include "lib/json.h"
718e3744 40#include "bgpd/bgpd.h"
41#include "bgpd/bgp_attr.h"
42#include "bgpd/bgp_debug.h"
14454c9f 43#include "bgpd/bgp_errors.h"
718e3744 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"
f188f2c4 50#include "bgpd/bgp_advertise.h"
3f9c7369 51#include "bgpd/bgp_updgrp.h"
ffd0c037 52#include "bgpd/bgp_nht.h"
c43ed2e4 53#include "bgpd/bgp_bfd.h"
4a1ab8e4 54#include "bgpd/bgp_memory.h"
03014d48 55#include "bgpd/bgp_keepalives.h"
56257a44 56#include "bgpd/bgp_io.h"
c42eab4b 57#include "bgpd/bgp_zebra.h"
6b0655a2 58
d62a17ae 59DEFINE_HOOK(peer_backward_transition, (struct peer * peer), (peer))
7d8d0eab 60DEFINE_HOOK(peer_status_changed, (struct peer * peer), (peer))
3012671f 61
6403814c
DS
62/* Definition of display strings corresponding to FSM events. This should be
63 * kept consistent with the events defined in bgpd.h
64 */
d62a17ae 65static const char *bgp_event_str[] = {
66 NULL,
67 "BGP_Start",
68 "BGP_Stop",
69 "TCP_connection_open",
70 "TCP_connection_closed",
71 "TCP_connection_open_failed",
72 "TCP_fatal_error",
73 "ConnectRetry_timer_expired",
74 "Hold_Timer_expired",
75 "KeepAlive_timer_expired",
76 "Receive_OPEN_message",
77 "Receive_KEEPALIVE_message",
78 "Receive_UPDATE_message",
79 "Receive_NOTIFICATION_message",
80 "Clearing_Completed",
6403814c
DS
81};
82
718e3744 83/* BGP FSM (finite state machine) has three types of functions. Type
84 one is thread functions. Type two is event functions. Type three
85 is FSM functions. Timer functions are set by bgp_timer_set
86 function. */
87
88/* BGP event function. */
d62a17ae 89int bgp_event(struct thread *);
718e3744 90
91/* BGP thread functions. */
d62a17ae 92static int bgp_start_timer(struct thread *);
93static int bgp_connect_timer(struct thread *);
94static int bgp_holdtime_timer(struct thread *);
718e3744 95
96/* BGP FSM functions. */
d62a17ae 97static int bgp_start(struct peer *);
718e3744 98
e2d3a909 99/* Register peer with NHT */
100static int bgp_peer_reg_with_nht(struct peer *peer)
101{
102 int connected = 0;
103
c8d6f0d6 104 if (peer->sort == BGP_PEER_EBGP && peer->ttl == BGP_DEFAULT_TTL
e2d3a909 105 && !CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
106 && !bgp_flag_check(peer->bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
107 connected = 1;
108
109 return bgp_find_or_add_nexthop(
110 peer->bgp, peer->bgp, family2afi(peer->su.sa.sa_family),
111 NULL, peer, connected);
112}
113
d62a17ae 114static void peer_xfer_stats(struct peer *peer_dst, struct peer *peer_src)
1ff9a340 115{
d62a17ae 116 /* Copy stats over. These are only the pre-established state stats */
117 peer_dst->open_in += peer_src->open_in;
118 peer_dst->open_out += peer_src->open_out;
119 peer_dst->keepalive_in += peer_src->keepalive_in;
120 peer_dst->keepalive_out += peer_src->keepalive_out;
121 peer_dst->notify_in += peer_src->notify_in;
122 peer_dst->notify_out += peer_src->notify_out;
123 peer_dst->dynamic_cap_in += peer_src->dynamic_cap_in;
124 peer_dst->dynamic_cap_out += peer_src->dynamic_cap_out;
1ff9a340
DS
125}
126
d62a17ae 127static struct peer *peer_xfer_conn(struct peer *from_peer)
1ff9a340 128{
d62a17ae 129 struct peer *peer;
130 afi_t afi;
131 safi_t safi;
132 int fd;
133 int status, pstatus;
134 unsigned char last_evt, last_maj_evt;
135
136 assert(from_peer != NULL);
137
138 peer = from_peer->doppelganger;
139
140 if (!peer || !CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
141 return from_peer;
142
9bf904cc
DS
143 /*
144 * Let's check that we are not going to loose known configuration
145 * state based upon doppelganger rules.
146 */
147 FOREACH_AFI_SAFI (afi, safi) {
148 if (from_peer->afc[afi][safi] != peer->afc[afi][safi]) {
149 flog_err(
150 EC_BGP_DOPPELGANGER_CONFIG,
151 "from_peer->afc[%d][%d] is not the same as what we are overwriting",
152 afi, safi);
153 return NULL;
154 }
155 }
156
d62a17ae 157 if (bgp_debug_neighbor_events(peer))
158 zlog_debug("%s: peer transfer %p fd %d -> %p fd %d)",
159 from_peer->host, from_peer, from_peer->fd, peer,
160 peer->fd);
161
424ab01d
QY
162 bgp_writes_off(peer);
163 bgp_reads_off(peer);
164 bgp_writes_off(from_peer);
165 bgp_reads_off(from_peer);
d62a17ae 166
167 BGP_TIMER_OFF(peer->t_routeadv);
424ab01d 168 BGP_TIMER_OFF(peer->t_connect);
387f984e
QY
169 BGP_TIMER_OFF(peer->t_connect_check_r);
170 BGP_TIMER_OFF(peer->t_connect_check_w);
d62a17ae 171 BGP_TIMER_OFF(from_peer->t_routeadv);
424ab01d 172 BGP_TIMER_OFF(from_peer->t_connect);
387f984e
QY
173 BGP_TIMER_OFF(from_peer->t_connect_check_r);
174 BGP_TIMER_OFF(from_peer->t_connect_check_w);
7a86aa5a 175 BGP_TIMER_OFF(from_peer->t_process_packet);
d3ecc69e 176
becedef6
QY
177 /*
178 * At this point in time, it is possible that there are packets pending
179 * on various buffers. Those need to be transferred or dropped,
180 * otherwise we'll get spurious failures during session establishment.
181 */
00dffa8c 182 frr_with_mutex(&peer->io_mtx, &from_peer->io_mtx) {
424ab01d
QY
183 fd = peer->fd;
184 peer->fd = from_peer->fd;
185 from_peer->fd = fd;
186
187 stream_fifo_clean(peer->ibuf);
d3ecc69e 188 stream_fifo_clean(peer->obuf);
d3ecc69e 189
becedef6
QY
190 /*
191 * this should never happen, since bgp_process_packet() is the
192 * only task that sets and unsets the current packet and it
193 * runs in our pthread.
194 */
424ab01d 195 if (peer->curr) {
af4c2728 196 flog_err(
e50f7cfd 197 EC_BGP_PKT_PROCESS,
424ab01d
QY
198 "[%s] Dropping pending packet on connection transfer:",
199 peer->host);
584470fb
DL
200 /* there used to be a bgp_packet_dump call here, but
201 * that's extremely confusing since there's no way to
202 * identify the packet in MRT dumps or BMP as dropped
203 * due to connection transfer.
204 */
424ab01d
QY
205 stream_free(peer->curr);
206 peer->curr = NULL;
207 }
208
209 // copy each packet from old peer's output queue to new peer
727c4f87
QY
210 while (from_peer->obuf->head)
211 stream_fifo_push(peer->obuf,
212 stream_fifo_pop(from_peer->obuf));
424ab01d
QY
213
214 // copy each packet from old peer's input queue to new peer
215 while (from_peer->ibuf->head)
216 stream_fifo_push(peer->ibuf,
217 stream_fifo_pop(from_peer->ibuf));
7db44ec8 218
74ffbfe6
QY
219 ringbuf_wipe(peer->ibuf_work);
220 ringbuf_copy(peer->ibuf_work, from_peer->ibuf_work,
221 ringbuf_remain(from_peer->ibuf_work));
d3ecc69e 222 }
d62a17ae 223
224 peer->as = from_peer->as;
225 peer->v_holdtime = from_peer->v_holdtime;
226 peer->v_keepalive = from_peer->v_keepalive;
d62a17ae 227 peer->v_routeadv = from_peer->v_routeadv;
228 peer->v_gr_restart = from_peer->v_gr_restart;
229 peer->cap = from_peer->cap;
230 status = peer->status;
231 pstatus = peer->ostatus;
232 last_evt = peer->last_event;
233 last_maj_evt = peer->last_major_event;
234 peer->status = from_peer->status;
235 peer->ostatus = from_peer->ostatus;
236 peer->last_event = from_peer->last_event;
237 peer->last_major_event = from_peer->last_major_event;
238 from_peer->status = status;
239 from_peer->ostatus = pstatus;
240 from_peer->last_event = last_evt;
241 from_peer->last_major_event = last_maj_evt;
242 peer->remote_id = from_peer->remote_id;
3577f1c5 243 peer->last_reset = from_peer->last_reset;
d62a17ae 244
245 if (from_peer->hostname != NULL) {
246 if (peer->hostname) {
247 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
248 peer->hostname = NULL;
249 }
250
251 peer->hostname = from_peer->hostname;
252 from_peer->hostname = NULL;
253 }
254
255 if (from_peer->domainname != NULL) {
256 if (peer->domainname) {
257 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
258 peer->domainname = NULL;
259 }
260
261 peer->domainname = from_peer->domainname;
262 from_peer->domainname = NULL;
263 }
264
05c7a1cc
QY
265 FOREACH_AFI_SAFI (afi, safi) {
266 peer->af_flags[afi][safi] = from_peer->af_flags[afi][safi];
267 peer->af_sflags[afi][safi] = from_peer->af_sflags[afi][safi];
268 peer->af_cap[afi][safi] = from_peer->af_cap[afi][safi];
269 peer->afc_nego[afi][safi] = from_peer->afc_nego[afi][safi];
270 peer->afc_adv[afi][safi] = from_peer->afc_adv[afi][safi];
271 peer->afc_recv[afi][safi] = from_peer->afc_recv[afi][safi];
272 peer->orf_plist[afi][safi] = from_peer->orf_plist[afi][safi];
273 }
d62a17ae 274
275 if (bgp_getsockname(peer) < 0) {
af4c2728 276 flog_err(
450971aa 277 EC_LIB_SOCKET,
d62a17ae 278 "%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
279 (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)
280 ? "accept"
281 : ""),
282 peer->host, peer->fd, from_peer->fd);
283 bgp_stop(peer);
284 bgp_stop(from_peer);
285 return NULL;
286 }
287 if (from_peer->status > Active) {
288 if (bgp_getsockname(from_peer) < 0) {
af4c2728 289 flog_err(
450971aa 290 EC_LIB_SOCKET,
d62a17ae 291 "%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
14454c9f 292
d62a17ae 293 (CHECK_FLAG(from_peer->sflags,
294 PEER_STATUS_ACCEPT_PEER)
295 ? "accept"
296 : ""),
297 from_peer->host, from_peer->fd, peer->fd);
298 bgp_stop(from_peer);
299 from_peer = NULL;
300 }
301 }
302
0112e9e0
QY
303
304 // Note: peer_xfer_stats() must be called with I/O turned OFF
305 if (from_peer)
306 peer_xfer_stats(peer, from_peer);
307
e2d3a909 308 /* Register peer for NHT. This is to allow RAs to be enabled when
309 * needed, even on a passive connection.
310 */
311 bgp_peer_reg_with_nht(peer);
312
424ab01d
QY
313 bgp_reads_on(peer);
314 bgp_writes_on(peer);
7a86aa5a
QY
315 thread_add_timer_msec(bm->master, bgp_process_packet, peer, 0,
316 &peer->t_process_packet);
d62a17ae 317
d62a17ae 318 return (peer);
1ff9a340
DS
319}
320
718e3744 321/* Hook function called after bgp event is occered. And vty's
322 neighbor command invoke this function after making neighbor
323 structure. */
d62a17ae 324void bgp_timer_set(struct peer *peer)
718e3744 325{
d62a17ae 326 switch (peer->status) {
327 case Idle:
328 /* First entry point of peer's finite state machine. In Idle
329 status start timer is on unless peer is shutdown or peer is
330 inactive. All other timer must be turned off */
f62abc7d 331 if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(peer)
dded74d5
DS
332 || (peer->bgp->inst_type != BGP_INSTANCE_TYPE_VIEW &&
333 peer->bgp->vrf_id == VRF_UNKNOWN)) {
d62a17ae 334 BGP_TIMER_OFF(peer->t_start);
335 } else {
336 BGP_TIMER_ON(peer->t_start, bgp_start_timer,
337 peer->v_start);
338 }
339 BGP_TIMER_OFF(peer->t_connect);
340 BGP_TIMER_OFF(peer->t_holdtime);
b72b6f4f 341 bgp_keepalives_off(peer);
d62a17ae 342 BGP_TIMER_OFF(peer->t_routeadv);
343 break;
344
345 case Connect:
346 /* After start timer is expired, the peer moves to Connect
347 status. Make sure start timer is off and connect timer is
348 on. */
349 BGP_TIMER_OFF(peer->t_start);
350 BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
351 peer->v_connect);
352 BGP_TIMER_OFF(peer->t_holdtime);
b72b6f4f 353 bgp_keepalives_off(peer);
d62a17ae 354 BGP_TIMER_OFF(peer->t_routeadv);
355 break;
356
357 case Active:
358 /* Active is waiting connection from remote peer. And if
359 connect timer is expired, change status to Connect. */
360 BGP_TIMER_OFF(peer->t_start);
361 /* If peer is passive mode, do not set connect timer. */
362 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)
363 || CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
364 BGP_TIMER_OFF(peer->t_connect);
365 } else {
366 BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
367 peer->v_connect);
368 }
369 BGP_TIMER_OFF(peer->t_holdtime);
b72b6f4f 370 bgp_keepalives_off(peer);
d62a17ae 371 BGP_TIMER_OFF(peer->t_routeadv);
372 break;
373
374 case OpenSent:
375 /* OpenSent status. */
376 BGP_TIMER_OFF(peer->t_start);
377 BGP_TIMER_OFF(peer->t_connect);
378 if (peer->v_holdtime != 0) {
379 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
380 peer->v_holdtime);
381 } else {
382 BGP_TIMER_OFF(peer->t_holdtime);
383 }
b72b6f4f 384 bgp_keepalives_off(peer);
d62a17ae 385 BGP_TIMER_OFF(peer->t_routeadv);
386 break;
387
388 case OpenConfirm:
389 /* OpenConfirm status. */
390 BGP_TIMER_OFF(peer->t_start);
391 BGP_TIMER_OFF(peer->t_connect);
392
393 /* If the negotiated Hold Time value is zero, then the Hold Time
394 timer and KeepAlive timers are not started. */
395 if (peer->v_holdtime == 0) {
396 BGP_TIMER_OFF(peer->t_holdtime);
b72b6f4f 397 bgp_keepalives_off(peer);
d62a17ae 398 } else {
399 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
400 peer->v_holdtime);
b72b6f4f 401 bgp_keepalives_on(peer);
d62a17ae 402 }
403 BGP_TIMER_OFF(peer->t_routeadv);
404 break;
405
406 case Established:
407 /* In Established status start and connect timer is turned
408 off. */
409 BGP_TIMER_OFF(peer->t_start);
410 BGP_TIMER_OFF(peer->t_connect);
411
412 /* Same as OpenConfirm, if holdtime is zero then both holdtime
413 and keepalive must be turned off. */
414 if (peer->v_holdtime == 0) {
415 BGP_TIMER_OFF(peer->t_holdtime);
bea01226 416 bgp_keepalives_off(peer);
d62a17ae 417 } else {
418 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
419 peer->v_holdtime);
bea01226 420 bgp_keepalives_on(peer);
d62a17ae 421 }
422 break;
423 case Deleted:
424 BGP_TIMER_OFF(peer->t_gr_restart);
425 BGP_TIMER_OFF(peer->t_gr_stale);
426 BGP_TIMER_OFF(peer->t_pmax_restart);
427 /* fallthru */
428 case Clearing:
429 BGP_TIMER_OFF(peer->t_start);
430 BGP_TIMER_OFF(peer->t_connect);
431 BGP_TIMER_OFF(peer->t_holdtime);
b72b6f4f 432 bgp_keepalives_off(peer);
d62a17ae 433 BGP_TIMER_OFF(peer->t_routeadv);
434 break;
718e3744 435 }
718e3744 436}
437
438/* BGP start timer. This function set BGP_Start event to thread value
439 and process event. */
d62a17ae 440static int bgp_start_timer(struct thread *thread)
718e3744 441{
d62a17ae 442 struct peer *peer;
718e3744 443
d62a17ae 444 peer = THREAD_ARG(thread);
445 peer->t_start = NULL;
718e3744 446
d62a17ae 447 if (bgp_debug_neighbor_events(peer))
448 zlog_debug("%s [FSM] Timer (start timer expire).", peer->host);
718e3744 449
d62a17ae 450 THREAD_VAL(thread) = BGP_Start;
451 bgp_event(thread); /* bgp_event unlocks peer */
718e3744 452
d62a17ae 453 return 0;
718e3744 454}
455
456/* BGP connect retry timer. */
d62a17ae 457static int bgp_connect_timer(struct thread *thread)
718e3744 458{
d62a17ae 459 struct peer *peer;
460 int ret;
461
462 peer = THREAD_ARG(thread);
424ab01d
QY
463
464 assert(!peer->t_write);
465 assert(!peer->t_read);
466
d62a17ae 467 peer->t_connect = NULL;
468
469 if (bgp_debug_neighbor_events(peer))
470 zlog_debug("%s [FSM] Timer (connect timer expire)", peer->host);
471
472 if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) {
473 bgp_stop(peer);
474 ret = -1;
475 } else {
476 THREAD_VAL(thread) = ConnectRetry_timer_expired;
477 bgp_event(thread); /* bgp_event unlocks peer */
478 ret = 0;
479 }
480
481 return ret;
718e3744 482}
483
484/* BGP holdtime timer. */
d62a17ae 485static int bgp_holdtime_timer(struct thread *thread)
718e3744 486{
d62a17ae 487 struct peer *peer;
718e3744 488
d62a17ae 489 peer = THREAD_ARG(thread);
490 peer->t_holdtime = NULL;
718e3744 491
d62a17ae 492 if (bgp_debug_neighbor_events(peer))
493 zlog_debug("%s [FSM] Timer (holdtime timer expire)",
494 peer->host);
718e3744 495
d62a17ae 496 THREAD_VAL(thread) = Hold_Timer_expired;
497 bgp_event(thread); /* bgp_event unlocks peer */
718e3744 498
d62a17ae 499 return 0;
718e3744 500}
501
d62a17ae 502int bgp_routeadv_timer(struct thread *thread)
718e3744 503{
d62a17ae 504 struct peer *peer;
718e3744 505
d62a17ae 506 peer = THREAD_ARG(thread);
507 peer->t_routeadv = NULL;
718e3744 508
d62a17ae 509 if (bgp_debug_neighbor_events(peer))
510 zlog_debug("%s [FSM] Timer (routeadv timer expire)",
511 peer->host);
718e3744 512
d62a17ae 513 peer->synctime = bgp_clock();
718e3744 514
a9794991 515 thread_add_timer_msec(bm->master, bgp_generate_updgrp_packets, peer, 0,
424ab01d
QY
516 &peer->t_generate_updgrp_packets);
517
d62a17ae 518 /* MRAI timer will be started again when FIFO is built, no need to
519 * do it here.
520 */
521 return 0;
718e3744 522}
523
e0701b79 524/* BGP Peer Down Cause */
d62a17ae 525const char *peer_down_str[] = {"",
526 "Router ID changed",
527 "Remote AS changed",
528 "Local AS change",
529 "Cluster ID changed",
530 "Confederation identifier changed",
531 "Confederation peer changed",
532 "RR client config change",
533 "RS client config change",
534 "Update source change",
535 "Address family activated",
536 "Admin. shutdown",
537 "User reset",
538 "BGP Notification received",
539 "BGP Notification send",
540 "Peer closed the session",
541 "Neighbor deleted",
542 "Peer-group add member",
543 "Peer-group delete member",
544 "Capability changed",
545 "Passive config change",
546 "Multihop config change",
547 "NSF peer closed the session",
548 "Intf peering v6only config change",
549 "BFD down received",
550 "Interface down",
05912a17 551 "Neighbor address lost",
3577f1c5 552 "Waiting for NHT",
05912a17
DD
553 "Waiting for Peer IPv6 LLA",
554 "Waiting for VRF to be initialized",
555 "No AFI/SAFI activated for peer"};
d62a17ae 556
557static int bgp_graceful_restart_timer_expire(struct thread *thread)
e0701b79 558{
d62a17ae 559 struct peer *peer;
560 afi_t afi;
561 safi_t safi;
562
563 peer = THREAD_ARG(thread);
564 peer->t_gr_restart = NULL;
565
566 /* NSF delete stale route */
567 for (afi = AFI_IP; afi < AFI_MAX; afi++)
a08ca0a7 568 for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++)
d62a17ae 569 if (peer->nsf[afi][safi])
570 bgp_clear_stale_route(peer, afi, safi);
571
572 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
573 BGP_TIMER_OFF(peer->t_gr_stale);
574
575 if (bgp_debug_neighbor_events(peer)) {
576 zlog_debug("%s graceful restart timer expired", peer->host);
577 zlog_debug("%s graceful restart stalepath timer stopped",
578 peer->host);
579 }
93406d87 580
d62a17ae 581 bgp_timer_set(peer);
93406d87 582
d62a17ae 583 return 0;
93406d87 584}
585
d62a17ae 586static int bgp_graceful_stale_timer_expire(struct thread *thread)
93406d87 587{
d62a17ae 588 struct peer *peer;
589 afi_t afi;
590 safi_t safi;
93406d87 591
d62a17ae 592 peer = THREAD_ARG(thread);
593 peer->t_gr_stale = NULL;
93406d87 594
d62a17ae 595 if (bgp_debug_neighbor_events(peer))
596 zlog_debug("%s graceful restart stalepath timer expired",
597 peer->host);
93406d87 598
d62a17ae 599 /* NSF delete stale route */
600 for (afi = AFI_IP; afi < AFI_MAX; afi++)
a08ca0a7 601 for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++)
d62a17ae 602 if (peer->nsf[afi][safi])
603 bgp_clear_stale_route(peer, afi, safi);
93406d87 604
d62a17ae 605 return 0;
93406d87 606}
607
d62a17ae 608static int bgp_update_delay_applicable(struct bgp *bgp)
f188f2c4 609{
d62a17ae 610 /* update_delay_over flag should be reset (set to 0) for any new
611 applicability of the update-delay during BGP process lifetime.
612 And it should be set after an occurence of the update-delay is
613 over)*/
614 if (!bgp->update_delay_over)
615 return 1;
616
617 return 0;
f188f2c4
DS
618}
619
d62a17ae 620int bgp_update_delay_active(struct bgp *bgp)
f188f2c4 621{
d62a17ae 622 if (bgp->t_update_delay)
623 return 1;
f188f2c4 624
d62a17ae 625 return 0;
f188f2c4
DS
626}
627
d62a17ae 628int bgp_update_delay_configured(struct bgp *bgp)
f188f2c4 629{
d62a17ae 630 if (bgp->v_update_delay)
631 return 1;
f188f2c4 632
d62a17ae 633 return 0;
f188f2c4
DS
634}
635
636/* Do the post-processing needed when bgp comes out of the read-only mode
637 on ending the update delay. */
d62a17ae 638void bgp_update_delay_end(struct bgp *bgp)
f188f2c4 639{
d62a17ae 640 THREAD_TIMER_OFF(bgp->t_update_delay);
641 THREAD_TIMER_OFF(bgp->t_establish_wait);
642
643 /* Reset update-delay related state */
644 bgp->update_delay_over = 1;
645 bgp->established = 0;
646 bgp->restarted_peers = 0;
647 bgp->implicit_eors = 0;
648 bgp->explicit_eors = 0;
649
650 quagga_timestamp(3, bgp->update_delay_end_time,
651 sizeof(bgp->update_delay_end_time));
652
653 /*
654 * Add an end-of-initial-update marker to the main process queues so
655 * that
656 * the route advertisement timer for the peers can be started. Also set
657 * the zebra and peer update hold flags. These flags are used to achieve
658 * three stages in the update-delay post processing:
659 * 1. Finish best-path selection for all the prefixes held on the
660 * queues.
661 * (routes in BGP are updated, and peers sync queues are populated
662 * too)
663 * 2. As the eoiu mark is reached in the bgp process routine, ship all
664 * the
665 * routes to zebra. With that zebra should see updates from BGP
666 * close
667 * to each other.
668 * 3. Unblock the peer update writes. With that peer update packing
669 * with
670 * the prefixes should be at its maximum.
671 */
672 bgp_add_eoiu_mark(bgp);
673 bgp->main_zebra_update_hold = 1;
674 bgp->main_peers_update_hold = 1;
675
676 /* Resume the queue processing. This should trigger the event that would
677 take
678 care of processing any work that was queued during the read-only
679 mode. */
680 work_queue_unplug(bm->process_main_queue);
f188f2c4
DS
681}
682
cb1faec9
DS
683/**
684 * see bgp_fsm.h
685 */
d62a17ae 686void bgp_start_routeadv(struct bgp *bgp)
cb1faec9 687{
d62a17ae 688 struct listnode *node, *nnode;
689 struct peer *peer;
cb1faec9 690
d62a17ae 691 zlog_info("bgp_start_routeadv(), update hold status %d",
692 bgp->main_peers_update_hold);
4a16ae86 693
d62a17ae 694 if (bgp->main_peers_update_hold)
695 return;
4a16ae86 696
d62a17ae 697 quagga_timestamp(3, bgp->update_delay_peers_resume_time,
698 sizeof(bgp->update_delay_peers_resume_time));
4a16ae86 699
d62a17ae 700 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
701 if (peer->status != Established)
702 continue;
703 BGP_TIMER_OFF(peer->t_routeadv);
704 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
705 }
cb1faec9
DS
706}
707
708/**
709 * see bgp_fsm.h
710 */
d62a17ae 711void bgp_adjust_routeadv(struct peer *peer)
cb1faec9 712{
d62a17ae 713 time_t nowtime = bgp_clock();
714 double diff;
715 unsigned long remain;
716
717 /* Bypass checks for special case of MRAI being 0 */
718 if (peer->v_routeadv == 0) {
719 /* Stop existing timer, just in case it is running for a
720 * different
721 * duration and schedule write thread immediately.
722 */
723 if (peer->t_routeadv)
724 BGP_TIMER_OFF(peer->t_routeadv);
725
726 peer->synctime = bgp_clock();
a9794991 727 thread_add_timer_msec(bm->master, bgp_generate_updgrp_packets,
424ab01d
QY
728 peer, 0,
729 &peer->t_generate_updgrp_packets);
d62a17ae 730 return;
731 }
732
733
734 /*
735 * CASE I:
736 * If the last update was written more than MRAI back, expire the timer
737 * instantly so that we can send the update out sooner.
738 *
739 * <------- MRAI --------->
740 * |-----------------|-----------------------|
741 * <------------- m ------------>
742 * ^ ^ ^
743 * | | |
744 * | | current time
745 * | timer start
746 * last write
747 *
748 * m > MRAI
749 */
750 diff = difftime(nowtime, peer->last_update);
751 if (diff > (double)peer->v_routeadv) {
752 BGP_TIMER_OFF(peer->t_routeadv);
753 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
754 return;
755 }
756
757 /*
758 * CASE II:
759 * - Find when to expire the MRAI timer.
760 * If MRAI timer is not active, assume we can start it now.
761 *
762 * <------- MRAI --------->
763 * |------------|-----------------------|
764 * <-------- m ----------><----- r ----->
765 * ^ ^ ^
766 * | | |
767 * | | current time
768 * | timer start
769 * last write
770 *
771 * (MRAI - m) < r
772 */
773 if (peer->t_routeadv)
774 remain = thread_timer_remain_second(peer->t_routeadv);
775 else
776 remain = peer->v_routeadv;
777 diff = peer->v_routeadv - diff;
778 if (diff <= (double)remain) {
779 BGP_TIMER_OFF(peer->t_routeadv);
780 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, diff);
781 }
cb1faec9
DS
782}
783
d62a17ae 784static int bgp_maxmed_onstartup_applicable(struct bgp *bgp)
abc920f8 785{
d62a17ae 786 if (!bgp->maxmed_onstartup_over)
787 return 1;
abc920f8 788
d62a17ae 789 return 0;
abc920f8
DS
790}
791
d62a17ae 792int bgp_maxmed_onstartup_configured(struct bgp *bgp)
abc920f8 793{
d62a17ae 794 if (bgp->v_maxmed_onstartup != BGP_MAXMED_ONSTARTUP_UNCONFIGURED)
795 return 1;
abc920f8 796
d62a17ae 797 return 0;
abc920f8
DS
798}
799
d62a17ae 800int bgp_maxmed_onstartup_active(struct bgp *bgp)
abc920f8 801{
d62a17ae 802 if (bgp->t_maxmed_onstartup)
803 return 1;
abc920f8 804
d62a17ae 805 return 0;
abc920f8
DS
806}
807
d62a17ae 808void bgp_maxmed_update(struct bgp *bgp)
abc920f8 809{
d7c0a89a
QY
810 uint8_t maxmed_active;
811 uint32_t maxmed_value;
d62a17ae 812
813 if (bgp->v_maxmed_admin) {
814 maxmed_active = 1;
815 maxmed_value = bgp->maxmed_admin_value;
816 } else if (bgp->t_maxmed_onstartup) {
817 maxmed_active = 1;
818 maxmed_value = bgp->maxmed_onstartup_value;
819 } else {
820 maxmed_active = 0;
821 maxmed_value = BGP_MAXMED_VALUE_DEFAULT;
822 }
823
824 if (bgp->maxmed_active != maxmed_active
825 || bgp->maxmed_value != maxmed_value) {
826 bgp->maxmed_active = maxmed_active;
827 bgp->maxmed_value = maxmed_value;
828
829 update_group_announce(bgp);
830 }
abc920f8
DS
831}
832
833/* The maxmed onstartup timer expiry callback. */
d62a17ae 834static int bgp_maxmed_onstartup_timer(struct thread *thread)
abc920f8 835{
d62a17ae 836 struct bgp *bgp;
abc920f8 837
d62a17ae 838 zlog_info("Max med on startup ended - timer expired.");
abc920f8 839
d62a17ae 840 bgp = THREAD_ARG(thread);
841 THREAD_TIMER_OFF(bgp->t_maxmed_onstartup);
842 bgp->maxmed_onstartup_over = 1;
abc920f8 843
d62a17ae 844 bgp_maxmed_update(bgp);
abc920f8 845
d62a17ae 846 return 0;
abc920f8
DS
847}
848
d62a17ae 849static void bgp_maxmed_onstartup_begin(struct bgp *bgp)
abc920f8 850{
d62a17ae 851 /* Applicable only once in the process lifetime on the startup */
852 if (bgp->maxmed_onstartup_over)
853 return;
abc920f8 854
d62a17ae 855 zlog_info("Begin maxmed onstartup mode - timer %d seconds",
856 bgp->v_maxmed_onstartup);
abc920f8 857
d62a17ae 858 thread_add_timer(bm->master, bgp_maxmed_onstartup_timer, bgp,
859 bgp->v_maxmed_onstartup, &bgp->t_maxmed_onstartup);
abc920f8 860
d62a17ae 861 if (!bgp->v_maxmed_admin) {
862 bgp->maxmed_active = 1;
863 bgp->maxmed_value = bgp->maxmed_onstartup_value;
864 }
abc920f8 865
d62a17ae 866 /* Route announce to all peers should happen after this in
867 * bgp_establish() */
abc920f8
DS
868}
869
d62a17ae 870static void bgp_maxmed_onstartup_process_status_change(struct peer *peer)
abc920f8 871{
d62a17ae 872 if (peer->status == Established && !peer->bgp->established) {
873 bgp_maxmed_onstartup_begin(peer->bgp);
874 }
abc920f8
DS
875}
876
f188f2c4 877/* The update delay timer expiry callback. */
d62a17ae 878static int bgp_update_delay_timer(struct thread *thread)
f188f2c4 879{
d62a17ae 880 struct bgp *bgp;
f188f2c4 881
d62a17ae 882 zlog_info("Update delay ended - timer expired.");
f188f2c4 883
d62a17ae 884 bgp = THREAD_ARG(thread);
885 THREAD_TIMER_OFF(bgp->t_update_delay);
886 bgp_update_delay_end(bgp);
f188f2c4 887
d62a17ae 888 return 0;
f188f2c4
DS
889}
890
891/* The establish wait timer expiry callback. */
d62a17ae 892static int bgp_establish_wait_timer(struct thread *thread)
f188f2c4 893{
d62a17ae 894 struct bgp *bgp;
f188f2c4 895
d62a17ae 896 zlog_info("Establish wait - timer expired.");
f188f2c4 897
d62a17ae 898 bgp = THREAD_ARG(thread);
899 THREAD_TIMER_OFF(bgp->t_establish_wait);
900 bgp_check_update_delay(bgp);
f188f2c4 901
d62a17ae 902 return 0;
f188f2c4
DS
903}
904
905/* Steps to begin the update delay:
906 - initialize queues if needed
907 - stop the queue processing
908 - start the timer */
d62a17ae 909static void bgp_update_delay_begin(struct bgp *bgp)
f188f2c4 910{
d62a17ae 911 struct listnode *node, *nnode;
912 struct peer *peer;
f188f2c4 913
d62a17ae 914 /* Stop the processing of queued work. Enqueue shall continue */
915 work_queue_plug(bm->process_main_queue);
f188f2c4 916
d62a17ae 917 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
918 peer->update_delay_over = 0;
f188f2c4 919
d62a17ae 920 /* Start the update-delay timer */
921 thread_add_timer(bm->master, bgp_update_delay_timer, bgp,
922 bgp->v_update_delay, &bgp->t_update_delay);
f188f2c4 923
d62a17ae 924 if (bgp->v_establish_wait != bgp->v_update_delay)
925 thread_add_timer(bm->master, bgp_establish_wait_timer, bgp,
926 bgp->v_establish_wait, &bgp->t_establish_wait);
f188f2c4 927
d62a17ae 928 quagga_timestamp(3, bgp->update_delay_begin_time,
929 sizeof(bgp->update_delay_begin_time));
f188f2c4
DS
930}
931
d62a17ae 932static void bgp_update_delay_process_status_change(struct peer *peer)
f188f2c4 933{
d62a17ae 934 if (peer->status == Established) {
935 if (!peer->bgp->established++) {
936 bgp_update_delay_begin(peer->bgp);
937 zlog_info(
938 "Begin read-only mode - update-delay timer %d seconds",
939 peer->bgp->v_update_delay);
940 }
941 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_BIT_RCV))
942 bgp_update_restarted_peers(peer);
943 }
944 if (peer->ostatus == Established
945 && bgp_update_delay_active(peer->bgp)) {
946 /* Adjust the update-delay state to account for this flap.
947 NOTE: Intentionally skipping adjusting implicit_eors or
948 explicit_eors
949 counters. Extra sanity check in bgp_check_update_delay()
950 should
951 be enough to take care of any additive discrepancy in bgp eor
952 counters */
953 peer->bgp->established--;
954 peer->update_delay_over = 0;
955 }
f188f2c4
DS
956}
957
0437e105 958/* Called after event occurred, this function change status and reset
200df115 959 read/write and timer thread. */
d62a17ae 960void bgp_fsm_change_status(struct peer *peer, int status)
200df115 961{
36dc7588 962 struct bgp *bgp;
963 uint32_t peer_count;
1ff9a340 964
36dc7588 965 bgp = peer->bgp;
966 peer_count = bgp->established_peers;
967
968 if (status == Established)
969 bgp->established_peers++;
970 else if ((peer->status == Established) && (status != Established))
971 bgp->established_peers--;
972
1cfe005d
DS
973 if (bgp_debug_neighbor_events(peer)) {
974 struct vrf *vrf = vrf_lookup_by_id(bgp->vrf_id);
975
976 zlog_debug("%s : vrf %s(%u), Status: %s established_peers %u", __func__,
977 vrf ? vrf->name : "Unknown", bgp->vrf_id,
978 lookup_msg(bgp_status_msg, status, NULL),
979 bgp->established_peers);
980 }
981
36dc7588 982 /* Set to router ID to the value provided by RIB if there are no peers
983 * in the established state and peer count did not change
984 */
985 if ((peer_count != bgp->established_peers) &&
986 (bgp->established_peers == 0))
987 bgp_router_id_zebra_bump(bgp->vrf_id, NULL);
988
d62a17ae 989 /* Transition into Clearing or Deleted must /always/ clear all routes..
990 * (and must do so before actually changing into Deleted..
991 */
992 if (status >= Clearing) {
993 bgp_clear_route_all(peer);
994
995 /* If no route was queued for the clear-node processing,
996 * generate the
997 * completion event here. This is needed because if there are no
998 * routes
999 * to trigger the background clear-node thread, the event won't
1000 * get
1001 * generated and the peer would be stuck in Clearing. Note that
1002 * this
1003 * event is for the peer and helps the peer transition out of
1004 * Clearing
1005 * state; it should not be generated per (AFI,SAFI). The event
1006 * is
1007 * directly posted here without calling clear_node_complete() as
1008 * we
1009 * shouldn't do an extra unlock. This event will get processed
1010 * after
1011 * the state change that happens below, so peer will be in
1012 * Clearing
1013 * (or Deleted).
1014 */
1015 if (!work_queue_is_scheduled(peer->clear_node_queue))
1016 BGP_EVENT_ADD(peer, Clearing_Completed);
1017 }
1018
1019 /* Preserve old status and change into new status. */
1020 peer->ostatus = peer->status;
1021 peer->status = status;
1022
1023 /* Save event that caused status change. */
1024 peer->last_major_event = peer->cur_event;
1025
7d8d0eab
MKS
1026 /* Operations after status change */
1027 hook_call(peer_status_changed, peer);
1028
d62a17ae 1029 if (status == Established)
1030 UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
1031
1032 /* If max-med processing is applicable, do the necessary. */
1033 if (status == Established) {
1034 if (bgp_maxmed_onstartup_configured(peer->bgp)
1035 && bgp_maxmed_onstartup_applicable(peer->bgp))
1036 bgp_maxmed_onstartup_process_status_change(peer);
1037 else
1038 peer->bgp->maxmed_onstartup_over = 1;
1039 }
1040
1041 /* If update-delay processing is applicable, do the necessary. */
1042 if (bgp_update_delay_configured(peer->bgp)
1043 && bgp_update_delay_applicable(peer->bgp))
1044 bgp_update_delay_process_status_change(peer);
1045
1046 if (bgp_debug_neighbor_events(peer))
1047 zlog_debug("%s went from %s to %s", peer->host,
1048 lookup_msg(bgp_status_msg, peer->ostatus, NULL),
1049 lookup_msg(bgp_status_msg, peer->status, NULL));
200df115 1050}
1051
3117b5c4 1052/* Flush the event queue and ensure the peer is shut down */
d62a17ae 1053static int bgp_clearing_completed(struct peer *peer)
3117b5c4 1054{
d62a17ae 1055 int rc = bgp_stop(peer);
1ff9a340 1056
d62a17ae 1057 if (rc >= 0)
1058 BGP_EVENT_FLUSH(peer);
3117b5c4 1059
d62a17ae 1060 return rc;
3117b5c4
SH
1061}
1062
718e3744 1063/* Administrative BGP peer stop event. */
3117b5c4 1064/* May be called multiple times for the same peer */
d62a17ae 1065int bgp_stop(struct peer *peer)
718e3744 1066{
d62a17ae 1067 afi_t afi;
1068 safi_t safi;
1069 char orf_name[BUFSIZ];
1070 int ret = 0;
1071
1072 if (peer_dynamic_neighbor(peer)
1073 && !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
1074 if (bgp_debug_neighbor_events(peer))
1075 zlog_debug("%s (dynamic neighbor) deleted", peer->host);
1076 peer_delete(peer);
1077 return -1;
c22767d8 1078 }
848973c7 1079
d62a17ae 1080 /* Can't do this in Clearing; events are used for state transitions */
1081 if (peer->status != Clearing) {
1082 /* Delete all existing events of the peer */
1083 BGP_EVENT_FLUSH(peer);
93406d87 1084 }
d62a17ae 1085
1086 /* Increment Dropped count. */
1087 if (peer->status == Established) {
1088 peer->dropped++;
1089
1090 /* bgp log-neighbor-changes of neighbor Down */
1091 if (bgp_flag_check(peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
1092 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
1093 zlog_info(
1094 "%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
1095 peer->host,
1096 (peer->hostname) ? peer->hostname : "Unknown",
5742e42b
DS
1097 vrf ? ((vrf->vrf_id != VRF_DEFAULT)
1098 ? vrf->name
1099 : VRF_DEFAULT_NAME)
d62a17ae 1100 : "",
1101 peer_down_str[(int)peer->last_reset]);
1102 }
1103
1104 /* graceful restart */
1105 if (peer->t_gr_stale) {
1106 BGP_TIMER_OFF(peer->t_gr_stale);
1107 if (bgp_debug_neighbor_events(peer))
1108 zlog_debug(
1109 "%s graceful restart stalepath timer stopped",
1110 peer->host);
1111 }
1112 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
1113 if (bgp_debug_neighbor_events(peer)) {
1114 zlog_debug(
1115 "%s graceful restart timer started for %d sec",
1116 peer->host, peer->v_gr_restart);
1117 zlog_debug(
1118 "%s graceful restart stalepath timer started for %d sec",
1119 peer->host, peer->bgp->stalepath_time);
1120 }
1121 BGP_TIMER_ON(peer->t_gr_restart,
1122 bgp_graceful_restart_timer_expire,
1123 peer->v_gr_restart);
1124 BGP_TIMER_ON(peer->t_gr_stale,
1125 bgp_graceful_stale_timer_expire,
1126 peer->bgp->stalepath_time);
1127 } else {
1128 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
1129
1130 for (afi = AFI_IP; afi < AFI_MAX; afi++)
996c9314
LB
1131 for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN;
1132 safi++)
d62a17ae 1133 peer->nsf[afi][safi] = 0;
1134 }
1135
1136 /* set last reset time */
1137 peer->resettime = peer->uptime = bgp_clock();
1138
1139 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1140 zlog_debug("%s remove from all update group",
1141 peer->host);
1142 update_group_remove_peer_afs(peer);
1143
1144 hook_call(peer_backward_transition, peer);
1145
1146 /* Reset peer synctime */
1147 peer->synctime = 0;
93406d87 1148 }
93406d87 1149
424ab01d 1150 /* stop keepalives */
b72b6f4f 1151 bgp_keepalives_off(peer);
424ab01d
QY
1152
1153 /* Stop read and write threads. */
1154 bgp_writes_off(peer);
1155 bgp_reads_off(peer);
1156
387f984e
QY
1157 THREAD_OFF(peer->t_connect_check_r);
1158 THREAD_OFF(peer->t_connect_check_w);
d62a17ae 1159
1160 /* Stop all timers. */
1161 BGP_TIMER_OFF(peer->t_start);
1162 BGP_TIMER_OFF(peer->t_connect);
1163 BGP_TIMER_OFF(peer->t_holdtime);
d62a17ae 1164 BGP_TIMER_OFF(peer->t_routeadv);
d62a17ae 1165
1166 /* Clear input and output buffer. */
00dffa8c 1167 frr_with_mutex(&peer->io_mtx) {
424ab01d
QY
1168 if (peer->ibuf)
1169 stream_fifo_clean(peer->ibuf);
d3ecc69e
QY
1170 if (peer->obuf)
1171 stream_fifo_clean(peer->obuf);
424ab01d
QY
1172
1173 if (peer->ibuf_work)
74ffbfe6 1174 ringbuf_wipe(peer->ibuf_work);
424ab01d
QY
1175 if (peer->obuf_work)
1176 stream_reset(peer->obuf_work);
1177
1178 if (peer->curr) {
1179 stream_free(peer->curr);
1180 peer->curr = NULL;
1181 }
d3ecc69e 1182 }
d62a17ae 1183
1184 /* Close of file descriptor. */
1185 if (peer->fd >= 0) {
1186 close(peer->fd);
1187 peer->fd = -1;
93406d87 1188 }
1189
05c7a1cc
QY
1190 FOREACH_AFI_SAFI (afi, safi) {
1191 /* Reset all negotiated variables */
1192 peer->afc_nego[afi][safi] = 0;
1193 peer->afc_adv[afi][safi] = 0;
1194 peer->afc_recv[afi][safi] = 0;
1195
1196 /* peer address family capability flags*/
1197 peer->af_cap[afi][safi] = 0;
1198
1199 /* peer address family status flags*/
1200 peer->af_sflags[afi][safi] = 0;
1201
1202 /* Received ORF prefix-filter */
1203 peer->orf_plist[afi][safi] = NULL;
1204
1205 if ((peer->status == OpenConfirm)
1206 || (peer->status == Established)) {
1207 /* ORF received prefix-filter pnt */
1208 sprintf(orf_name, "%s.%d.%d", peer->host, afi, safi);
1209 prefix_bgp_orf_remove_all(afi, orf_name);
d62a17ae 1210 }
05c7a1cc 1211 }
d62a17ae 1212
1213 /* Reset keepalive and holdtime */
b90a8e13 1214 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) {
d62a17ae 1215 peer->v_keepalive = peer->keepalive;
1216 peer->v_holdtime = peer->holdtime;
1217 } else {
1218 peer->v_keepalive = peer->bgp->default_keepalive;
1219 peer->v_holdtime = peer->bgp->default_holdtime;
1ff9a340 1220 }
d62a17ae 1221
1222 peer->update_time = 0;
1223
1224/* Until we are sure that there is no problem about prefix count
1225 this should be commented out.*/
718e3744 1226#if 0
1227 /* Reset prefix count */
1228 peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
1229 peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
cd1964ff 1230 peer->pcount[AFI_IP][SAFI_LABELED_UNICAST] = 0;
718e3744 1231 peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
1232 peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
1233 peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
cd1964ff 1234 peer->pcount[AFI_IP6][SAFI_LABELED_UNICAST] = 0;
718e3744 1235#endif /* 0 */
1236
d62a17ae 1237 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)
1238 && !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
1239 peer_delete(peer);
1240 ret = -1;
1241 } else {
1242 bgp_peer_conf_if_to_su_update(peer);
1243 }
1244
1245 return ret;
718e3744 1246}
1247
1248/* BGP peer is stoped by the error. */
d62a17ae 1249static int bgp_stop_with_error(struct peer *peer)
718e3744 1250{
d62a17ae 1251 /* Double start timer. */
1252 peer->v_start *= 2;
1253
1254 /* Overflow check. */
1255 if (peer->v_start >= (60 * 2))
1256 peer->v_start = (60 * 2);
1257
1258 if (peer_dynamic_neighbor(peer)) {
1259 if (bgp_debug_neighbor_events(peer))
1260 zlog_debug("%s (dynamic neighbor) deleted", peer->host);
1261 peer_delete(peer);
1262 return -1;
1263 }
1264
1265 return (bgp_stop(peer));
718e3744 1266}
1267
397b5bde
LR
1268
1269/* something went wrong, send notify and tear down */
d7c0a89a
QY
1270static int bgp_stop_with_notify(struct peer *peer, uint8_t code,
1271 uint8_t sub_code)
397b5bde 1272{
d62a17ae 1273 /* Send notify to remote peer */
1274 bgp_notify_send(peer, code, sub_code);
1275
1276 if (peer_dynamic_neighbor(peer)) {
1277 if (bgp_debug_neighbor_events(peer))
1278 zlog_debug("%s (dynamic neighbor) deleted", peer->host);
1279 peer_delete(peer);
1280 return -1;
1281 }
f14e6fdb 1282
d62a17ae 1283 /* Clear start timer value to default. */
1284 peer->v_start = BGP_INIT_START_TIMER;
397b5bde 1285
d62a17ae 1286 return (bgp_stop(peer));
397b5bde
LR
1287}
1288
07a16526
QY
1289/**
1290 * Determines whether a TCP session has successfully established for a peer and
1291 * events as appropriate.
1292 *
1293 * This function is called when setting up a new session. After connect() is
387f984e
QY
1294 * called on the peer's socket (in bgp_start()), the fd is passed to poll()
1295 * to wait for connection success or failure. When poll() returns, this
07a16526 1296 * function is called to evaluate the result.
387f984e
QY
1297 *
1298 * Due to differences in behavior of poll() on Linux and BSD - specifically,
1299 * the value of .revents in the case of a closed connection - this function is
1300 * scheduled both for a read and a write event. The write event is triggered
1301 * when the connection is established. A read event is triggered when the
1302 * connection is closed. Thus we need to cancel whichever one did not occur.
07a16526
QY
1303 */
1304static int bgp_connect_check(struct thread *thread)
1305{
1306 int status;
1307 socklen_t slen;
1308 int ret;
1309 struct peer *peer;
1310
1311 peer = THREAD_ARG(thread);
424ab01d
QY
1312 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
1313 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
1314 assert(!peer->t_read);
1315 assert(!peer->t_write);
07a16526 1316
387f984e
QY
1317 THREAD_OFF(peer->t_connect_check_r);
1318 THREAD_OFF(peer->t_connect_check_w);
dc1188bb 1319
07a16526
QY
1320 /* Check file descriptor. */
1321 slen = sizeof(status);
1322 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *)&status,
1323 &slen);
1324
1325 /* If getsockopt is fail, this is fatal error. */
1326 if (ret < 0) {
4cb5e18b 1327 zlog_err("can't get sockopt for nonblocking connect: %d(%s)",
54ff5e9b 1328 errno, safe_strerror(errno));
07a16526
QY
1329 BGP_EVENT_ADD(peer, TCP_fatal_error);
1330 return -1;
1331 }
1332
1333 /* When status is 0 then TCP connection is established. */
1334 if (status == 0) {
1335 BGP_EVENT_ADD(peer, TCP_connection_open);
1336 return 1;
1337 } else {
1338 if (bgp_debug_neighbor_events(peer))
54ff5e9b
DS
1339 zlog_debug("%s [Event] Connect failed %d(%s)",
1340 peer->host, status, safe_strerror(status));
07a16526
QY
1341 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1342 return 0;
1343 }
1344}
397b5bde 1345
718e3744 1346/* TCP connection open. Next we send open message to remote peer. And
1347 add read thread for reading open message. */
d62a17ae 1348static int bgp_connect_success(struct peer *peer)
718e3744 1349{
d62a17ae 1350 if (peer->fd < 0) {
e50f7cfd 1351 flog_err(EC_BGP_CONNECT,
1c50c1c0
QY
1352 "bgp_connect_success peer's fd is negative value %d",
1353 peer->fd);
d62a17ae 1354 bgp_stop(peer);
1355 return -1;
1356 }
1357
1358 if (bgp_getsockname(peer) < 0) {
450971aa 1359 flog_err_sys(EC_LIB_SOCKET,
09c866e3
QY
1360 "%s: bgp_getsockname(): failed for peer %s, fd %d",
1361 __FUNCTION__, peer->host, peer->fd);
0e35025e
DA
1362 bgp_notify_send(
1363 peer, BGP_NOTIFY_FSM_ERR,
1364 BGP_NOTIFY_SUBCODE_UNSPECIFIC); /* internal error */
424ab01d 1365 bgp_writes_on(peer);
d62a17ae 1366 return -1;
1367 }
1368
424ab01d 1369 bgp_reads_on(peer);
d62a17ae 1370
1371 if (bgp_debug_neighbor_events(peer)) {
1372 char buf1[SU_ADDRSTRLEN];
1373
1374 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
1375 zlog_debug("%s open active, local address %s",
1376 peer->host,
1377 sockunion2str(peer->su_local, buf1,
1378 SU_ADDRSTRLEN));
1379 else
1380 zlog_debug("%s passive open", peer->host);
1381 }
1382
1383 bgp_open_send(peer);
1384
1385 return 0;
718e3744 1386}
1387
1388/* TCP connect fail */
d62a17ae 1389static int bgp_connect_fail(struct peer *peer)
718e3744 1390{
d62a17ae 1391 if (peer_dynamic_neighbor(peer)) {
1392 if (bgp_debug_neighbor_events(peer))
1393 zlog_debug("%s (dynamic neighbor) deleted", peer->host);
1394 peer_delete(peer);
1395 return -1;
1396 }
1397
1398 return (bgp_stop(peer));
718e3744 1399}
1400
1401/* This function is the first starting point of all BGP connection. It
1402 try to connect to remote peer with non-blocking IO. */
d62a17ae 1403int bgp_start(struct peer *peer)
718e3744 1404{
d62a17ae 1405 int status;
d62a17ae 1406
1407 bgp_peer_conf_if_to_su_update(peer);
1408
1409 if (peer->su.sa.sa_family == AF_UNSPEC) {
1410 if (bgp_debug_neighbor_events(peer))
1411 zlog_debug(
1412 "%s [FSM] Unable to get neighbor's IP address, waiting...",
1413 peer->host);
3577f1c5 1414 peer->last_reset = PEER_DOWN_NBR_ADDR;
d62a17ae 1415 return -1;
1416 }
1417
1418 if (BGP_PEER_START_SUPPRESSED(peer)) {
1419 if (bgp_debug_neighbor_events(peer))
e50f7cfd 1420 flog_err(EC_BGP_FSM,
1c50c1c0
QY
1421 "%s [FSM] Trying to start suppressed peer"
1422 " - this is never supposed to happen!",
1423 peer->host);
d62a17ae 1424 return -1;
1425 }
1426
1427 /* Scrub some information that might be left over from a previous,
1428 * session
1429 */
1430 /* Connection information. */
1431 if (peer->su_local) {
1432 sockunion_free(peer->su_local);
1433 peer->su_local = NULL;
1434 }
1435
1436 if (peer->su_remote) {
1437 sockunion_free(peer->su_remote);
1438 peer->su_remote = NULL;
1439 }
1440
1441 /* Clear remote router-id. */
1442 peer->remote_id.s_addr = 0;
1443
1444 /* Clear peer capability flag. */
1445 peer->cap = 0;
1446
1447 /* If the peer is passive mode, force to move to Active mode. */
1448 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)) {
1449 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1450 return 0;
1451 }
1452
dded74d5
DS
1453 if (peer->bgp->inst_type != BGP_INSTANCE_TYPE_VIEW &&
1454 peer->bgp->vrf_id == VRF_UNKNOWN) {
61cf4b37 1455 if (bgp_debug_neighbor_events(peer))
af4c2728 1456 flog_err(
e50f7cfd 1457 EC_BGP_FSM,
996c9314
LB
1458 "%s [FSM] In a VRF that is not initialised yet",
1459 peer->host);
3577f1c5 1460 peer->last_reset = PEER_DOWN_VRF_UNINIT;
61cf4b37
PG
1461 return -1;
1462 }
1463
e2d3a909 1464 /* Register peer for NHT. If next hop is already resolved, proceed
1465 * with connection setup, else wait.
1466 */
1467 if (!bgp_peer_reg_with_nht(peer)) {
c42eab4b
DS
1468 if (bgp_zebra_num_connects()) {
1469 if (bgp_debug_neighbor_events(peer))
1470 zlog_debug("%s [FSM] Waiting for NHT",
1471 peer->host);
3577f1c5 1472 peer->last_reset = PEER_DOWN_WAITING_NHT;
c42eab4b
DS
1473 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1474 return 0;
1475 }
718e3744 1476 }
d62a17ae 1477
424ab01d
QY
1478 assert(!peer->t_write);
1479 assert(!peer->t_read);
1480 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
1481 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
d62a17ae 1482 status = bgp_connect(peer);
1483
1484 switch (status) {
1485 case connect_error:
1486 if (bgp_debug_neighbor_events(peer))
1487 zlog_debug("%s [FSM] Connect error", peer->host);
1488 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1489 break;
1490 case connect_success:
1491 if (bgp_debug_neighbor_events(peer))
1492 zlog_debug(
1493 "%s [FSM] Connect immediately success, fd %d",
1494 peer->host, peer->fd);
1495 BGP_EVENT_ADD(peer, TCP_connection_open);
1496 break;
1497 case connect_in_progress:
1498 /* To check nonblocking connect, we wait until socket is
1499 readable or writable. */
1500 if (bgp_debug_neighbor_events(peer))
1501 zlog_debug(
1502 "%s [FSM] Non blocking connect waiting result, fd %d",
1503 peer->host, peer->fd);
1504 if (peer->fd < 0) {
e50f7cfd 1505 flog_err(EC_BGP_FSM,
1c50c1c0
QY
1506 "bgp_start peer's fd is negative value %d",
1507 peer->fd);
d62a17ae 1508 return -1;
1509 }
becedef6 1510 /*
387f984e
QY
1511 * - when the socket becomes ready, poll() will signify POLLOUT
1512 * - if it fails to connect, poll() will signify POLLHUP
1513 * - POLLHUP is handled as a 'read' event by thread.c
1514 *
1515 * therefore, we schedule both a read and a write event with
1516 * bgp_connect_check() as the handler for each and cancel the
1517 * unused event in that function.
becedef6 1518 */
424ab01d 1519 thread_add_read(bm->master, bgp_connect_check, peer, peer->fd,
387f984e
QY
1520 &peer->t_connect_check_r);
1521 thread_add_write(bm->master, bgp_connect_check, peer, peer->fd,
1522 &peer->t_connect_check_w);
d62a17ae 1523 break;
1524 }
1525 return 0;
718e3744 1526}
1527
1528/* Connect retry timer is expired when the peer status is Connect. */
d62a17ae 1529static int bgp_reconnect(struct peer *peer)
718e3744 1530{
d62a17ae 1531 if (bgp_stop(peer) < 0)
1532 return -1;
1ff9a340 1533
d62a17ae 1534 bgp_start(peer);
1535 return 0;
718e3744 1536}
1537
d62a17ae 1538static int bgp_fsm_open(struct peer *peer)
718e3744 1539{
d62a17ae 1540 /* Send keepalive and make keepalive timer */
1541 bgp_keepalive_send(peer);
718e3744 1542
d62a17ae 1543 /* Reset holdtimer value. */
1544 BGP_TIMER_OFF(peer->t_holdtime);
718e3744 1545
d62a17ae 1546 return 0;
718e3744 1547}
1548
397b5bde
LR
1549/* FSM error, unexpected event. This is error of BGP connection. So cut the
1550 peer and change to Idle status. */
d62a17ae 1551static int bgp_fsm_event_error(struct peer *peer)
397b5bde 1552{
1c50c1c0
QY
1553 flog_err(EC_BGP_FSM, "%s [FSM] unexpected packet received in state %s",
1554 peer->host, lookup_msg(bgp_status_msg, peer->status, NULL));
397b5bde 1555
d62a17ae 1556 return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR, 0);
397b5bde
LR
1557}
1558
718e3744 1559/* Hold timer expire. This is error of BGP connection. So cut the
1560 peer and change to Idle status. */
d62a17ae 1561static int bgp_fsm_holdtime_expire(struct peer *peer)
718e3744 1562{
d62a17ae 1563 if (bgp_debug_neighbor_events(peer))
1564 zlog_debug("%s [FSM] Hold timer expire", peer->host);
718e3744 1565
d62a17ae 1566 return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0);
718e3744 1567}
1568
727c4f87
QY
1569/**
1570 * Transition to Established state.
1571 *
1572 * Convert peer from stub to full fledged peer, set some timers, and generate
1573 * initial updates.
1574 */
d62a17ae 1575static int bgp_establish(struct peer *peer)
718e3744 1576{
d62a17ae 1577 afi_t afi;
1578 safi_t safi;
1579 int nsf_af_count = 0;
1580 int ret = 0;
1581 struct peer *other;
1582
1583 other = peer->doppelganger;
1584 peer = peer_xfer_conn(peer);
1585 if (!peer) {
e50f7cfd 1586 flog_err(EC_BGP_CONNECT, "%%Neighbor failed in xfer_conn");
d62a17ae 1587 return -1;
93406d87 1588 }
93406d87 1589
d62a17ae 1590 if (other == peer)
996c9314
LB
1591 ret = 1; /* bgp_establish specific code when xfer_conn
1592 happens. */
d62a17ae 1593
1594 /* Reset capability open status flag. */
1595 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
1596 SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1597
1598 /* Clear start timer value to default. */
1599 peer->v_start = BGP_INIT_START_TIMER;
1600
1601 /* Increment established count. */
1602 peer->established++;
1603 bgp_fsm_change_status(peer, Established);
1604
1605 /* bgp log-neighbor-changes of neighbor Up */
1606 if (bgp_flag_check(peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
1607 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
1608 zlog_info("%%ADJCHANGE: neighbor %s(%s) in vrf %s Up",
1609 peer->host,
1610 (peer->hostname) ? peer->hostname : "Unknown",
5742e42b
DS
1611 vrf ? ((vrf->vrf_id != VRF_DEFAULT)
1612 ? vrf->name
1613 : VRF_DEFAULT_NAME)
d62a17ae 1614 : "");
1615 }
1616 /* assign update-group/subgroup */
1617 update_group_adjust_peer_afs(peer);
1618
1619 /* graceful restart */
1620 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
1621 for (afi = AFI_IP; afi < AFI_MAX; afi++)
a08ca0a7 1622 for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++) {
d62a17ae 1623 if (peer->afc_nego[afi][safi]
1624 && CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)
1625 && CHECK_FLAG(peer->af_cap[afi][safi],
1626 PEER_CAP_RESTART_AF_RCV)) {
1627 if (peer->nsf[afi][safi]
1628 && !CHECK_FLAG(
1629 peer->af_cap[afi][safi],
1630 PEER_CAP_RESTART_AF_PRESERVE_RCV))
1631 bgp_clear_stale_route(peer, afi, safi);
1632
1633 peer->nsf[afi][safi] = 1;
1634 nsf_af_count++;
1635 } else {
1636 if (peer->nsf[afi][safi])
1637 bgp_clear_stale_route(peer, afi, safi);
1638 peer->nsf[afi][safi] = 0;
1639 }
1640 }
1641
1642 if (nsf_af_count)
1643 SET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
1644 else {
1645 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
1646 if (peer->t_gr_stale) {
1647 BGP_TIMER_OFF(peer->t_gr_stale);
1648 if (bgp_debug_neighbor_events(peer))
1649 zlog_debug(
1650 "%s graceful restart stalepath timer stopped",
1651 peer->host);
1652 }
1653 }
93406d87 1654
d62a17ae 1655 if (peer->t_gr_restart) {
1656 BGP_TIMER_OFF(peer->t_gr_restart);
1657 if (bgp_debug_neighbor_events(peer))
1658 zlog_debug("%s graceful restart timer stopped",
1659 peer->host);
1660 }
718e3744 1661
9eb217ff
QY
1662 /* Reset uptime, turn on keepalives, send current table. */
1663 if (!peer->v_holdtime)
1664 bgp_keepalives_on(peer);
1665
d62a17ae 1666 peer->uptime = bgp_clock();
1667
1668 /* Send route-refresh when ORF is enabled */
05c7a1cc
QY
1669 FOREACH_AFI_SAFI (afi, safi) {
1670 if (CHECK_FLAG(peer->af_cap[afi][safi],
1671 PEER_CAP_ORF_PREFIX_SM_ADV)) {
d62a17ae 1672 if (CHECK_FLAG(peer->af_cap[afi][safi],
05c7a1cc
QY
1673 PEER_CAP_ORF_PREFIX_RM_RCV))
1674 bgp_route_refresh_send(peer, afi, safi,
1675 ORF_TYPE_PREFIX,
1676 REFRESH_IMMEDIATE, 0);
1677 else if (CHECK_FLAG(peer->af_cap[afi][safi],
1678 PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
1679 bgp_route_refresh_send(peer, afi, safi,
1680 ORF_TYPE_PREFIX_OLD,
1681 REFRESH_IMMEDIATE, 0);
1682 }
1683 }
d62a17ae 1684
1685 /* First update is deferred until ORF or ROUTE-REFRESH is received */
05c7a1cc
QY
1686 FOREACH_AFI_SAFI (afi, safi) {
1687 if (CHECK_FLAG(peer->af_cap[afi][safi],
1688 PEER_CAP_ORF_PREFIX_RM_ADV))
d62a17ae 1689 if (CHECK_FLAG(peer->af_cap[afi][safi],
05c7a1cc
QY
1690 PEER_CAP_ORF_PREFIX_SM_RCV)
1691 || CHECK_FLAG(peer->af_cap[afi][safi],
1692 PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
1693 SET_FLAG(peer->af_sflags[afi][safi],
1694 PEER_STATUS_ORF_WAIT_REFRESH);
1695 }
d62a17ae 1696
1697 bgp_announce_peer(peer);
1698
1699 /* Start the route advertisement timer to send updates to the peer - if
1700 * BGP
1701 * is not in read-only mode. If it is, the timer will be started at the
1702 * end
1703 * of read-only mode.
1704 */
1705 if (!bgp_update_delay_active(peer->bgp)) {
1706 BGP_TIMER_OFF(peer->t_routeadv);
1707 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
1708 }
718e3744 1709
d62a17ae 1710 if (peer->doppelganger && (peer->doppelganger->status != Deleted)) {
1711 if (bgp_debug_neighbor_events(peer))
1712 zlog_debug(
1713 "[Event] Deleting stub connection for peer %s",
1714 peer->host);
1715
1716 if (peer->doppelganger->status > Active)
1717 bgp_notify_send(peer->doppelganger, BGP_NOTIFY_CEASE,
1718 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1719 else
1720 peer_delete(peer->doppelganger);
718e3744 1721 }
1722
19bd3dff
DS
1723 /*
1724 * If we are replacing the old peer for a doppelganger
1725 * then switch it around in the bgp->peerhash
1726 * the doppelgangers su and this peer's su are the same
1727 * so the hash_release is the same for either.
1728 */
1729 hash_release(peer->bgp->peerhash, peer);
1730 hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
1731
d62a17ae 1732 bgp_bfd_register_peer(peer);
1733 return ret;
718e3744 1734}
1735
1736/* Keepalive packet is received. */
d62a17ae 1737static int bgp_fsm_keepalive(struct peer *peer)
718e3744 1738{
d62a17ae 1739 BGP_TIMER_OFF(peer->t_holdtime);
1740 return 0;
718e3744 1741}
1742
1743/* Update packet is received. */
d62a17ae 1744static int bgp_fsm_update(struct peer *peer)
718e3744 1745{
d62a17ae 1746 BGP_TIMER_OFF(peer->t_holdtime);
1747 return 0;
718e3744 1748}
1749
1750/* This is empty event. */
d62a17ae 1751static int bgp_ignore(struct peer *peer)
718e3744 1752{
af4c2728 1753 flog_err(
e50f7cfd 1754 EC_BGP_FSM,
d62a17ae 1755 "%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d",
1756 peer->host, bgp_event_str[peer->cur_event],
1757 lookup_msg(bgp_status_msg, peer->status, NULL),
1758 bgp_event_str[peer->last_event],
1759 bgp_event_str[peer->last_major_event], peer->fd);
1760 return 0;
718e3744 1761}
6b0655a2 1762
6403814c 1763/* This is to handle unexpected events.. */
d62a17ae 1764static int bgp_fsm_exeption(struct peer *peer)
6403814c 1765{
af4c2728 1766 flog_err(
e50f7cfd 1767 EC_BGP_FSM,
d62a17ae 1768 "%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d",
1769 peer->host, bgp_event_str[peer->cur_event],
1770 lookup_msg(bgp_status_msg, peer->status, NULL),
1771 bgp_event_str[peer->last_event],
1772 bgp_event_str[peer->last_major_event], peer->fd);
1773 return (bgp_stop(peer));
6403814c
DS
1774}
1775
fc04a677 1776void bgp_fsm_event_update(struct peer *peer, int valid)
fc9a856f 1777{
d62a17ae 1778 if (!peer)
1779 return;
1780
1781 switch (peer->status) {
1782 case Idle:
1783 if (valid)
1784 BGP_EVENT_ADD(peer, BGP_Start);
1785 break;
1786 case Connect:
1787 if (!valid) {
1788 BGP_TIMER_OFF(peer->t_connect);
1789 BGP_EVENT_ADD(peer, TCP_fatal_error);
1790 }
1791 break;
1792 case Active:
1793 if (valid) {
1794 BGP_TIMER_OFF(peer->t_connect);
1795 BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
1796 }
1797 break;
1798 case OpenSent:
1799 case OpenConfirm:
1800 case Established:
1801 if (!valid && (peer->gtsm_hops == 1))
1802 BGP_EVENT_ADD(peer, TCP_fatal_error);
1803 case Clearing:
1804 case Deleted:
1805 default:
1806 break;
fc9a856f 1807 }
fc9a856f
DS
1808}
1809
718e3744 1810/* Finite State Machine structure */
fda1d3e0 1811static const struct {
d62a17ae 1812 int (*func)(struct peer *);
1813 int next_state;
1814} FSM[BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] = {
1815 {
1816 /* Idle state: In Idle state, all events other than BGP_Start is
1817 ignored. With BGP_Start event, finite state machine calls
1818 bgp_start(). */
1819 {bgp_start, Connect}, /* BGP_Start */
1820 {bgp_stop, Idle}, /* BGP_Stop */
1821 {bgp_stop, Idle}, /* TCP_connection_open */
1822 {bgp_stop, Idle}, /* TCP_connection_closed */
1823 {bgp_ignore, Idle}, /* TCP_connection_open_failed */
1824 {bgp_stop, Idle}, /* TCP_fatal_error */
1825 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
1826 {bgp_ignore, Idle}, /* Hold_Timer_expired */
1827 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
1828 {bgp_ignore, Idle}, /* Receive_OPEN_message */
1829 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
1830 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
1831 {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
1832 {bgp_ignore, Idle}, /* Clearing_Completed */
1833 },
1834 {
1835 /* Connect */
1836 {bgp_ignore, Connect}, /* BGP_Start */
1837 {bgp_stop, Idle}, /* BGP_Stop */
1838 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
1839 {bgp_stop, Idle}, /* TCP_connection_closed */
1840 {bgp_connect_fail, Active}, /* TCP_connection_open_failed */
1841 {bgp_connect_fail, Idle}, /* TCP_fatal_error */
1842 {bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
1843 {bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
1844 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
1845 {bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
1846 {bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
1847 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
1848 {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
1849 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
1850 },
1851 {
1852 /* Active, */
1853 {bgp_ignore, Active}, /* BGP_Start */
1854 {bgp_stop, Idle}, /* BGP_Stop */
1855 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
1856 {bgp_stop, Idle}, /* TCP_connection_closed */
1857 {bgp_ignore, Active}, /* TCP_connection_open_failed */
1858 {bgp_fsm_exeption, Idle}, /* TCP_fatal_error */
1859 {bgp_start, Connect}, /* ConnectRetry_timer_expired */
1860 {bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
1861 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
1862 {bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
1863 {bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
1864 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
1865 {bgp_fsm_exeption, Idle}, /* Receive_NOTIFICATION_message */
1866 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
1867 },
1868 {
1869 /* OpenSent, */
1870 {bgp_ignore, OpenSent}, /* BGP_Start */
1871 {bgp_stop, Idle}, /* BGP_Stop */
1872 {bgp_stop, Active}, /* TCP_connection_open */
1873 {bgp_stop, Active}, /* TCP_connection_closed */
1874 {bgp_stop, Active}, /* TCP_connection_open_failed */
1875 {bgp_stop, Active}, /* TCP_fatal_error */
1876 {bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
1877 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
1878 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
1879 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
1880 {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
1881 {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
1882 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
1883 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
1884 },
1885 {
1886 /* OpenConfirm, */
1887 {bgp_ignore, OpenConfirm}, /* BGP_Start */
1888 {bgp_stop, Idle}, /* BGP_Stop */
1889 {bgp_stop, Idle}, /* TCP_connection_open */
1890 {bgp_stop, Idle}, /* TCP_connection_closed */
1891 {bgp_stop, Idle}, /* TCP_connection_open_failed */
1892 {bgp_stop, Idle}, /* TCP_fatal_error */
1893 {bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
1894 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
1895 {bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
1896 {bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
1897 {bgp_establish, Established}, /* Receive_KEEPALIVE_message */
1898 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
1899 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
1900 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
1901 },
1902 {
1903 /* Established, */
1904 {bgp_ignore, Established}, /* BGP_Start */
1905 {bgp_stop, Clearing}, /* BGP_Stop */
1906 {bgp_stop, Clearing}, /* TCP_connection_open */
1907 {bgp_stop, Clearing}, /* TCP_connection_closed */
1908 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
1909 {bgp_stop, Clearing}, /* TCP_fatal_error */
1910 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
1911 {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
03014d48
QY
1912 {bgp_ignore, Established}, /* KeepAlive_timer_expired */
1913 {bgp_stop, Clearing}, /* Receive_OPEN_message */
d62a17ae 1914 {bgp_fsm_keepalive,
1915 Established}, /* Receive_KEEPALIVE_message */
1916 {bgp_fsm_update, Established}, /* Receive_UPDATE_message */
1917 {bgp_stop_with_error,
1918 Clearing}, /* Receive_NOTIFICATION_message */
1919 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
1920 },
1921 {
1922 /* Clearing, */
1923 {bgp_ignore, Clearing}, /* BGP_Start */
1924 {bgp_stop, Clearing}, /* BGP_Stop */
1925 {bgp_stop, Clearing}, /* TCP_connection_open */
1926 {bgp_stop, Clearing}, /* TCP_connection_closed */
1927 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
1928 {bgp_stop, Clearing}, /* TCP_fatal_error */
1929 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
1930 {bgp_stop, Clearing}, /* Hold_Timer_expired */
1931 {bgp_stop, Clearing}, /* KeepAlive_timer_expired */
1932 {bgp_stop, Clearing}, /* Receive_OPEN_message */
1933 {bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
1934 {bgp_stop, Clearing}, /* Receive_UPDATE_message */
1935 {bgp_stop, Clearing}, /* Receive_NOTIFICATION_message */
1936 {bgp_clearing_completed, Idle}, /* Clearing_Completed */
1937 },
1938 {
1939 /* Deleted, */
1940 {bgp_ignore, Deleted}, /* BGP_Start */
1941 {bgp_ignore, Deleted}, /* BGP_Stop */
1942 {bgp_ignore, Deleted}, /* TCP_connection_open */
1943 {bgp_ignore, Deleted}, /* TCP_connection_closed */
1944 {bgp_ignore, Deleted}, /* TCP_connection_open_failed */
1945 {bgp_ignore, Deleted}, /* TCP_fatal_error */
1946 {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
1947 {bgp_ignore, Deleted}, /* Hold_Timer_expired */
1948 {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
1949 {bgp_ignore, Deleted}, /* Receive_OPEN_message */
1950 {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
1951 {bgp_ignore, Deleted}, /* Receive_UPDATE_message */
1952 {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */
1953 {bgp_ignore, Deleted}, /* Clearing_Completed */
1954 },
718e3744 1955};
1956
718e3744 1957/* Execute event process. */
d62a17ae 1958int bgp_event(struct thread *thread)
718e3744 1959{
d62a17ae 1960 int event;
1961 struct peer *peer;
1962 int ret;
718e3744 1963
d62a17ae 1964 peer = THREAD_ARG(thread);
1965 event = THREAD_VAL(thread);
718e3744 1966
d62a17ae 1967 ret = bgp_event_update(peer, event);
1ff9a340 1968
d62a17ae 1969 return (ret);
1ff9a340
DS
1970}
1971
d62a17ae 1972int bgp_event_update(struct peer *peer, int event)
1ff9a340 1973{
d62a17ae 1974 int next;
1975 int ret = 0;
1976 struct peer *other;
1977 int passive_conn = 0;
1978 int dyn_nbr;
1979
d8151687
QY
1980 /* default return code */
1981 ret = FSM_PEER_NOOP;
1982
d62a17ae 1983 other = peer->doppelganger;
1984 passive_conn =
1985 (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) ? 1 : 0;
1986 dyn_nbr = peer_dynamic_neighbor(peer);
1987
1988 /* Logging this event. */
1989 next = FSM[peer->status - 1][event - 1].next_state;
1990
1991 if (bgp_debug_neighbor_events(peer) && peer->status != next)
1992 zlog_debug("%s [FSM] %s (%s->%s), fd %d", peer->host,
1993 bgp_event_str[event],
1994 lookup_msg(bgp_status_msg, peer->status, NULL),
1995 lookup_msg(bgp_status_msg, next, NULL), peer->fd);
1996
1997 peer->last_event = peer->cur_event;
1998 peer->cur_event = event;
1999
2000 /* Call function. */
2001 if (FSM[peer->status - 1][event - 1].func)
2002 ret = (*(FSM[peer->status - 1][event - 1].func))(peer);
2003
d62a17ae 2004 if (ret >= 0) {
2005 if (ret == 1 && next == Established) {
2006 /* The case when doppelganger swap accurred in
2007 bgp_establish.
2008 Update the peer pointer accordingly */
d8151687 2009 ret = FSM_PEER_TRANSFERRED;
d62a17ae 2010 peer = other;
2011 }
2012
2013 /* If status is changed. */
d8151687 2014 if (next != peer->status) {
d62a17ae 2015 bgp_fsm_change_status(peer, next);
2016
becedef6
QY
2017 /*
2018 * If we're going to ESTABLISHED then we executed a
2019 * peer transfer. In this case we can either return
2020 * FSM_PEER_TRANSITIONED or FSM_PEER_TRANSFERRED.
2021 * Opting for TRANSFERRED since transfer implies
2022 * session establishment.
2023 */
d8151687
QY
2024 if (ret != FSM_PEER_TRANSFERRED)
2025 ret = FSM_PEER_TRANSITIONED;
2026 }
2027
d62a17ae 2028 /* Make sure timer is set. */
2029 bgp_timer_set(peer);
2030
bea01226 2031 } else {
becedef6
QY
2032 /*
2033 * If we got a return value of -1, that means there was an
2034 * error, restart the FSM. Since bgp_stop() was called on the
2035 * peer. only a few fields are safe to access here. In any case
2036 * we need to indicate that the peer was stopped in the return
2037 * code.
2038 */
bea01226 2039 if (!dyn_nbr && !passive_conn && peer->bgp) {
af4c2728 2040 flog_err(
e50f7cfd 2041 EC_BGP_FSM,
bea01226
QY
2042 "%s [FSM] Failure handling event %s in state %s, "
2043 "prior events %s, %s, fd %d",
2044 peer->host, bgp_event_str[peer->cur_event],
2045 lookup_msg(bgp_status_msg, peer->status, NULL),
2046 bgp_event_str[peer->last_event],
2047 bgp_event_str[peer->last_major_event],
2048 peer->fd);
2049 bgp_stop(peer);
2050 bgp_fsm_change_status(peer, Idle);
2051 bgp_timer_set(peer);
2052 }
2053 ret = FSM_PEER_STOPPED;
d62a17ae 2054 }
bea01226 2055
d62a17ae 2056 return ret;
718e3744 2057}