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