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