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