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