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