]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_fsm.c
bgpd: BGP Garaceful Restart debug logs.
[mirror_frr.git] / bgpd / bgp_fsm.c
CommitLineData
d62a17ae 1/* BGP-4 Finite State Machine
896014f4
DL
2 * From RFC1771 [A Border Gateway Protocol 4 (BGP-4)]
3 * Copyright (C) 1996, 97, 98 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
718e3744 21
22#include <zebra.h>
23
24#include "linklist.h"
25#include "prefix.h"
718e3744 26#include "sockunion.h"
27#include "thread.h"
28#include "log.h"
29#include "stream.h"
74ffbfe6 30#include "ringbuf.h"
718e3744 31#include "memory.h"
32#include "plist.h"
f188f2c4 33#include "workqueue.h"
3f9c7369 34#include "queue.h"
039f3a34 35#include "filter.h"
4dcadbef 36#include "command.h"
02705213 37#include "lib_errors.h"
8c48b3b6 38#include "zclient.h"
856ca177 39#include "lib/json.h"
718e3744 40#include "bgpd/bgpd.h"
41#include "bgpd/bgp_attr.h"
42#include "bgpd/bgp_debug.h"
14454c9f 43#include "bgpd/bgp_errors.h"
718e3744 44#include "bgpd/bgp_fsm.h"
45#include "bgpd/bgp_packet.h"
46#include "bgpd/bgp_network.h"
47#include "bgpd/bgp_route.h"
48#include "bgpd/bgp_dump.h"
49#include "bgpd/bgp_open.h"
f188f2c4 50#include "bgpd/bgp_advertise.h"
3f9c7369 51#include "bgpd/bgp_updgrp.h"
ffd0c037 52#include "bgpd/bgp_nht.h"
c43ed2e4 53#include "bgpd/bgp_bfd.h"
4a1ab8e4 54#include "bgpd/bgp_memory.h"
03014d48 55#include "bgpd/bgp_keepalives.h"
56257a44 56#include "bgpd/bgp_io.h"
c42eab4b 57#include "bgpd/bgp_zebra.h"
6b0655a2 58
d62a17ae 59DEFINE_HOOK(peer_backward_transition, (struct peer * peer), (peer))
7d8d0eab 60DEFINE_HOOK(peer_status_changed, (struct peer * peer), (peer))
f009ff26 61extern const char *get_afi_safi_str(afi_t afi,
62 safi_t safi, bool for_json);
6403814c
DS
63/* Definition of display strings corresponding to FSM events. This should be
64 * kept consistent with the events defined in bgpd.h
65 */
2b64873d 66static const char *const bgp_event_str[] = {
d62a17ae 67 NULL,
68 "BGP_Start",
69 "BGP_Stop",
70 "TCP_connection_open",
71 "TCP_connection_closed",
72 "TCP_connection_open_failed",
73 "TCP_fatal_error",
74 "ConnectRetry_timer_expired",
75 "Hold_Timer_expired",
76 "KeepAlive_timer_expired",
77 "Receive_OPEN_message",
78 "Receive_KEEPALIVE_message",
79 "Receive_UPDATE_message",
80 "Receive_NOTIFICATION_message",
81 "Clearing_Completed",
6403814c
DS
82};
83
718e3744 84/* BGP FSM (finite state machine) has three types of functions. Type
85 one is thread functions. Type two is event functions. Type three
86 is FSM functions. Timer functions are set by bgp_timer_set
87 function. */
88
89/* BGP event function. */
d62a17ae 90int bgp_event(struct thread *);
718e3744 91
92/* BGP thread functions. */
d62a17ae 93static int bgp_start_timer(struct thread *);
94static int bgp_connect_timer(struct thread *);
95static int bgp_holdtime_timer(struct thread *);
718e3744 96
97/* BGP FSM functions. */
d62a17ae 98static int bgp_start(struct peer *);
718e3744 99
e2d3a909 100/* Register peer with NHT */
101static int bgp_peer_reg_with_nht(struct peer *peer)
102{
103 int connected = 0;
104
c8d6f0d6 105 if (peer->sort == BGP_PEER_EBGP && peer->ttl == BGP_DEFAULT_TTL
e2d3a909 106 && !CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
107 && !bgp_flag_check(peer->bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
108 connected = 1;
109
110 return bgp_find_or_add_nexthop(
111 peer->bgp, peer->bgp, family2afi(peer->su.sa.sa_family),
112 NULL, peer, connected);
113}
114
d62a17ae 115static void peer_xfer_stats(struct peer *peer_dst, struct peer *peer_src)
1ff9a340 116{
d62a17ae 117 /* Copy stats over. These are only the pre-established state stats */
118 peer_dst->open_in += peer_src->open_in;
119 peer_dst->open_out += peer_src->open_out;
120 peer_dst->keepalive_in += peer_src->keepalive_in;
121 peer_dst->keepalive_out += peer_src->keepalive_out;
122 peer_dst->notify_in += peer_src->notify_in;
123 peer_dst->notify_out += peer_src->notify_out;
124 peer_dst->dynamic_cap_in += peer_src->dynamic_cap_in;
125 peer_dst->dynamic_cap_out += peer_src->dynamic_cap_out;
1ff9a340
DS
126}
127
d62a17ae 128static struct peer *peer_xfer_conn(struct peer *from_peer)
1ff9a340 129{
d62a17ae 130 struct peer *peer;
131 afi_t afi;
132 safi_t safi;
133 int fd;
134 int status, pstatus;
135 unsigned char last_evt, last_maj_evt;
136
137 assert(from_peer != NULL);
138
139 peer = from_peer->doppelganger;
140
141 if (!peer || !CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
142 return from_peer;
143
9bf904cc
DS
144 /*
145 * Let's check that we are not going to loose known configuration
146 * state based upon doppelganger rules.
147 */
148 FOREACH_AFI_SAFI (afi, safi) {
149 if (from_peer->afc[afi][safi] != peer->afc[afi][safi]) {
150 flog_err(
151 EC_BGP_DOPPELGANGER_CONFIG,
152 "from_peer->afc[%d][%d] is not the same as what we are overwriting",
153 afi, safi);
154 return NULL;
155 }
156 }
157
d62a17ae 158 if (bgp_debug_neighbor_events(peer))
159 zlog_debug("%s: peer transfer %p fd %d -> %p fd %d)",
160 from_peer->host, from_peer, from_peer->fd, peer,
161 peer->fd);
162
424ab01d
QY
163 bgp_writes_off(peer);
164 bgp_reads_off(peer);
165 bgp_writes_off(from_peer);
166 bgp_reads_off(from_peer);
d62a17ae 167
74e00a55
S
168 /*
169 * Before exchanging FD remove doppelganger from
170 * keepalive peer hash. It could be possible conf peer
171 * fd is set to -1. If blocked on lock then keepalive
172 * thread can access peer pointer with fd -1.
173 */
174 bgp_keepalives_off(from_peer);
175
d62a17ae 176 BGP_TIMER_OFF(peer->t_routeadv);
424ab01d 177 BGP_TIMER_OFF(peer->t_connect);
387f984e
QY
178 BGP_TIMER_OFF(peer->t_connect_check_r);
179 BGP_TIMER_OFF(peer->t_connect_check_w);
d62a17ae 180 BGP_TIMER_OFF(from_peer->t_routeadv);
424ab01d 181 BGP_TIMER_OFF(from_peer->t_connect);
387f984e
QY
182 BGP_TIMER_OFF(from_peer->t_connect_check_r);
183 BGP_TIMER_OFF(from_peer->t_connect_check_w);
7a86aa5a 184 BGP_TIMER_OFF(from_peer->t_process_packet);
d3ecc69e 185
becedef6
QY
186 /*
187 * At this point in time, it is possible that there are packets pending
188 * on various buffers. Those need to be transferred or dropped,
189 * otherwise we'll get spurious failures during session establishment.
190 */
00dffa8c 191 frr_with_mutex(&peer->io_mtx, &from_peer->io_mtx) {
424ab01d
QY
192 fd = peer->fd;
193 peer->fd = from_peer->fd;
194 from_peer->fd = fd;
195
196 stream_fifo_clean(peer->ibuf);
d3ecc69e 197 stream_fifo_clean(peer->obuf);
d3ecc69e 198
becedef6
QY
199 /*
200 * this should never happen, since bgp_process_packet() is the
201 * only task that sets and unsets the current packet and it
202 * runs in our pthread.
203 */
424ab01d 204 if (peer->curr) {
af4c2728 205 flog_err(
e50f7cfd 206 EC_BGP_PKT_PROCESS,
424ab01d
QY
207 "[%s] Dropping pending packet on connection transfer:",
208 peer->host);
584470fb
DL
209 /* there used to be a bgp_packet_dump call here, but
210 * that's extremely confusing since there's no way to
211 * identify the packet in MRT dumps or BMP as dropped
212 * due to connection transfer.
213 */
424ab01d
QY
214 stream_free(peer->curr);
215 peer->curr = NULL;
216 }
217
218 // copy each packet from old peer's output queue to new peer
727c4f87
QY
219 while (from_peer->obuf->head)
220 stream_fifo_push(peer->obuf,
221 stream_fifo_pop(from_peer->obuf));
424ab01d
QY
222
223 // copy each packet from old peer's input queue to new peer
224 while (from_peer->ibuf->head)
225 stream_fifo_push(peer->ibuf,
226 stream_fifo_pop(from_peer->ibuf));
7db44ec8 227
74ffbfe6
QY
228 ringbuf_wipe(peer->ibuf_work);
229 ringbuf_copy(peer->ibuf_work, from_peer->ibuf_work,
230 ringbuf_remain(from_peer->ibuf_work));
d3ecc69e 231 }
d62a17ae 232
233 peer->as = from_peer->as;
234 peer->v_holdtime = from_peer->v_holdtime;
235 peer->v_keepalive = from_peer->v_keepalive;
d62a17ae 236 peer->v_routeadv = from_peer->v_routeadv;
237 peer->v_gr_restart = from_peer->v_gr_restart;
238 peer->cap = from_peer->cap;
239 status = peer->status;
240 pstatus = peer->ostatus;
241 last_evt = peer->last_event;
242 last_maj_evt = peer->last_major_event;
243 peer->status = from_peer->status;
244 peer->ostatus = from_peer->ostatus;
245 peer->last_event = from_peer->last_event;
246 peer->last_major_event = from_peer->last_major_event;
247 from_peer->status = status;
248 from_peer->ostatus = pstatus;
249 from_peer->last_event = last_evt;
250 from_peer->last_major_event = last_maj_evt;
251 peer->remote_id = from_peer->remote_id;
3577f1c5 252 peer->last_reset = from_peer->last_reset;
d62a17ae 253
d7b3cda6 254 peer->peer_gr_present_state = from_peer->peer_gr_present_state;
255 peer->peer_gr_new_status_flag = from_peer->peer_gr_new_status_flag;
256 bgp_peer_gr_flags_update(peer);
257
8c48b3b6 258 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(
259 peer->bgp,
260 peer->bgp->peer);
261
d7b3cda6 262 if (bgp_peer_gr_mode_get(peer) == PEER_DISABLE) {
263
264 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
265
266 if (CHECK_FLAG(peer->sflags,
267 PEER_STATUS_NSF_WAIT)) {
268 peer_nsf_stop(peer);
269 }
270 }
271
d62a17ae 272 if (from_peer->hostname != NULL) {
273 if (peer->hostname) {
274 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
275 peer->hostname = NULL;
276 }
277
278 peer->hostname = from_peer->hostname;
279 from_peer->hostname = NULL;
280 }
281
282 if (from_peer->domainname != NULL) {
283 if (peer->domainname) {
284 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
285 peer->domainname = NULL;
286 }
287
288 peer->domainname = from_peer->domainname;
289 from_peer->domainname = NULL;
290 }
291
05c7a1cc
QY
292 FOREACH_AFI_SAFI (afi, safi) {
293 peer->af_flags[afi][safi] = from_peer->af_flags[afi][safi];
294 peer->af_sflags[afi][safi] = from_peer->af_sflags[afi][safi];
295 peer->af_cap[afi][safi] = from_peer->af_cap[afi][safi];
296 peer->afc_nego[afi][safi] = from_peer->afc_nego[afi][safi];
297 peer->afc_adv[afi][safi] = from_peer->afc_adv[afi][safi];
298 peer->afc_recv[afi][safi] = from_peer->afc_recv[afi][safi];
299 peer->orf_plist[afi][safi] = from_peer->orf_plist[afi][safi];
300 }
d62a17ae 301
302 if (bgp_getsockname(peer) < 0) {
af4c2728 303 flog_err(
450971aa 304 EC_LIB_SOCKET,
d62a17ae 305 "%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
306 (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)
307 ? "accept"
308 : ""),
309 peer->host, peer->fd, from_peer->fd);
310 bgp_stop(peer);
311 bgp_stop(from_peer);
312 return NULL;
313 }
314 if (from_peer->status > Active) {
315 if (bgp_getsockname(from_peer) < 0) {
af4c2728 316 flog_err(
450971aa 317 EC_LIB_SOCKET,
d62a17ae 318 "%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
14454c9f 319
d62a17ae 320 (CHECK_FLAG(from_peer->sflags,
321 PEER_STATUS_ACCEPT_PEER)
322 ? "accept"
323 : ""),
324 from_peer->host, from_peer->fd, peer->fd);
325 bgp_stop(from_peer);
326 from_peer = NULL;
327 }
328 }
329
0112e9e0
QY
330
331 // Note: peer_xfer_stats() must be called with I/O turned OFF
332 if (from_peer)
333 peer_xfer_stats(peer, from_peer);
334
e2d3a909 335 /* Register peer for NHT. This is to allow RAs to be enabled when
336 * needed, even on a passive connection.
337 */
338 bgp_peer_reg_with_nht(peer);
339
424ab01d
QY
340 bgp_reads_on(peer);
341 bgp_writes_on(peer);
7a86aa5a
QY
342 thread_add_timer_msec(bm->master, bgp_process_packet, peer, 0,
343 &peer->t_process_packet);
d62a17ae 344
d62a17ae 345 return (peer);
1ff9a340
DS
346}
347
718e3744 348/* Hook function called after bgp event is occered. And vty's
349 neighbor command invoke this function after making neighbor
350 structure. */
d62a17ae 351void bgp_timer_set(struct peer *peer)
718e3744 352{
d62a17ae 353 switch (peer->status) {
354 case Idle:
355 /* First entry point of peer's finite state machine. In Idle
356 status start timer is on unless peer is shutdown or peer is
357 inactive. All other timer must be turned off */
f62abc7d 358 if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(peer)
dded74d5
DS
359 || (peer->bgp->inst_type != BGP_INSTANCE_TYPE_VIEW &&
360 peer->bgp->vrf_id == VRF_UNKNOWN)) {
d62a17ae 361 BGP_TIMER_OFF(peer->t_start);
362 } else {
363 BGP_TIMER_ON(peer->t_start, bgp_start_timer,
364 peer->v_start);
365 }
366 BGP_TIMER_OFF(peer->t_connect);
367 BGP_TIMER_OFF(peer->t_holdtime);
b72b6f4f 368 bgp_keepalives_off(peer);
d62a17ae 369 BGP_TIMER_OFF(peer->t_routeadv);
370 break;
371
372 case Connect:
373 /* After start timer is expired, the peer moves to Connect
374 status. Make sure start timer is off and connect timer is
375 on. */
376 BGP_TIMER_OFF(peer->t_start);
377 BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
378 peer->v_connect);
379 BGP_TIMER_OFF(peer->t_holdtime);
b72b6f4f 380 bgp_keepalives_off(peer);
d62a17ae 381 BGP_TIMER_OFF(peer->t_routeadv);
382 break;
383
384 case Active:
385 /* Active is waiting connection from remote peer. And if
386 connect timer is expired, change status to Connect. */
387 BGP_TIMER_OFF(peer->t_start);
388 /* If peer is passive mode, do not set connect timer. */
389 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)
390 || CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
391 BGP_TIMER_OFF(peer->t_connect);
392 } else {
393 BGP_TIMER_ON(peer->t_connect, bgp_connect_timer,
394 peer->v_connect);
395 }
396 BGP_TIMER_OFF(peer->t_holdtime);
b72b6f4f 397 bgp_keepalives_off(peer);
d62a17ae 398 BGP_TIMER_OFF(peer->t_routeadv);
399 break;
400
401 case OpenSent:
402 /* OpenSent status. */
403 BGP_TIMER_OFF(peer->t_start);
404 BGP_TIMER_OFF(peer->t_connect);
405 if (peer->v_holdtime != 0) {
406 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
407 peer->v_holdtime);
408 } else {
409 BGP_TIMER_OFF(peer->t_holdtime);
410 }
b72b6f4f 411 bgp_keepalives_off(peer);
d62a17ae 412 BGP_TIMER_OFF(peer->t_routeadv);
413 break;
414
415 case OpenConfirm:
416 /* OpenConfirm status. */
417 BGP_TIMER_OFF(peer->t_start);
418 BGP_TIMER_OFF(peer->t_connect);
419
420 /* If the negotiated Hold Time value is zero, then the Hold Time
421 timer and KeepAlive timers are not started. */
422 if (peer->v_holdtime == 0) {
423 BGP_TIMER_OFF(peer->t_holdtime);
b72b6f4f 424 bgp_keepalives_off(peer);
d62a17ae 425 } else {
426 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
427 peer->v_holdtime);
b72b6f4f 428 bgp_keepalives_on(peer);
d62a17ae 429 }
430 BGP_TIMER_OFF(peer->t_routeadv);
431 break;
432
433 case Established:
434 /* In Established status start and connect timer is turned
435 off. */
436 BGP_TIMER_OFF(peer->t_start);
437 BGP_TIMER_OFF(peer->t_connect);
438
439 /* Same as OpenConfirm, if holdtime is zero then both holdtime
440 and keepalive must be turned off. */
441 if (peer->v_holdtime == 0) {
442 BGP_TIMER_OFF(peer->t_holdtime);
bea01226 443 bgp_keepalives_off(peer);
d62a17ae 444 } else {
445 BGP_TIMER_ON(peer->t_holdtime, bgp_holdtime_timer,
446 peer->v_holdtime);
bea01226 447 bgp_keepalives_on(peer);
d62a17ae 448 }
449 break;
450 case Deleted:
451 BGP_TIMER_OFF(peer->t_gr_restart);
452 BGP_TIMER_OFF(peer->t_gr_stale);
453 BGP_TIMER_OFF(peer->t_pmax_restart);
454 /* fallthru */
455 case Clearing:
456 BGP_TIMER_OFF(peer->t_start);
457 BGP_TIMER_OFF(peer->t_connect);
458 BGP_TIMER_OFF(peer->t_holdtime);
b72b6f4f 459 bgp_keepalives_off(peer);
d62a17ae 460 BGP_TIMER_OFF(peer->t_routeadv);
461 break;
718e3744 462 }
718e3744 463}
464
465/* BGP start timer. This function set BGP_Start event to thread value
466 and process event. */
d62a17ae 467static int bgp_start_timer(struct thread *thread)
718e3744 468{
d62a17ae 469 struct peer *peer;
718e3744 470
d62a17ae 471 peer = THREAD_ARG(thread);
472 peer->t_start = NULL;
718e3744 473
d62a17ae 474 if (bgp_debug_neighbor_events(peer))
475 zlog_debug("%s [FSM] Timer (start timer expire).", peer->host);
718e3744 476
d62a17ae 477 THREAD_VAL(thread) = BGP_Start;
478 bgp_event(thread); /* bgp_event unlocks peer */
718e3744 479
d62a17ae 480 return 0;
718e3744 481}
482
483/* BGP connect retry timer. */
d62a17ae 484static int bgp_connect_timer(struct thread *thread)
718e3744 485{
d62a17ae 486 struct peer *peer;
487 int ret;
488
489 peer = THREAD_ARG(thread);
424ab01d
QY
490
491 assert(!peer->t_write);
492 assert(!peer->t_read);
493
d62a17ae 494 peer->t_connect = NULL;
495
496 if (bgp_debug_neighbor_events(peer))
497 zlog_debug("%s [FSM] Timer (connect timer expire)", peer->host);
498
499 if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) {
500 bgp_stop(peer);
501 ret = -1;
502 } else {
503 THREAD_VAL(thread) = ConnectRetry_timer_expired;
504 bgp_event(thread); /* bgp_event unlocks peer */
505 ret = 0;
506 }
507
508 return ret;
718e3744 509}
510
511/* BGP holdtime timer. */
d62a17ae 512static int bgp_holdtime_timer(struct thread *thread)
718e3744 513{
d62a17ae 514 struct peer *peer;
718e3744 515
d62a17ae 516 peer = THREAD_ARG(thread);
517 peer->t_holdtime = NULL;
718e3744 518
d62a17ae 519 if (bgp_debug_neighbor_events(peer))
520 zlog_debug("%s [FSM] Timer (holdtime timer expire)",
521 peer->host);
718e3744 522
d62a17ae 523 THREAD_VAL(thread) = Hold_Timer_expired;
524 bgp_event(thread); /* bgp_event unlocks peer */
718e3744 525
d62a17ae 526 return 0;
718e3744 527}
528
d62a17ae 529int bgp_routeadv_timer(struct thread *thread)
718e3744 530{
d62a17ae 531 struct peer *peer;
718e3744 532
d62a17ae 533 peer = THREAD_ARG(thread);
534 peer->t_routeadv = NULL;
718e3744 535
d62a17ae 536 if (bgp_debug_neighbor_events(peer))
537 zlog_debug("%s [FSM] Timer (routeadv timer expire)",
538 peer->host);
718e3744 539
d62a17ae 540 peer->synctime = bgp_clock();
718e3744 541
a9794991 542 thread_add_timer_msec(bm->master, bgp_generate_updgrp_packets, peer, 0,
424ab01d
QY
543 &peer->t_generate_updgrp_packets);
544
d62a17ae 545 /* MRAI timer will be started again when FIFO is built, no need to
546 * do it here.
547 */
548 return 0;
718e3744 549}
550
e0701b79 551/* BGP Peer Down Cause */
2b64873d 552const char *const peer_down_str[] = {"",
d62a17ae 553 "Router ID changed",
554 "Remote AS changed",
555 "Local AS change",
556 "Cluster ID changed",
557 "Confederation identifier changed",
558 "Confederation peer changed",
559 "RR client config change",
560 "RS client config change",
561 "Update source change",
562 "Address family activated",
563 "Admin. shutdown",
564 "User reset",
565 "BGP Notification received",
566 "BGP Notification send",
567 "Peer closed the session",
568 "Neighbor deleted",
569 "Peer-group add member",
570 "Peer-group delete member",
571 "Capability changed",
572 "Passive config change",
573 "Multihop config change",
574 "NSF peer closed the session",
575 "Intf peering v6only config change",
576 "BFD down received",
577 "Interface down",
05912a17 578 "Neighbor address lost",
3577f1c5 579 "Waiting for NHT",
05912a17
DD
580 "Waiting for Peer IPv6 LLA",
581 "Waiting for VRF to be initialized",
582 "No AFI/SAFI activated for peer"};
d62a17ae 583
584static int bgp_graceful_restart_timer_expire(struct thread *thread)
e0701b79 585{
d62a17ae 586 struct peer *peer;
587 afi_t afi;
588 safi_t safi;
589
590 peer = THREAD_ARG(thread);
591 peer->t_gr_restart = NULL;
592
593 /* NSF delete stale route */
594 for (afi = AFI_IP; afi < AFI_MAX; afi++)
a08ca0a7 595 for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++)
d62a17ae 596 if (peer->nsf[afi][safi])
597 bgp_clear_stale_route(peer, afi, safi);
598
599 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
600 BGP_TIMER_OFF(peer->t_gr_stale);
601
602 if (bgp_debug_neighbor_events(peer)) {
603 zlog_debug("%s graceful restart timer expired", peer->host);
604 zlog_debug("%s graceful restart stalepath timer stopped",
605 peer->host);
606 }
93406d87 607
d62a17ae 608 bgp_timer_set(peer);
93406d87 609
d62a17ae 610 return 0;
93406d87 611}
612
d62a17ae 613static int bgp_graceful_stale_timer_expire(struct thread *thread)
93406d87 614{
d62a17ae 615 struct peer *peer;
616 afi_t afi;
617 safi_t safi;
93406d87 618
d62a17ae 619 peer = THREAD_ARG(thread);
620 peer->t_gr_stale = NULL;
93406d87 621
d62a17ae 622 if (bgp_debug_neighbor_events(peer))
623 zlog_debug("%s graceful restart stalepath timer expired",
624 peer->host);
93406d87 625
d62a17ae 626 /* NSF delete stale route */
627 for (afi = AFI_IP; afi < AFI_MAX; afi++)
a08ca0a7 628 for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++)
d62a17ae 629 if (peer->nsf[afi][safi])
630 bgp_clear_stale_route(peer, afi, safi);
93406d87 631
d62a17ae 632 return 0;
93406d87 633}
634
f009ff26 635/* Selection deferral timer processing function */
636static int bgp_graceful_deferral_timer_expire(struct thread *thread)
637{
638 struct afi_safi_info *info;
639 afi_t afi;
640 safi_t safi;
641 struct bgp *bgp;
642
643 info = THREAD_ARG(thread);
644 afi = info->afi;
645 safi = info->safi;
646 bgp = info->bgp;
647
648 if (BGP_DEBUG(update, UPDATE_OUT))
649 zlog_debug("afi %d, safi %d : graceful restart deferral timer expired",
650 afi, safi);
651
652 bgp->gr_info[afi][safi].t_select_deferral = NULL;
653
654 bgp->gr_info[afi][safi].eor_required = 0;
655 bgp->gr_info[afi][safi].eor_received = 0;
656 XFREE(MTYPE_TMP, info);
657
658 /* Best path selection */
659 return bgp_best_path_select_defer(bgp, afi, safi);
660}
661
d62a17ae 662static int bgp_update_delay_applicable(struct bgp *bgp)
f188f2c4 663{
d62a17ae 664 /* update_delay_over flag should be reset (set to 0) for any new
665 applicability of the update-delay during BGP process lifetime.
666 And it should be set after an occurence of the update-delay is
667 over)*/
668 if (!bgp->update_delay_over)
669 return 1;
670
671 return 0;
f188f2c4
DS
672}
673
d62a17ae 674int bgp_update_delay_active(struct bgp *bgp)
f188f2c4 675{
d62a17ae 676 if (bgp->t_update_delay)
677 return 1;
f188f2c4 678
d62a17ae 679 return 0;
f188f2c4
DS
680}
681
d62a17ae 682int bgp_update_delay_configured(struct bgp *bgp)
f188f2c4 683{
d62a17ae 684 if (bgp->v_update_delay)
685 return 1;
f188f2c4 686
d62a17ae 687 return 0;
f188f2c4
DS
688}
689
690/* Do the post-processing needed when bgp comes out of the read-only mode
691 on ending the update delay. */
d62a17ae 692void bgp_update_delay_end(struct bgp *bgp)
f188f2c4 693{
d62a17ae 694 THREAD_TIMER_OFF(bgp->t_update_delay);
695 THREAD_TIMER_OFF(bgp->t_establish_wait);
696
697 /* Reset update-delay related state */
698 bgp->update_delay_over = 1;
699 bgp->established = 0;
700 bgp->restarted_peers = 0;
701 bgp->implicit_eors = 0;
702 bgp->explicit_eors = 0;
703
704 quagga_timestamp(3, bgp->update_delay_end_time,
705 sizeof(bgp->update_delay_end_time));
706
707 /*
708 * Add an end-of-initial-update marker to the main process queues so
709 * that
710 * the route advertisement timer for the peers can be started. Also set
711 * the zebra and peer update hold flags. These flags are used to achieve
712 * three stages in the update-delay post processing:
713 * 1. Finish best-path selection for all the prefixes held on the
714 * queues.
715 * (routes in BGP are updated, and peers sync queues are populated
716 * too)
717 * 2. As the eoiu mark is reached in the bgp process routine, ship all
718 * the
719 * routes to zebra. With that zebra should see updates from BGP
720 * close
721 * to each other.
722 * 3. Unblock the peer update writes. With that peer update packing
723 * with
724 * the prefixes should be at its maximum.
725 */
726 bgp_add_eoiu_mark(bgp);
727 bgp->main_zebra_update_hold = 1;
728 bgp->main_peers_update_hold = 1;
729
730 /* Resume the queue processing. This should trigger the event that would
731 take
732 care of processing any work that was queued during the read-only
733 mode. */
734 work_queue_unplug(bm->process_main_queue);
f188f2c4
DS
735}
736
cb1faec9
DS
737/**
738 * see bgp_fsm.h
739 */
d62a17ae 740void bgp_start_routeadv(struct bgp *bgp)
cb1faec9 741{
d62a17ae 742 struct listnode *node, *nnode;
743 struct peer *peer;
cb1faec9 744
d62a17ae 745 zlog_info("bgp_start_routeadv(), update hold status %d",
746 bgp->main_peers_update_hold);
4a16ae86 747
d62a17ae 748 if (bgp->main_peers_update_hold)
749 return;
4a16ae86 750
d62a17ae 751 quagga_timestamp(3, bgp->update_delay_peers_resume_time,
752 sizeof(bgp->update_delay_peers_resume_time));
4a16ae86 753
d62a17ae 754 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
755 if (peer->status != Established)
756 continue;
757 BGP_TIMER_OFF(peer->t_routeadv);
758 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
759 }
cb1faec9
DS
760}
761
762/**
763 * see bgp_fsm.h
764 */
d62a17ae 765void bgp_adjust_routeadv(struct peer *peer)
cb1faec9 766{
d62a17ae 767 time_t nowtime = bgp_clock();
768 double diff;
769 unsigned long remain;
770
771 /* Bypass checks for special case of MRAI being 0 */
772 if (peer->v_routeadv == 0) {
773 /* Stop existing timer, just in case it is running for a
774 * different
775 * duration and schedule write thread immediately.
776 */
777 if (peer->t_routeadv)
778 BGP_TIMER_OFF(peer->t_routeadv);
779
780 peer->synctime = bgp_clock();
a9794991 781 thread_add_timer_msec(bm->master, bgp_generate_updgrp_packets,
424ab01d
QY
782 peer, 0,
783 &peer->t_generate_updgrp_packets);
d62a17ae 784 return;
785 }
786
787
788 /*
789 * CASE I:
790 * If the last update was written more than MRAI back, expire the timer
791 * instantly so that we can send the update out sooner.
792 *
793 * <------- MRAI --------->
794 * |-----------------|-----------------------|
795 * <------------- m ------------>
796 * ^ ^ ^
797 * | | |
798 * | | current time
799 * | timer start
800 * last write
801 *
802 * m > MRAI
803 */
804 diff = difftime(nowtime, peer->last_update);
805 if (diff > (double)peer->v_routeadv) {
806 BGP_TIMER_OFF(peer->t_routeadv);
807 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
808 return;
809 }
810
811 /*
812 * CASE II:
813 * - Find when to expire the MRAI timer.
814 * If MRAI timer is not active, assume we can start it now.
815 *
816 * <------- MRAI --------->
817 * |------------|-----------------------|
818 * <-------- m ----------><----- r ----->
819 * ^ ^ ^
820 * | | |
821 * | | current time
822 * | timer start
823 * last write
824 *
825 * (MRAI - m) < r
826 */
827 if (peer->t_routeadv)
828 remain = thread_timer_remain_second(peer->t_routeadv);
829 else
830 remain = peer->v_routeadv;
831 diff = peer->v_routeadv - diff;
832 if (diff <= (double)remain) {
833 BGP_TIMER_OFF(peer->t_routeadv);
834 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, diff);
835 }
cb1faec9
DS
836}
837
d62a17ae 838static int bgp_maxmed_onstartup_applicable(struct bgp *bgp)
abc920f8 839{
d62a17ae 840 if (!bgp->maxmed_onstartup_over)
841 return 1;
abc920f8 842
d62a17ae 843 return 0;
abc920f8
DS
844}
845
d62a17ae 846int bgp_maxmed_onstartup_configured(struct bgp *bgp)
abc920f8 847{
d62a17ae 848 if (bgp->v_maxmed_onstartup != BGP_MAXMED_ONSTARTUP_UNCONFIGURED)
849 return 1;
abc920f8 850
d62a17ae 851 return 0;
abc920f8
DS
852}
853
d62a17ae 854int bgp_maxmed_onstartup_active(struct bgp *bgp)
abc920f8 855{
d62a17ae 856 if (bgp->t_maxmed_onstartup)
857 return 1;
abc920f8 858
d62a17ae 859 return 0;
abc920f8
DS
860}
861
d62a17ae 862void bgp_maxmed_update(struct bgp *bgp)
abc920f8 863{
d7c0a89a
QY
864 uint8_t maxmed_active;
865 uint32_t maxmed_value;
d62a17ae 866
867 if (bgp->v_maxmed_admin) {
868 maxmed_active = 1;
869 maxmed_value = bgp->maxmed_admin_value;
870 } else if (bgp->t_maxmed_onstartup) {
871 maxmed_active = 1;
872 maxmed_value = bgp->maxmed_onstartup_value;
873 } else {
874 maxmed_active = 0;
875 maxmed_value = BGP_MAXMED_VALUE_DEFAULT;
876 }
877
878 if (bgp->maxmed_active != maxmed_active
879 || bgp->maxmed_value != maxmed_value) {
880 bgp->maxmed_active = maxmed_active;
881 bgp->maxmed_value = maxmed_value;
882
883 update_group_announce(bgp);
884 }
abc920f8
DS
885}
886
887/* The maxmed onstartup timer expiry callback. */
d62a17ae 888static int bgp_maxmed_onstartup_timer(struct thread *thread)
abc920f8 889{
d62a17ae 890 struct bgp *bgp;
abc920f8 891
d62a17ae 892 zlog_info("Max med on startup ended - timer expired.");
abc920f8 893
d62a17ae 894 bgp = THREAD_ARG(thread);
895 THREAD_TIMER_OFF(bgp->t_maxmed_onstartup);
896 bgp->maxmed_onstartup_over = 1;
abc920f8 897
d62a17ae 898 bgp_maxmed_update(bgp);
abc920f8 899
d62a17ae 900 return 0;
abc920f8
DS
901}
902
d62a17ae 903static void bgp_maxmed_onstartup_begin(struct bgp *bgp)
abc920f8 904{
d62a17ae 905 /* Applicable only once in the process lifetime on the startup */
906 if (bgp->maxmed_onstartup_over)
907 return;
abc920f8 908
d62a17ae 909 zlog_info("Begin maxmed onstartup mode - timer %d seconds",
910 bgp->v_maxmed_onstartup);
abc920f8 911
d62a17ae 912 thread_add_timer(bm->master, bgp_maxmed_onstartup_timer, bgp,
913 bgp->v_maxmed_onstartup, &bgp->t_maxmed_onstartup);
abc920f8 914
d62a17ae 915 if (!bgp->v_maxmed_admin) {
916 bgp->maxmed_active = 1;
917 bgp->maxmed_value = bgp->maxmed_onstartup_value;
918 }
abc920f8 919
d62a17ae 920 /* Route announce to all peers should happen after this in
921 * bgp_establish() */
abc920f8
DS
922}
923
d62a17ae 924static void bgp_maxmed_onstartup_process_status_change(struct peer *peer)
abc920f8 925{
d62a17ae 926 if (peer->status == Established && !peer->bgp->established) {
927 bgp_maxmed_onstartup_begin(peer->bgp);
928 }
abc920f8
DS
929}
930
f188f2c4 931/* The update delay timer expiry callback. */
d62a17ae 932static int bgp_update_delay_timer(struct thread *thread)
f188f2c4 933{
d62a17ae 934 struct bgp *bgp;
f188f2c4 935
d62a17ae 936 zlog_info("Update delay ended - timer expired.");
f188f2c4 937
d62a17ae 938 bgp = THREAD_ARG(thread);
939 THREAD_TIMER_OFF(bgp->t_update_delay);
940 bgp_update_delay_end(bgp);
f188f2c4 941
d62a17ae 942 return 0;
f188f2c4
DS
943}
944
945/* The establish wait timer expiry callback. */
d62a17ae 946static int bgp_establish_wait_timer(struct thread *thread)
f188f2c4 947{
d62a17ae 948 struct bgp *bgp;
f188f2c4 949
d62a17ae 950 zlog_info("Establish wait - timer expired.");
f188f2c4 951
d62a17ae 952 bgp = THREAD_ARG(thread);
953 THREAD_TIMER_OFF(bgp->t_establish_wait);
954 bgp_check_update_delay(bgp);
f188f2c4 955
d62a17ae 956 return 0;
f188f2c4
DS
957}
958
959/* Steps to begin the update delay:
960 - initialize queues if needed
961 - stop the queue processing
962 - start the timer */
d62a17ae 963static void bgp_update_delay_begin(struct bgp *bgp)
f188f2c4 964{
d62a17ae 965 struct listnode *node, *nnode;
966 struct peer *peer;
f188f2c4 967
d62a17ae 968 /* Stop the processing of queued work. Enqueue shall continue */
969 work_queue_plug(bm->process_main_queue);
f188f2c4 970
d62a17ae 971 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
972 peer->update_delay_over = 0;
f188f2c4 973
d62a17ae 974 /* Start the update-delay timer */
975 thread_add_timer(bm->master, bgp_update_delay_timer, bgp,
976 bgp->v_update_delay, &bgp->t_update_delay);
f188f2c4 977
d62a17ae 978 if (bgp->v_establish_wait != bgp->v_update_delay)
979 thread_add_timer(bm->master, bgp_establish_wait_timer, bgp,
980 bgp->v_establish_wait, &bgp->t_establish_wait);
f188f2c4 981
d62a17ae 982 quagga_timestamp(3, bgp->update_delay_begin_time,
983 sizeof(bgp->update_delay_begin_time));
f188f2c4
DS
984}
985
d62a17ae 986static void bgp_update_delay_process_status_change(struct peer *peer)
f188f2c4 987{
d62a17ae 988 if (peer->status == Established) {
989 if (!peer->bgp->established++) {
990 bgp_update_delay_begin(peer->bgp);
991 zlog_info(
992 "Begin read-only mode - update-delay timer %d seconds",
993 peer->bgp->v_update_delay);
994 }
995 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_BIT_RCV))
996 bgp_update_restarted_peers(peer);
997 }
998 if (peer->ostatus == Established
999 && bgp_update_delay_active(peer->bgp)) {
1000 /* Adjust the update-delay state to account for this flap.
1001 NOTE: Intentionally skipping adjusting implicit_eors or
1002 explicit_eors
1003 counters. Extra sanity check in bgp_check_update_delay()
1004 should
1005 be enough to take care of any additive discrepancy in bgp eor
1006 counters */
1007 peer->bgp->established--;
1008 peer->update_delay_over = 0;
1009 }
f188f2c4
DS
1010}
1011
0437e105 1012/* Called after event occurred, this function change status and reset
200df115 1013 read/write and timer thread. */
d62a17ae 1014void bgp_fsm_change_status(struct peer *peer, int status)
200df115 1015{
36dc7588 1016 struct bgp *bgp;
1017 uint32_t peer_count;
1ff9a340 1018
36dc7588 1019 bgp = peer->bgp;
1020 peer_count = bgp->established_peers;
1021
1022 if (status == Established)
1023 bgp->established_peers++;
1024 else if ((peer->status == Established) && (status != Established))
1025 bgp->established_peers--;
1026
1cfe005d
DS
1027 if (bgp_debug_neighbor_events(peer)) {
1028 struct vrf *vrf = vrf_lookup_by_id(bgp->vrf_id);
1029
1030 zlog_debug("%s : vrf %s(%u), Status: %s established_peers %u", __func__,
1031 vrf ? vrf->name : "Unknown", bgp->vrf_id,
1032 lookup_msg(bgp_status_msg, status, NULL),
1033 bgp->established_peers);
1034 }
1035
36dc7588 1036 /* Set to router ID to the value provided by RIB if there are no peers
1037 * in the established state and peer count did not change
1038 */
1039 if ((peer_count != bgp->established_peers) &&
1040 (bgp->established_peers == 0))
1041 bgp_router_id_zebra_bump(bgp->vrf_id, NULL);
1042
d62a17ae 1043 /* Transition into Clearing or Deleted must /always/ clear all routes..
1044 * (and must do so before actually changing into Deleted..
1045 */
1046 if (status >= Clearing) {
1047 bgp_clear_route_all(peer);
1048
1049 /* If no route was queued for the clear-node processing,
1050 * generate the
1051 * completion event here. This is needed because if there are no
1052 * routes
1053 * to trigger the background clear-node thread, the event won't
1054 * get
1055 * generated and the peer would be stuck in Clearing. Note that
1056 * this
1057 * event is for the peer and helps the peer transition out of
1058 * Clearing
1059 * state; it should not be generated per (AFI,SAFI). The event
1060 * is
1061 * directly posted here without calling clear_node_complete() as
1062 * we
1063 * shouldn't do an extra unlock. This event will get processed
1064 * after
1065 * the state change that happens below, so peer will be in
1066 * Clearing
1067 * (or Deleted).
1068 */
1069 if (!work_queue_is_scheduled(peer->clear_node_queue))
1070 BGP_EVENT_ADD(peer, Clearing_Completed);
1071 }
1072
1073 /* Preserve old status and change into new status. */
1074 peer->ostatus = peer->status;
1075 peer->status = status;
1076
1077 /* Save event that caused status change. */
1078 peer->last_major_event = peer->cur_event;
1079
7d8d0eab
MKS
1080 /* Operations after status change */
1081 hook_call(peer_status_changed, peer);
1082
d62a17ae 1083 if (status == Established)
1084 UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
1085
1086 /* If max-med processing is applicable, do the necessary. */
1087 if (status == Established) {
1088 if (bgp_maxmed_onstartup_configured(peer->bgp)
1089 && bgp_maxmed_onstartup_applicable(peer->bgp))
1090 bgp_maxmed_onstartup_process_status_change(peer);
1091 else
1092 peer->bgp->maxmed_onstartup_over = 1;
1093 }
1094
1095 /* If update-delay processing is applicable, do the necessary. */
1096 if (bgp_update_delay_configured(peer->bgp)
1097 && bgp_update_delay_applicable(peer->bgp))
1098 bgp_update_delay_process_status_change(peer);
1099
1100 if (bgp_debug_neighbor_events(peer))
1101 zlog_debug("%s went from %s to %s", peer->host,
1102 lookup_msg(bgp_status_msg, peer->ostatus, NULL),
1103 lookup_msg(bgp_status_msg, peer->status, NULL));
200df115 1104}
1105
3117b5c4 1106/* Flush the event queue and ensure the peer is shut down */
d62a17ae 1107static int bgp_clearing_completed(struct peer *peer)
3117b5c4 1108{
d62a17ae 1109 int rc = bgp_stop(peer);
1ff9a340 1110
d62a17ae 1111 if (rc >= 0)
1112 BGP_EVENT_FLUSH(peer);
3117b5c4 1113
d62a17ae 1114 return rc;
3117b5c4
SH
1115}
1116
718e3744 1117/* Administrative BGP peer stop event. */
3117b5c4 1118/* May be called multiple times for the same peer */
d62a17ae 1119int bgp_stop(struct peer *peer)
718e3744 1120{
d62a17ae 1121 afi_t afi;
1122 safi_t safi;
1123 char orf_name[BUFSIZ];
1124 int ret = 0;
f009ff26 1125 struct bgp *bgp = peer->bgp;
1126 struct graceful_restart_info *gr_info = NULL;
d62a17ae 1127
2ba1fe69 1128 peer->nsf_af_count = 0;
1129
d62a17ae 1130 if (peer_dynamic_neighbor(peer)
1131 && !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
1132 if (bgp_debug_neighbor_events(peer))
1133 zlog_debug("%s (dynamic neighbor) deleted", peer->host);
1134 peer_delete(peer);
1135 return -1;
c22767d8 1136 }
848973c7 1137
d62a17ae 1138 /* Can't do this in Clearing; events are used for state transitions */
1139 if (peer->status != Clearing) {
1140 /* Delete all existing events of the peer */
1141 BGP_EVENT_FLUSH(peer);
93406d87 1142 }
d62a17ae 1143
1144 /* Increment Dropped count. */
1145 if (peer->status == Established) {
1146 peer->dropped++;
1147
1148 /* bgp log-neighbor-changes of neighbor Down */
1149 if (bgp_flag_check(peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
1150 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
2986cac2 1151
d62a17ae 1152 zlog_info(
1153 "%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
1154 peer->host,
1155 (peer->hostname) ? peer->hostname : "Unknown",
5742e42b
DS
1156 vrf ? ((vrf->vrf_id != VRF_DEFAULT)
1157 ? vrf->name
1158 : VRF_DEFAULT_NAME)
d62a17ae 1159 : "",
1160 peer_down_str[(int)peer->last_reset]);
1161 }
1162
1163 /* graceful restart */
1164 if (peer->t_gr_stale) {
1165 BGP_TIMER_OFF(peer->t_gr_stale);
1166 if (bgp_debug_neighbor_events(peer))
1167 zlog_debug(
1168 "%s graceful restart stalepath timer stopped",
1169 peer->host);
1170 }
1171 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) {
1172 if (bgp_debug_neighbor_events(peer)) {
1173 zlog_debug(
1174 "%s graceful restart timer started for %d sec",
1175 peer->host, peer->v_gr_restart);
1176 zlog_debug(
1177 "%s graceful restart stalepath timer started for %d sec",
1178 peer->host, peer->bgp->stalepath_time);
1179 }
1180 BGP_TIMER_ON(peer->t_gr_restart,
1181 bgp_graceful_restart_timer_expire,
1182 peer->v_gr_restart);
1183 BGP_TIMER_ON(peer->t_gr_stale,
1184 bgp_graceful_stale_timer_expire,
1185 peer->bgp->stalepath_time);
1186 } else {
1187 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
1188
1189 for (afi = AFI_IP; afi < AFI_MAX; afi++)
996c9314
LB
1190 for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN;
1191 safi++)
d62a17ae 1192 peer->nsf[afi][safi] = 0;
1193 }
1194
f009ff26 1195 /* If peer reset before receiving EOR, decrement EOR count and
1196 * cancel the selection deferral timer if there are no
1197 * pending EOR messages to be received
1198 */
1199 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
1200 FOREACH_AFI_SAFI (afi, safi) {
1201 if (peer->afc_nego[afi][safi] &&
1202 !CHECK_FLAG(peer->af_sflags[afi][safi],
1203 PEER_STATUS_EOR_RECEIVED)) {
1204 gr_info = &bgp->gr_info[afi][safi];
9e3b51a7 1205
1206 if (gr_info && (gr_info->eor_required))
f009ff26 1207 gr_info->eor_required--;
9e3b51a7 1208
1209 if (gr_info && BGP_DEBUG(update,
1210 UPDATE_OUT))
1211 zlog_debug(
2ba1fe69 1212 "peer %s, EOR_required %d",
f009ff26 1213 peer->host,
1214 gr_info->eor_required);
1215
1216 /* There is no pending EOR message */
9e3b51a7 1217 if (gr_info && gr_info->eor_required
1218 == 0) {
f009ff26 1219 BGP_TIMER_OFF(
1220 gr_info->t_select_deferral);
1221 gr_info->eor_received = 0;
1222 }
1223 }
1224 }
1225 }
1226
d62a17ae 1227 /* set last reset time */
1228 peer->resettime = peer->uptime = bgp_clock();
1229
1230 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1231 zlog_debug("%s remove from all update group",
1232 peer->host);
1233 update_group_remove_peer_afs(peer);
1234
1235 hook_call(peer_backward_transition, peer);
1236
1237 /* Reset peer synctime */
1238 peer->synctime = 0;
93406d87 1239 }
93406d87 1240
424ab01d 1241 /* stop keepalives */
b72b6f4f 1242 bgp_keepalives_off(peer);
424ab01d
QY
1243
1244 /* Stop read and write threads. */
1245 bgp_writes_off(peer);
1246 bgp_reads_off(peer);
1247
387f984e
QY
1248 THREAD_OFF(peer->t_connect_check_r);
1249 THREAD_OFF(peer->t_connect_check_w);
d62a17ae 1250
1251 /* Stop all timers. */
1252 BGP_TIMER_OFF(peer->t_start);
1253 BGP_TIMER_OFF(peer->t_connect);
1254 BGP_TIMER_OFF(peer->t_holdtime);
d62a17ae 1255 BGP_TIMER_OFF(peer->t_routeadv);
d62a17ae 1256
1257 /* Clear input and output buffer. */
00dffa8c 1258 frr_with_mutex(&peer->io_mtx) {
424ab01d
QY
1259 if (peer->ibuf)
1260 stream_fifo_clean(peer->ibuf);
d3ecc69e
QY
1261 if (peer->obuf)
1262 stream_fifo_clean(peer->obuf);
424ab01d
QY
1263
1264 if (peer->ibuf_work)
74ffbfe6 1265 ringbuf_wipe(peer->ibuf_work);
424ab01d
QY
1266 if (peer->obuf_work)
1267 stream_reset(peer->obuf_work);
1268
1269 if (peer->curr) {
1270 stream_free(peer->curr);
1271 peer->curr = NULL;
1272 }
d3ecc69e 1273 }
d62a17ae 1274
1275 /* Close of file descriptor. */
1276 if (peer->fd >= 0) {
1277 close(peer->fd);
1278 peer->fd = -1;
93406d87 1279 }
1280
05c7a1cc
QY
1281 FOREACH_AFI_SAFI (afi, safi) {
1282 /* Reset all negotiated variables */
1283 peer->afc_nego[afi][safi] = 0;
1284 peer->afc_adv[afi][safi] = 0;
1285 peer->afc_recv[afi][safi] = 0;
1286
1287 /* peer address family capability flags*/
1288 peer->af_cap[afi][safi] = 0;
1289
1290 /* peer address family status flags*/
1291 peer->af_sflags[afi][safi] = 0;
1292
1293 /* Received ORF prefix-filter */
1294 peer->orf_plist[afi][safi] = NULL;
1295
1296 if ((peer->status == OpenConfirm)
1297 || (peer->status == Established)) {
1298 /* ORF received prefix-filter pnt */
1299 sprintf(orf_name, "%s.%d.%d", peer->host, afi, safi);
1300 prefix_bgp_orf_remove_all(afi, orf_name);
d62a17ae 1301 }
05c7a1cc 1302 }
d62a17ae 1303
1304 /* Reset keepalive and holdtime */
b90a8e13 1305 if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) {
d62a17ae 1306 peer->v_keepalive = peer->keepalive;
1307 peer->v_holdtime = peer->holdtime;
1308 } else {
1309 peer->v_keepalive = peer->bgp->default_keepalive;
1310 peer->v_holdtime = peer->bgp->default_holdtime;
1ff9a340 1311 }
d62a17ae 1312
1313 peer->update_time = 0;
1314
1315/* Until we are sure that there is no problem about prefix count
1316 this should be commented out.*/
718e3744 1317#if 0
1318 /* Reset prefix count */
1319 peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
1320 peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
cd1964ff 1321 peer->pcount[AFI_IP][SAFI_LABELED_UNICAST] = 0;
718e3744 1322 peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
1323 peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
1324 peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
cd1964ff 1325 peer->pcount[AFI_IP6][SAFI_LABELED_UNICAST] = 0;
718e3744 1326#endif /* 0 */
1327
d62a17ae 1328 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)
1329 && !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) {
1330 peer_delete(peer);
1331 ret = -1;
1332 } else {
1333 bgp_peer_conf_if_to_su_update(peer);
1334 }
d62a17ae 1335 return ret;
718e3744 1336}
1337
1338/* BGP peer is stoped by the error. */
d62a17ae 1339static int bgp_stop_with_error(struct peer *peer)
718e3744 1340{
d62a17ae 1341 /* Double start timer. */
1342 peer->v_start *= 2;
1343
1344 /* Overflow check. */
1345 if (peer->v_start >= (60 * 2))
1346 peer->v_start = (60 * 2);
1347
1348 if (peer_dynamic_neighbor(peer)) {
1349 if (bgp_debug_neighbor_events(peer))
1350 zlog_debug("%s (dynamic neighbor) deleted", peer->host);
1351 peer_delete(peer);
1352 return -1;
1353 }
1354
1355 return (bgp_stop(peer));
718e3744 1356}
1357
397b5bde
LR
1358
1359/* something went wrong, send notify and tear down */
d7c0a89a
QY
1360static int bgp_stop_with_notify(struct peer *peer, uint8_t code,
1361 uint8_t sub_code)
397b5bde 1362{
d62a17ae 1363 /* Send notify to remote peer */
1364 bgp_notify_send(peer, code, sub_code);
1365
1366 if (peer_dynamic_neighbor(peer)) {
1367 if (bgp_debug_neighbor_events(peer))
1368 zlog_debug("%s (dynamic neighbor) deleted", peer->host);
1369 peer_delete(peer);
1370 return -1;
1371 }
f14e6fdb 1372
d62a17ae 1373 /* Clear start timer value to default. */
1374 peer->v_start = BGP_INIT_START_TIMER;
397b5bde 1375
d62a17ae 1376 return (bgp_stop(peer));
397b5bde
LR
1377}
1378
07a16526
QY
1379/**
1380 * Determines whether a TCP session has successfully established for a peer and
1381 * events as appropriate.
1382 *
1383 * This function is called when setting up a new session. After connect() is
387f984e
QY
1384 * called on the peer's socket (in bgp_start()), the fd is passed to poll()
1385 * to wait for connection success or failure. When poll() returns, this
07a16526 1386 * function is called to evaluate the result.
387f984e
QY
1387 *
1388 * Due to differences in behavior of poll() on Linux and BSD - specifically,
1389 * the value of .revents in the case of a closed connection - this function is
1390 * scheduled both for a read and a write event. The write event is triggered
1391 * when the connection is established. A read event is triggered when the
1392 * connection is closed. Thus we need to cancel whichever one did not occur.
07a16526
QY
1393 */
1394static int bgp_connect_check(struct thread *thread)
1395{
1396 int status;
1397 socklen_t slen;
1398 int ret;
1399 struct peer *peer;
1400
1401 peer = THREAD_ARG(thread);
424ab01d
QY
1402 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
1403 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
1404 assert(!peer->t_read);
1405 assert(!peer->t_write);
07a16526 1406
387f984e
QY
1407 THREAD_OFF(peer->t_connect_check_r);
1408 THREAD_OFF(peer->t_connect_check_w);
dc1188bb 1409
07a16526
QY
1410 /* Check file descriptor. */
1411 slen = sizeof(status);
1412 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *)&status,
1413 &slen);
1414
1415 /* If getsockopt is fail, this is fatal error. */
1416 if (ret < 0) {
4cb5e18b 1417 zlog_err("can't get sockopt for nonblocking connect: %d(%s)",
54ff5e9b 1418 errno, safe_strerror(errno));
07a16526
QY
1419 BGP_EVENT_ADD(peer, TCP_fatal_error);
1420 return -1;
1421 }
1422
1423 /* When status is 0 then TCP connection is established. */
1424 if (status == 0) {
1425 BGP_EVENT_ADD(peer, TCP_connection_open);
1426 return 1;
1427 } else {
1428 if (bgp_debug_neighbor_events(peer))
54ff5e9b
DS
1429 zlog_debug("%s [Event] Connect failed %d(%s)",
1430 peer->host, status, safe_strerror(status));
07a16526
QY
1431 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1432 return 0;
1433 }
1434}
397b5bde 1435
718e3744 1436/* TCP connection open. Next we send open message to remote peer. And
1437 add read thread for reading open message. */
d62a17ae 1438static int bgp_connect_success(struct peer *peer)
718e3744 1439{
d62a17ae 1440 if (peer->fd < 0) {
e50f7cfd 1441 flog_err(EC_BGP_CONNECT,
1c50c1c0
QY
1442 "bgp_connect_success peer's fd is negative value %d",
1443 peer->fd);
d62a17ae 1444 bgp_stop(peer);
1445 return -1;
1446 }
1447
1448 if (bgp_getsockname(peer) < 0) {
450971aa 1449 flog_err_sys(EC_LIB_SOCKET,
09c866e3
QY
1450 "%s: bgp_getsockname(): failed for peer %s, fd %d",
1451 __FUNCTION__, peer->host, peer->fd);
0e35025e
DA
1452 bgp_notify_send(
1453 peer, BGP_NOTIFY_FSM_ERR,
1454 BGP_NOTIFY_SUBCODE_UNSPECIFIC); /* internal error */
424ab01d 1455 bgp_writes_on(peer);
d62a17ae 1456 return -1;
1457 }
1458
424ab01d 1459 bgp_reads_on(peer);
d62a17ae 1460
1461 if (bgp_debug_neighbor_events(peer)) {
1462 char buf1[SU_ADDRSTRLEN];
1463
1464 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER))
1465 zlog_debug("%s open active, local address %s",
1466 peer->host,
1467 sockunion2str(peer->su_local, buf1,
1468 SU_ADDRSTRLEN));
1469 else
1470 zlog_debug("%s passive open", peer->host);
1471 }
1472
1473 bgp_open_send(peer);
1474
1475 return 0;
718e3744 1476}
1477
1478/* TCP connect fail */
d62a17ae 1479static int bgp_connect_fail(struct peer *peer)
718e3744 1480{
d62a17ae 1481 if (peer_dynamic_neighbor(peer)) {
1482 if (bgp_debug_neighbor_events(peer))
1483 zlog_debug("%s (dynamic neighbor) deleted", peer->host);
1484 peer_delete(peer);
1485 return -1;
1486 }
1487
1488 return (bgp_stop(peer));
718e3744 1489}
1490
1491/* This function is the first starting point of all BGP connection. It
1492 try to connect to remote peer with non-blocking IO. */
d62a17ae 1493int bgp_start(struct peer *peer)
718e3744 1494{
d62a17ae 1495 int status;
d62a17ae 1496
1497 bgp_peer_conf_if_to_su_update(peer);
1498
1499 if (peer->su.sa.sa_family == AF_UNSPEC) {
1500 if (bgp_debug_neighbor_events(peer))
1501 zlog_debug(
1502 "%s [FSM] Unable to get neighbor's IP address, waiting...",
1503 peer->host);
3577f1c5 1504 peer->last_reset = PEER_DOWN_NBR_ADDR;
d62a17ae 1505 return -1;
1506 }
1507
1508 if (BGP_PEER_START_SUPPRESSED(peer)) {
1509 if (bgp_debug_neighbor_events(peer))
e50f7cfd 1510 flog_err(EC_BGP_FSM,
1c50c1c0
QY
1511 "%s [FSM] Trying to start suppressed peer"
1512 " - this is never supposed to happen!",
1513 peer->host);
d62a17ae 1514 return -1;
1515 }
1516
1517 /* Scrub some information that might be left over from a previous,
1518 * session
1519 */
1520 /* Connection information. */
1521 if (peer->su_local) {
1522 sockunion_free(peer->su_local);
1523 peer->su_local = NULL;
1524 }
1525
1526 if (peer->su_remote) {
1527 sockunion_free(peer->su_remote);
1528 peer->su_remote = NULL;
1529 }
1530
1531 /* Clear remote router-id. */
1532 peer->remote_id.s_addr = 0;
1533
1534 /* Clear peer capability flag. */
1535 peer->cap = 0;
1536
1537 /* If the peer is passive mode, force to move to Active mode. */
1538 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)) {
1539 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1540 return 0;
1541 }
1542
dded74d5
DS
1543 if (peer->bgp->inst_type != BGP_INSTANCE_TYPE_VIEW &&
1544 peer->bgp->vrf_id == VRF_UNKNOWN) {
61cf4b37 1545 if (bgp_debug_neighbor_events(peer))
af4c2728 1546 flog_err(
e50f7cfd 1547 EC_BGP_FSM,
996c9314
LB
1548 "%s [FSM] In a VRF that is not initialised yet",
1549 peer->host);
3577f1c5 1550 peer->last_reset = PEER_DOWN_VRF_UNINIT;
61cf4b37
PG
1551 return -1;
1552 }
1553
e2d3a909 1554 /* Register peer for NHT. If next hop is already resolved, proceed
1555 * with connection setup, else wait.
1556 */
1557 if (!bgp_peer_reg_with_nht(peer)) {
c42eab4b
DS
1558 if (bgp_zebra_num_connects()) {
1559 if (bgp_debug_neighbor_events(peer))
1560 zlog_debug("%s [FSM] Waiting for NHT",
1561 peer->host);
3577f1c5 1562 peer->last_reset = PEER_DOWN_WAITING_NHT;
c42eab4b
DS
1563 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1564 return 0;
1565 }
718e3744 1566 }
d62a17ae 1567
424ab01d
QY
1568 assert(!peer->t_write);
1569 assert(!peer->t_read);
1570 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
1571 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
d62a17ae 1572 status = bgp_connect(peer);
1573
1574 switch (status) {
1575 case connect_error:
1576 if (bgp_debug_neighbor_events(peer))
1577 zlog_debug("%s [FSM] Connect error", peer->host);
1578 BGP_EVENT_ADD(peer, TCP_connection_open_failed);
1579 break;
1580 case connect_success:
1581 if (bgp_debug_neighbor_events(peer))
1582 zlog_debug(
1583 "%s [FSM] Connect immediately success, fd %d",
1584 peer->host, peer->fd);
1585 BGP_EVENT_ADD(peer, TCP_connection_open);
1586 break;
1587 case connect_in_progress:
1588 /* To check nonblocking connect, we wait until socket is
1589 readable or writable. */
1590 if (bgp_debug_neighbor_events(peer))
1591 zlog_debug(
1592 "%s [FSM] Non blocking connect waiting result, fd %d",
1593 peer->host, peer->fd);
1594 if (peer->fd < 0) {
e50f7cfd 1595 flog_err(EC_BGP_FSM,
1c50c1c0
QY
1596 "bgp_start peer's fd is negative value %d",
1597 peer->fd);
d62a17ae 1598 return -1;
1599 }
becedef6 1600 /*
387f984e
QY
1601 * - when the socket becomes ready, poll() will signify POLLOUT
1602 * - if it fails to connect, poll() will signify POLLHUP
1603 * - POLLHUP is handled as a 'read' event by thread.c
1604 *
1605 * therefore, we schedule both a read and a write event with
1606 * bgp_connect_check() as the handler for each and cancel the
1607 * unused event in that function.
becedef6 1608 */
424ab01d 1609 thread_add_read(bm->master, bgp_connect_check, peer, peer->fd,
387f984e
QY
1610 &peer->t_connect_check_r);
1611 thread_add_write(bm->master, bgp_connect_check, peer, peer->fd,
1612 &peer->t_connect_check_w);
d62a17ae 1613 break;
1614 }
1615 return 0;
718e3744 1616}
1617
1618/* Connect retry timer is expired when the peer status is Connect. */
d62a17ae 1619static int bgp_reconnect(struct peer *peer)
718e3744 1620{
d62a17ae 1621 if (bgp_stop(peer) < 0)
1622 return -1;
1ff9a340 1623
8c48b3b6 1624 /* Send graceful restart capabilty */
1625 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(
1626 peer->bgp, peer->bgp->peer);
1627
d62a17ae 1628 bgp_start(peer);
1629 return 0;
718e3744 1630}
1631
d62a17ae 1632static int bgp_fsm_open(struct peer *peer)
718e3744 1633{
d62a17ae 1634 /* Send keepalive and make keepalive timer */
1635 bgp_keepalive_send(peer);
718e3744 1636
d62a17ae 1637 /* Reset holdtimer value. */
1638 BGP_TIMER_OFF(peer->t_holdtime);
718e3744 1639
d62a17ae 1640 return 0;
718e3744 1641}
1642
397b5bde
LR
1643/* FSM error, unexpected event. This is error of BGP connection. So cut the
1644 peer and change to Idle status. */
d62a17ae 1645static int bgp_fsm_event_error(struct peer *peer)
397b5bde 1646{
1c50c1c0
QY
1647 flog_err(EC_BGP_FSM, "%s [FSM] unexpected packet received in state %s",
1648 peer->host, lookup_msg(bgp_status_msg, peer->status, NULL));
397b5bde 1649
d62a17ae 1650 return bgp_stop_with_notify(peer, BGP_NOTIFY_FSM_ERR, 0);
397b5bde
LR
1651}
1652
718e3744 1653/* Hold timer expire. This is error of BGP connection. So cut the
1654 peer and change to Idle status. */
d62a17ae 1655static int bgp_fsm_holdtime_expire(struct peer *peer)
718e3744 1656{
d62a17ae 1657 if (bgp_debug_neighbor_events(peer))
1658 zlog_debug("%s [FSM] Hold timer expire", peer->host);
718e3744 1659
d62a17ae 1660 return bgp_stop_with_notify(peer, BGP_NOTIFY_HOLD_ERR, 0);
718e3744 1661}
1662
f009ff26 1663/* Start the selection deferral timer thread for the specified AFI, SAFI */
1664static int bgp_start_deferral_timer(struct bgp *bgp, afi_t afi, safi_t safi,
1665 struct graceful_restart_info *gr_info)
1666{
1667 struct afi_safi_info *thread_info;
1668
1669 /* If the deferral timer is active, then increment eor count */
1670 if (gr_info->t_select_deferral) {
1671 gr_info->eor_required++;
1672 return 0;
1673 }
1674
1675 /* Start the deferral timer when the first peer enabled for the graceful
1676 * restart is established
1677 */
1678 if (gr_info->eor_required == 0) {
1679 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
1680 if (thread_info == NULL) {
1681 if (BGP_DEBUG(update, UPDATE_OUT))
1682 zlog_debug("%s : Error allocating thread info",
1683 __func__);
1684 return -1;
1685 }
1686
1687 thread_info->afi = afi;
1688 thread_info->safi = safi;
1689 thread_info->bgp = bgp;
1690
1691 thread_add_timer(bm->master,
1692 bgp_graceful_deferral_timer_expire,
1693 thread_info, bgp->select_defer_time,
1694 &gr_info->t_select_deferral);
1695 if (gr_info->t_select_deferral == NULL) {
1696 if (BGP_DEBUG(update, UPDATE_OUT))
1697 zlog_debug("Error starting deferral timer for %s",
1698 get_afi_safi_str(afi, safi, false));
1699 return -1;
1700 }
1701 }
f009ff26 1702 gr_info->eor_required++;
8c48b3b6 1703 /* Send message to RIB indicating route update pending */
1704 if (gr_info->af_enabled[afi][safi] == false) {
1705 gr_info->af_enabled[afi][safi] = true;
1706 /* Send message to RIB */
1707 bgp_zebra_update(afi, safi, bgp->vrf_id,
1708 ZEBRA_CLIENT_ROUTE_UPDATE_PENDING);
1709 }
f009ff26 1710 if (BGP_DEBUG(update, UPDATE_OUT))
1711 zlog_debug("Started the deferral timer for %s eor_required %d",
1712 get_afi_safi_str(afi, safi, false),
1713 gr_info->eor_required);
1714 return 0;
1715}
1716
1717/* Update the graceful restart information for the specified AFI, SAFI */
1718static int bgp_update_gr_info(struct peer *peer, afi_t afi, safi_t safi)
1719{
1720 struct graceful_restart_info *gr_info;
1721 struct bgp *bgp = peer->bgp;
1722 int ret = 0;
1723
1724 if ((afi < AFI_IP) || (afi >= AFI_MAX)) {
1725 if (BGP_DEBUG(update, UPDATE_OUT))
1726 zlog_debug("%s : invalid afi %d", __func__, afi);
1727 return -1;
1728 }
1729
1730 if ((safi < SAFI_UNICAST) || (safi > SAFI_MPLS_VPN)) {
1731 if (BGP_DEBUG(update, UPDATE_OUT))
1732 zlog_debug("%s : invalid safi %d", __func__, safi);
1733 return -1;
1734 }
1735
1736 /* Restarting router */
1737 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer) &&
1738 BGP_PEER_RESTARTING_MODE(peer)) {
1739 /* Check if the forwarding state is preserved */
1740 if (bgp_flag_check(bgp, BGP_FLAG_GR_PRESERVE_FWD)) {
1741 gr_info = &(bgp->gr_info[afi][safi]);
1742 ret = bgp_start_deferral_timer(bgp, afi, safi, gr_info);
1743 }
1744 }
2ba1fe69 1745 return ret;
f009ff26 1746}
1747
727c4f87
QY
1748/**
1749 * Transition to Established state.
1750 *
1751 * Convert peer from stub to full fledged peer, set some timers, and generate
1752 * initial updates.
1753 */
d62a17ae 1754static int bgp_establish(struct peer *peer)
718e3744 1755{
d62a17ae 1756 afi_t afi;
1757 safi_t safi;
1758 int nsf_af_count = 0;
1759 int ret = 0;
1760 struct peer *other;
f009ff26 1761 int status;
d62a17ae 1762
1763 other = peer->doppelganger;
1764 peer = peer_xfer_conn(peer);
1765 if (!peer) {
e50f7cfd 1766 flog_err(EC_BGP_CONNECT, "%%Neighbor failed in xfer_conn");
d62a17ae 1767 return -1;
93406d87 1768 }
93406d87 1769
d62a17ae 1770 if (other == peer)
996c9314
LB
1771 ret = 1; /* bgp_establish specific code when xfer_conn
1772 happens. */
d62a17ae 1773
1774 /* Reset capability open status flag. */
1775 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
1776 SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1777
1778 /* Clear start timer value to default. */
1779 peer->v_start = BGP_INIT_START_TIMER;
1780
1781 /* Increment established count. */
1782 peer->established++;
1783 bgp_fsm_change_status(peer, Established);
1784
1785 /* bgp log-neighbor-changes of neighbor Up */
1786 if (bgp_flag_check(peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
1787 struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
1788 zlog_info("%%ADJCHANGE: neighbor %s(%s) in vrf %s Up",
1789 peer->host,
1790 (peer->hostname) ? peer->hostname : "Unknown",
5742e42b
DS
1791 vrf ? ((vrf->vrf_id != VRF_DEFAULT)
1792 ? vrf->name
1793 : VRF_DEFAULT_NAME)
d62a17ae 1794 : "");
1795 }
1796 /* assign update-group/subgroup */
1797 update_group_adjust_peer_afs(peer);
1798
1799 /* graceful restart */
1800 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
f009ff26 1801 if (bgp_debug_neighbor_events(peer)) {
1802 if (BGP_PEER_RESTARTING_MODE(peer))
1803 zlog_debug("peer %s BGP_RESTARTING_MODE",
1804 peer->host);
1805 else if (BGP_PEER_HELPER_MODE(peer))
1806 zlog_debug("peer %s BGP_HELPER_MODE",
1807 peer->host);
1808 }
d62a17ae 1809 for (afi = AFI_IP; afi < AFI_MAX; afi++)
a08ca0a7 1810 for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++) {
d62a17ae 1811 if (peer->afc_nego[afi][safi]
1812 && CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)
1813 && CHECK_FLAG(peer->af_cap[afi][safi],
1814 PEER_CAP_RESTART_AF_RCV)) {
1815 if (peer->nsf[afi][safi]
1816 && !CHECK_FLAG(
1817 peer->af_cap[afi][safi],
1818 PEER_CAP_RESTART_AF_PRESERVE_RCV))
1819 bgp_clear_stale_route(peer, afi, safi);
1820
1821 peer->nsf[afi][safi] = 1;
1822 nsf_af_count++;
1823 } else {
1824 if (peer->nsf[afi][safi])
1825 bgp_clear_stale_route(peer, afi, safi);
1826 peer->nsf[afi][safi] = 0;
1827 }
f009ff26 1828 /* Update the graceful restart information */
1829 if (peer->afc_nego[afi][safi]) {
1830 if (!BGP_SELECT_DEFER_DISABLE(peer->bgp)) {
1831 status = bgp_update_gr_info(peer, afi,
1832 safi);
1833 if (status < 0)
2ba1fe69 1834 zlog_err("Error in updating graceful restart for %s",
1835 get_afi_safi_str(afi,
9e3b51a7 1836 safi, false));
1837 } else {
1838 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(
1839 peer) &&
1840 BGP_PEER_RESTARTING_MODE(peer)
1841 && bgp_flag_check(peer->bgp,
1842 BGP_FLAG_GR_PRESERVE_FWD))
1843 peer->bgp->gr_info[afi][safi]
1844 .eor_required++;
f009ff26 1845 }
1846 }
d62a17ae 1847 }
1848
794b37d5 1849 peer->nsf_af_count = nsf_af_count;
1850
d62a17ae 1851 if (nsf_af_count)
1852 SET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
1853 else {
1854 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
1855 if (peer->t_gr_stale) {
1856 BGP_TIMER_OFF(peer->t_gr_stale);
1857 if (bgp_debug_neighbor_events(peer))
1858 zlog_debug(
1859 "%s graceful restart stalepath timer stopped",
1860 peer->host);
1861 }
1862 }
93406d87 1863
d62a17ae 1864 if (peer->t_gr_restart) {
1865 BGP_TIMER_OFF(peer->t_gr_restart);
1866 if (bgp_debug_neighbor_events(peer))
1867 zlog_debug("%s graceful restart timer stopped",
1868 peer->host);
1869 }
718e3744 1870
9eb217ff
QY
1871 /* Reset uptime, turn on keepalives, send current table. */
1872 if (!peer->v_holdtime)
1873 bgp_keepalives_on(peer);
1874
d62a17ae 1875 peer->uptime = bgp_clock();
1876
1877 /* Send route-refresh when ORF is enabled */
05c7a1cc
QY
1878 FOREACH_AFI_SAFI (afi, safi) {
1879 if (CHECK_FLAG(peer->af_cap[afi][safi],
1880 PEER_CAP_ORF_PREFIX_SM_ADV)) {
d62a17ae 1881 if (CHECK_FLAG(peer->af_cap[afi][safi],
05c7a1cc
QY
1882 PEER_CAP_ORF_PREFIX_RM_RCV))
1883 bgp_route_refresh_send(peer, afi, safi,
1884 ORF_TYPE_PREFIX,
1885 REFRESH_IMMEDIATE, 0);
1886 else if (CHECK_FLAG(peer->af_cap[afi][safi],
1887 PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
1888 bgp_route_refresh_send(peer, afi, safi,
1889 ORF_TYPE_PREFIX_OLD,
1890 REFRESH_IMMEDIATE, 0);
1891 }
1892 }
d62a17ae 1893
1894 /* First update is deferred until ORF or ROUTE-REFRESH is received */
05c7a1cc
QY
1895 FOREACH_AFI_SAFI (afi, safi) {
1896 if (CHECK_FLAG(peer->af_cap[afi][safi],
1897 PEER_CAP_ORF_PREFIX_RM_ADV))
d62a17ae 1898 if (CHECK_FLAG(peer->af_cap[afi][safi],
05c7a1cc
QY
1899 PEER_CAP_ORF_PREFIX_SM_RCV)
1900 || CHECK_FLAG(peer->af_cap[afi][safi],
1901 PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
1902 SET_FLAG(peer->af_sflags[afi][safi],
1903 PEER_STATUS_ORF_WAIT_REFRESH);
1904 }
d62a17ae 1905
1906 bgp_announce_peer(peer);
1907
1908 /* Start the route advertisement timer to send updates to the peer - if
1909 * BGP
1910 * is not in read-only mode. If it is, the timer will be started at the
1911 * end
1912 * of read-only mode.
1913 */
1914 if (!bgp_update_delay_active(peer->bgp)) {
1915 BGP_TIMER_OFF(peer->t_routeadv);
1916 BGP_TIMER_ON(peer->t_routeadv, bgp_routeadv_timer, 0);
1917 }
718e3744 1918
d62a17ae 1919 if (peer->doppelganger && (peer->doppelganger->status != Deleted)) {
1920 if (bgp_debug_neighbor_events(peer))
1921 zlog_debug(
1922 "[Event] Deleting stub connection for peer %s",
1923 peer->host);
1924
1925 if (peer->doppelganger->status > Active)
1926 bgp_notify_send(peer->doppelganger, BGP_NOTIFY_CEASE,
1927 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1928 else
1929 peer_delete(peer->doppelganger);
718e3744 1930 }
1931
19bd3dff
DS
1932 /*
1933 * If we are replacing the old peer for a doppelganger
1934 * then switch it around in the bgp->peerhash
1935 * the doppelgangers su and this peer's su are the same
1936 * so the hash_release is the same for either.
1937 */
1938 hash_release(peer->bgp->peerhash, peer);
1939 hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
1940
d62a17ae 1941 bgp_bfd_register_peer(peer);
1942 return ret;
718e3744 1943}
1944
1945/* Keepalive packet is received. */
d62a17ae 1946static int bgp_fsm_keepalive(struct peer *peer)
718e3744 1947{
d62a17ae 1948 BGP_TIMER_OFF(peer->t_holdtime);
1949 return 0;
718e3744 1950}
1951
1952/* Update packet is received. */
d62a17ae 1953static int bgp_fsm_update(struct peer *peer)
718e3744 1954{
d62a17ae 1955 BGP_TIMER_OFF(peer->t_holdtime);
1956 return 0;
718e3744 1957}
1958
1959/* This is empty event. */
d62a17ae 1960static int bgp_ignore(struct peer *peer)
718e3744 1961{
af4c2728 1962 flog_err(
e50f7cfd 1963 EC_BGP_FSM,
d62a17ae 1964 "%s [FSM] Ignoring event %s in state %s, prior events %s, %s, fd %d",
1965 peer->host, bgp_event_str[peer->cur_event],
1966 lookup_msg(bgp_status_msg, peer->status, NULL),
1967 bgp_event_str[peer->last_event],
1968 bgp_event_str[peer->last_major_event], peer->fd);
1969 return 0;
718e3744 1970}
6b0655a2 1971
6403814c 1972/* This is to handle unexpected events.. */
d62a17ae 1973static int bgp_fsm_exeption(struct peer *peer)
6403814c 1974{
af4c2728 1975 flog_err(
e50f7cfd 1976 EC_BGP_FSM,
d62a17ae 1977 "%s [FSM] Unexpected event %s in state %s, prior events %s, %s, fd %d",
1978 peer->host, bgp_event_str[peer->cur_event],
1979 lookup_msg(bgp_status_msg, peer->status, NULL),
1980 bgp_event_str[peer->last_event],
1981 bgp_event_str[peer->last_major_event], peer->fd);
1982 return (bgp_stop(peer));
6403814c
DS
1983}
1984
fc04a677 1985void bgp_fsm_event_update(struct peer *peer, int valid)
fc9a856f 1986{
d62a17ae 1987 if (!peer)
1988 return;
1989
1990 switch (peer->status) {
1991 case Idle:
1992 if (valid)
1993 BGP_EVENT_ADD(peer, BGP_Start);
1994 break;
1995 case Connect:
1996 if (!valid) {
1997 BGP_TIMER_OFF(peer->t_connect);
1998 BGP_EVENT_ADD(peer, TCP_fatal_error);
1999 }
2000 break;
2001 case Active:
2002 if (valid) {
2003 BGP_TIMER_OFF(peer->t_connect);
2004 BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
2005 }
2006 break;
2007 case OpenSent:
2008 case OpenConfirm:
2009 case Established:
2010 if (!valid && (peer->gtsm_hops == 1))
2011 BGP_EVENT_ADD(peer, TCP_fatal_error);
2012 case Clearing:
2013 case Deleted:
2014 default:
2015 break;
fc9a856f 2016 }
fc9a856f
DS
2017}
2018
718e3744 2019/* Finite State Machine structure */
fda1d3e0 2020static const struct {
d62a17ae 2021 int (*func)(struct peer *);
2022 int next_state;
2023} FSM[BGP_STATUS_MAX - 1][BGP_EVENTS_MAX - 1] = {
2024 {
2025 /* Idle state: In Idle state, all events other than BGP_Start is
2026 ignored. With BGP_Start event, finite state machine calls
2027 bgp_start(). */
2028 {bgp_start, Connect}, /* BGP_Start */
2029 {bgp_stop, Idle}, /* BGP_Stop */
2030 {bgp_stop, Idle}, /* TCP_connection_open */
2031 {bgp_stop, Idle}, /* TCP_connection_closed */
2032 {bgp_ignore, Idle}, /* TCP_connection_open_failed */
2033 {bgp_stop, Idle}, /* TCP_fatal_error */
2034 {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */
2035 {bgp_ignore, Idle}, /* Hold_Timer_expired */
2036 {bgp_ignore, Idle}, /* KeepAlive_timer_expired */
2037 {bgp_ignore, Idle}, /* Receive_OPEN_message */
2038 {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */
2039 {bgp_ignore, Idle}, /* Receive_UPDATE_message */
2040 {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */
2041 {bgp_ignore, Idle}, /* Clearing_Completed */
2042 },
2043 {
2044 /* Connect */
2045 {bgp_ignore, Connect}, /* BGP_Start */
2046 {bgp_stop, Idle}, /* BGP_Stop */
2047 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
2048 {bgp_stop, Idle}, /* TCP_connection_closed */
2049 {bgp_connect_fail, Active}, /* TCP_connection_open_failed */
2050 {bgp_connect_fail, Idle}, /* TCP_fatal_error */
2051 {bgp_reconnect, Connect}, /* ConnectRetry_timer_expired */
2052 {bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
2053 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
2054 {bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
2055 {bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
2056 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
2057 {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */
2058 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
2059 },
2060 {
2061 /* Active, */
2062 {bgp_ignore, Active}, /* BGP_Start */
2063 {bgp_stop, Idle}, /* BGP_Stop */
2064 {bgp_connect_success, OpenSent}, /* TCP_connection_open */
2065 {bgp_stop, Idle}, /* TCP_connection_closed */
2066 {bgp_ignore, Active}, /* TCP_connection_open_failed */
2067 {bgp_fsm_exeption, Idle}, /* TCP_fatal_error */
2068 {bgp_start, Connect}, /* ConnectRetry_timer_expired */
2069 {bgp_fsm_exeption, Idle}, /* Hold_Timer_expired */
2070 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
2071 {bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
2072 {bgp_fsm_exeption, Idle}, /* Receive_KEEPALIVE_message */
2073 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
2074 {bgp_fsm_exeption, Idle}, /* Receive_NOTIFICATION_message */
2075 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
2076 },
2077 {
2078 /* OpenSent, */
2079 {bgp_ignore, OpenSent}, /* BGP_Start */
2080 {bgp_stop, Idle}, /* BGP_Stop */
2081 {bgp_stop, Active}, /* TCP_connection_open */
2082 {bgp_stop, Active}, /* TCP_connection_closed */
2083 {bgp_stop, Active}, /* TCP_connection_open_failed */
2084 {bgp_stop, Active}, /* TCP_fatal_error */
2085 {bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
2086 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
2087 {bgp_fsm_exeption, Idle}, /* KeepAlive_timer_expired */
2088 {bgp_fsm_open, OpenConfirm}, /* Receive_OPEN_message */
2089 {bgp_fsm_event_error, Idle}, /* Receive_KEEPALIVE_message */
2090 {bgp_fsm_event_error, Idle}, /* Receive_UPDATE_message */
53b4aaec 2091 {bgp_fsm_event_error, Idle}, /* Receive_NOTIFICATION_message */
d62a17ae 2092 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
2093 },
2094 {
2095 /* OpenConfirm, */
2096 {bgp_ignore, OpenConfirm}, /* BGP_Start */
2097 {bgp_stop, Idle}, /* BGP_Stop */
2098 {bgp_stop, Idle}, /* TCP_connection_open */
2099 {bgp_stop, Idle}, /* TCP_connection_closed */
2100 {bgp_stop, Idle}, /* TCP_connection_open_failed */
2101 {bgp_stop, Idle}, /* TCP_fatal_error */
2102 {bgp_fsm_exeption, Idle}, /* ConnectRetry_timer_expired */
2103 {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */
2104 {bgp_ignore, OpenConfirm}, /* KeepAlive_timer_expired */
2105 {bgp_fsm_exeption, Idle}, /* Receive_OPEN_message */
2106 {bgp_establish, Established}, /* Receive_KEEPALIVE_message */
2107 {bgp_fsm_exeption, Idle}, /* Receive_UPDATE_message */
2108 {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */
2109 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
2110 },
2111 {
2112 /* Established, */
2113 {bgp_ignore, Established}, /* BGP_Start */
2114 {bgp_stop, Clearing}, /* BGP_Stop */
2115 {bgp_stop, Clearing}, /* TCP_connection_open */
2116 {bgp_stop, Clearing}, /* TCP_connection_closed */
2117 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
2118 {bgp_stop, Clearing}, /* TCP_fatal_error */
2119 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
2120 {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */
03014d48
QY
2121 {bgp_ignore, Established}, /* KeepAlive_timer_expired */
2122 {bgp_stop, Clearing}, /* Receive_OPEN_message */
d62a17ae 2123 {bgp_fsm_keepalive,
2124 Established}, /* Receive_KEEPALIVE_message */
2125 {bgp_fsm_update, Established}, /* Receive_UPDATE_message */
2126 {bgp_stop_with_error,
2127 Clearing}, /* Receive_NOTIFICATION_message */
2128 {bgp_fsm_exeption, Idle}, /* Clearing_Completed */
2129 },
2130 {
2131 /* Clearing, */
2132 {bgp_ignore, Clearing}, /* BGP_Start */
2133 {bgp_stop, Clearing}, /* BGP_Stop */
2134 {bgp_stop, Clearing}, /* TCP_connection_open */
2135 {bgp_stop, Clearing}, /* TCP_connection_closed */
2136 {bgp_stop, Clearing}, /* TCP_connection_open_failed */
2137 {bgp_stop, Clearing}, /* TCP_fatal_error */
2138 {bgp_stop, Clearing}, /* ConnectRetry_timer_expired */
2139 {bgp_stop, Clearing}, /* Hold_Timer_expired */
2140 {bgp_stop, Clearing}, /* KeepAlive_timer_expired */
2141 {bgp_stop, Clearing}, /* Receive_OPEN_message */
2142 {bgp_stop, Clearing}, /* Receive_KEEPALIVE_message */
2143 {bgp_stop, Clearing}, /* Receive_UPDATE_message */
2144 {bgp_stop, Clearing}, /* Receive_NOTIFICATION_message */
2145 {bgp_clearing_completed, Idle}, /* Clearing_Completed */
2146 },
2147 {
2148 /* Deleted, */
2149 {bgp_ignore, Deleted}, /* BGP_Start */
2150 {bgp_ignore, Deleted}, /* BGP_Stop */
2151 {bgp_ignore, Deleted}, /* TCP_connection_open */
2152 {bgp_ignore, Deleted}, /* TCP_connection_closed */
2153 {bgp_ignore, Deleted}, /* TCP_connection_open_failed */
2154 {bgp_ignore, Deleted}, /* TCP_fatal_error */
2155 {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */
2156 {bgp_ignore, Deleted}, /* Hold_Timer_expired */
2157 {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */
2158 {bgp_ignore, Deleted}, /* Receive_OPEN_message */
2159 {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */
2160 {bgp_ignore, Deleted}, /* Receive_UPDATE_message */
2161 {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */
2162 {bgp_ignore, Deleted}, /* Clearing_Completed */
2163 },
718e3744 2164};
2165
718e3744 2166/* Execute event process. */
d62a17ae 2167int bgp_event(struct thread *thread)
718e3744 2168{
d62a17ae 2169 int event;
2170 struct peer *peer;
2171 int ret;
718e3744 2172
d62a17ae 2173 peer = THREAD_ARG(thread);
2174 event = THREAD_VAL(thread);
718e3744 2175
d62a17ae 2176 ret = bgp_event_update(peer, event);
1ff9a340 2177
d62a17ae 2178 return (ret);
1ff9a340
DS
2179}
2180
d62a17ae 2181int bgp_event_update(struct peer *peer, int event)
1ff9a340 2182{
d62a17ae 2183 int next;
2184 int ret = 0;
2185 struct peer *other;
2186 int passive_conn = 0;
2187 int dyn_nbr;
2188
d8151687
QY
2189 /* default return code */
2190 ret = FSM_PEER_NOOP;
2191
d62a17ae 2192 other = peer->doppelganger;
2193 passive_conn =
2194 (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) ? 1 : 0;
2195 dyn_nbr = peer_dynamic_neighbor(peer);
2196
2197 /* Logging this event. */
2198 next = FSM[peer->status - 1][event - 1].next_state;
2199
2200 if (bgp_debug_neighbor_events(peer) && peer->status != next)
2201 zlog_debug("%s [FSM] %s (%s->%s), fd %d", peer->host,
2202 bgp_event_str[event],
2203 lookup_msg(bgp_status_msg, peer->status, NULL),
2204 lookup_msg(bgp_status_msg, next, NULL), peer->fd);
2205
2206 peer->last_event = peer->cur_event;
2207 peer->cur_event = event;
2208
2209 /* Call function. */
2210 if (FSM[peer->status - 1][event - 1].func)
2211 ret = (*(FSM[peer->status - 1][event - 1].func))(peer);
2212
d62a17ae 2213 if (ret >= 0) {
2214 if (ret == 1 && next == Established) {
2215 /* The case when doppelganger swap accurred in
2216 bgp_establish.
2217 Update the peer pointer accordingly */
d8151687 2218 ret = FSM_PEER_TRANSFERRED;
d62a17ae 2219 peer = other;
2220 }
2221
2222 /* If status is changed. */
d8151687 2223 if (next != peer->status) {
d62a17ae 2224 bgp_fsm_change_status(peer, next);
2225
becedef6
QY
2226 /*
2227 * If we're going to ESTABLISHED then we executed a
2228 * peer transfer. In this case we can either return
2229 * FSM_PEER_TRANSITIONED or FSM_PEER_TRANSFERRED.
2230 * Opting for TRANSFERRED since transfer implies
2231 * session establishment.
2232 */
d8151687
QY
2233 if (ret != FSM_PEER_TRANSFERRED)
2234 ret = FSM_PEER_TRANSITIONED;
2235 }
2236
d62a17ae 2237 /* Make sure timer is set. */
2238 bgp_timer_set(peer);
2239
bea01226 2240 } else {
becedef6
QY
2241 /*
2242 * If we got a return value of -1, that means there was an
2243 * error, restart the FSM. Since bgp_stop() was called on the
2244 * peer. only a few fields are safe to access here. In any case
2245 * we need to indicate that the peer was stopped in the return
2246 * code.
2247 */
bea01226 2248 if (!dyn_nbr && !passive_conn && peer->bgp) {
af4c2728 2249 flog_err(
e50f7cfd 2250 EC_BGP_FSM,
bea01226
QY
2251 "%s [FSM] Failure handling event %s in state %s, "
2252 "prior events %s, %s, fd %d",
2253 peer->host, bgp_event_str[peer->cur_event],
2254 lookup_msg(bgp_status_msg, peer->status, NULL),
2255 bgp_event_str[peer->last_event],
2256 bgp_event_str[peer->last_major_event],
2257 peer->fd);
2258 bgp_stop(peer);
2259 bgp_fsm_change_status(peer, Idle);
2260 bgp_timer_set(peer);
2261 }
2262 ret = FSM_PEER_STOPPED;
d62a17ae 2263 }
bea01226 2264
d62a17ae 2265 return ret;
718e3744 2266}
794b37d5 2267/* BGP GR Code */
2268
2269int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp,
2270 enum global_mode global_new_state,
2271 enum global_mode global_old_state)
2272{
2273 struct peer *peer = {0};
2274 struct listnode *node = {0};
2275 struct listnode *nnode = {0};
2276 enum peer_mode peer_old_state = PEER_INVALID;
2277
2278 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
2279
2280 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2281 zlog_debug(
2ba1fe69 2282 "%s [BGP_GR] Peer: (%s) :",
794b37d5 2283 __func__, peer->host);
2284
2285 peer_old_state = bgp_peer_gr_mode_get(peer);
2286
2287 if (peer_old_state == PEER_GLOBAL_INHERIT) {
2288
2289 /*
2290 *Reset only these peers and send a
2291 *new open message with the change capabilities.
2292 *Considering the mode to be "global_new_state" and
2293 *do all operation accordingly
2294 */
2295
2296 switch (global_new_state) {
794b37d5 2297 case GLOBAL_HELPER:
794b37d5 2298 BGP_PEER_GR_HELPER_ENABLE(peer);
2299 break;
2300 case GLOBAL_GR:
794b37d5 2301 BGP_PEER_GR_ENABLE(peer);
2302 break;
2303 case GLOBAL_DISABLE:
794b37d5 2304 BGP_PEER_GR_DISABLE(peer);
2305 break;
2306 case GLOBAL_INVALID:
794b37d5 2307 zlog_debug(
2ba1fe69 2308 "%s [BGP_GR]GLOBAL_INVALID",
794b37d5 2309 __func__);
2310 return BGP_ERR_GR_OPERATION_FAILED;
2311 default:
794b37d5 2312 zlog_debug(
2ba1fe69 2313 "%s [BGP_GR]Global unknown ERROR",
794b37d5 2314 __func__);
2315 return BGP_ERR_GR_OPERATION_FAILED;
2316 }
2317 }
2318 }
2319
2320 bgp->global_gr_present_state = global_new_state;
2321
794b37d5 2322 return BGP_GR_SUCCESS;
2323}
2324
2ba1fe69 2325int bgp_gr_update_all(struct bgp *bgp, int global_gr_cmd)
794b37d5 2326{
2327 enum global_mode global_new_state = GLOBAL_INVALID;
2328 enum global_mode global_old_state = GLOBAL_INVALID;
2329
2330 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2331 zlog_debug(
2ba1fe69 2332 "%s [BGP_GR]START: global_gr_cmd :%s:",
2333 __func__, print_global_gr_cmd(global_gr_cmd));
794b37d5 2334
2335 global_old_state = bgp_global_gr_mode_get(bgp);
2336
2ba1fe69 2337 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2338 zlog_debug(
2339 "[BGP_GR] global_old_gr_state :%s:",
2340 print_global_gr_mode(global_old_state));
794b37d5 2341
2ba1fe69 2342 if (global_old_state != GLOBAL_INVALID) {
794b37d5 2343 global_new_state =
2ba1fe69 2344 bgp->GLOBAL_GR_FSM[global_old_state][global_gr_cmd];
2345
2346 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2347 zlog_debug(
2348 "[BGP_GR] global_new_gr_state :%s:",
2349 print_global_gr_mode(global_new_state));
794b37d5 2350 } else {
2ba1fe69 2351 zlog_err(
2352 "%s [BGP_GR] global_old_state == GLOBAL_INVALID",
794b37d5 2353 __func__);
2354 return BGP_ERR_GR_OPERATION_FAILED;
2355 }
2356
2357 if (global_new_state == GLOBAL_INVALID) {
2ba1fe69 2358 zlog_err(
2359 "%s [BGP_GR] global_new_state == GLOBAL_INVALID",
794b37d5 2360 __func__);
2361 return BGP_ERR_GR_INVALID_CMD;
2362 }
2363 if (global_new_state == global_old_state) {
2364 /* Trace msg */
2ba1fe69 2365 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2366 zlog_debug(
2367 "%s [BGP_GR] global_new_state == global_old_state :%s",
2368 __func__, print_global_gr_mode(global_new_state));
794b37d5 2369 return BGP_GR_NO_OPERATION;
2370 }
2371
2372 return bgp_gr_lookup_n_update_all_peer(bgp,
2373 global_new_state,
2374 global_old_state);
2375}
2376
2ba1fe69 2377const char *print_peer_gr_mode(enum peer_mode pr_mode)
2378{
2379 const char *peer_gr_mode = NULL;
2380
2381 switch (pr_mode) {
2382 case PEER_HELPER:
2383 peer_gr_mode = "PEER_HELPER";
2384 break;
2385 case PEER_GR:
2386 peer_gr_mode = "PEER_GR";
2387 break;
2388 case PEER_DISABLE:
2389 peer_gr_mode = "PEER_DISABLE";
2390 break;
2391 case PEER_INVALID:
2392 peer_gr_mode = "PEER_INVALID";
2393 break;
2394 case PEER_GLOBAL_INHERIT:
2395 peer_gr_mode = "PEER_GLOBAL_INHERIT";
2396 break;
2397 }
2398
2399 return peer_gr_mode;
2400}
2401
2402const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd)
2403{
2404 const char *peer_gr_cmd = NULL;
2405
2406 switch (pr_gr_cmd) {
2407 case PEER_GR_CMD:
2408 peer_gr_cmd = "PEER_GR_CMD";
2409 break;
2410 case NO_PEER_GR_CMD:
2411 peer_gr_cmd = "NO_PEER_GR_CMD";
2412 break;
2413 case PEER_DISABLE_CMD:
2414 peer_gr_cmd = "PEER_GR_CMD";
2415 break;
2416 case NO_PEER_DISABLE_CMD:
2417 peer_gr_cmd = "NO_PEER_GR_CMD";
2418 break;
2419 case PEER_HELPER_CMD:
2420 peer_gr_cmd = "PEER_HELPER_CMD";
2421 break;
2422 case NO_PEER_HELPER_CMD:
2423 peer_gr_cmd = "NO_PEER_HELPER_CMD";
2424 break;
2425 }
2426
2427 return peer_gr_cmd;
2428}
2429
2430const char *print_global_gr_mode(enum global_mode gl_mode)
2431{
2432 const char *global_gr_mode = NULL;
2433
2434 switch (gl_mode) {
2435 case GLOBAL_HELPER:
2436 global_gr_mode = "GLOBAL_HELPER";
2437 break;
2438 case GLOBAL_GR:
2439 global_gr_mode = "GLOBAL_GR";
2440 break;
2441 case GLOBAL_DISABLE:
2442 global_gr_mode = "GLOBAL_DISABLE";
2443 break;
2444 case GLOBAL_INVALID:
2445 global_gr_mode = "GLOBAL_INVALID";
2446 break;
2447 }
2448
2449 return global_gr_mode;
2450}
2451
2452const char *print_global_gr_cmd(enum global_gr_command gl_gr_cmd)
2453{
2454 const char *global_gr_cmd = NULL;
2455
2456 switch (gl_gr_cmd) {
2457 case GLOBAL_GR_CMD:
2458 global_gr_cmd = "GLOBAL_GR_CMD";
2459 break;
2460 case NO_GLOBAL_GR_CMD:
2461 global_gr_cmd = "NO_GLOBAL_GR_CMD";
2462 break;
2463 case GLOBAL_DISABLE_CMD:
2464 global_gr_cmd = "GLOBAL_DISABLE_CMD";
2465 break;
2466 case NO_GLOBAL_DISABLE_CMD:
2467 global_gr_cmd = "NO_GLOBAL_DISABLE_CMD";
2468 break;
2469 }
2470
2471 return global_gr_cmd;
2472}
2473
794b37d5 2474enum global_mode bgp_global_gr_mode_get(struct bgp *bgp)
2475{
2476 return bgp->global_gr_present_state;
2477}
2478
2479enum peer_mode bgp_peer_gr_mode_get(struct peer *peer)
2480{
2481 return peer->peer_gr_present_state;
2482}
2483
2484int bgp_neighbor_graceful_restart(struct peer *peer,
2ba1fe69 2485 int peer_gr_cmd)
794b37d5 2486{
2487 enum peer_mode peer_new_state = PEER_INVALID;
2488 enum peer_mode peer_old_state = PEER_INVALID;
2489 struct bgp_peer_gr peer_state;
2490 int result = BGP_GR_FAILURE;
2491
2492 /*
2493 * fetch peer_old_state from peer structure also
2494 * fetch global_old_state from bgp structure,
2495 * peer had a back pointer to bgpo struct ;
2496 */
2497
2498 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2499 zlog_debug(
2ba1fe69 2500 "%s [BGP_GR] START:Peer: (%s) : peer_gr_cmd :%s:",
2501 __func__, peer->host, print_peer_gr_cmd(peer_gr_cmd));
794b37d5 2502
2503 peer_old_state = bgp_peer_gr_mode_get(peer);
2504
2505 if (peer_old_state == PEER_INVALID) {
794b37d5 2506 zlog_debug(
2ba1fe69 2507 "[BGP_GR] peer_old_state == Invalid state !");
794b37d5 2508 return BGP_ERR_GR_OPERATION_FAILED;
2509 }
2510
2ba1fe69 2511 peer_state = peer->PEER_GR_FSM[peer_old_state][peer_gr_cmd];
794b37d5 2512 peer_new_state = peer_state.next_state;
2513
2514 if (peer_new_state == PEER_INVALID) {
794b37d5 2515 zlog_debug(
2ba1fe69 2516 "[BGP_GR] Invalid bgp graceful restart command used !");
794b37d5 2517 return BGP_ERR_GR_INVALID_CMD;
2518 }
2519
2520 if (peer_new_state != peer_old_state) {
2521 result = peer_state.action_fun(peer,
2522 peer_old_state,
2523 peer_new_state);
2524 } else {
2ba1fe69 2525 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2526 zlog_debug(
2527 "[BGP_GR] peer_old_state == peer_new_state !");
794b37d5 2528 return BGP_GR_NO_OPERATION;
2529 }
2530
2531 if (result == BGP_GR_SUCCESS) {
2532
2533 /* Update the mode i.e peer_new_state into the peer structure */
2534 peer->peer_gr_present_state = peer_new_state;
794b37d5 2535 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2ba1fe69 2536 zlog_debug("[BGP_GR] Succesfully change the state of the peer to : %s : !",
2537 print_peer_gr_mode(peer_new_state));
794b37d5 2538
2539 return BGP_GR_SUCCESS;
2540 }
2541
2542 return result;
2543}
2544
2545unsigned int bgp_peer_gr_action(struct peer *peer,
2546 int old_peer_state, int new_peer_state)
2547{
2548 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2549 zlog_debug(
2ba1fe69 2550 "%s [BGP_GR] Move peer from old_peer_state :%s: to new_peer_state :%s: !!!!",
2551 __func__, print_peer_gr_mode(old_peer_state),
2552 print_peer_gr_mode(new_peer_state));
794b37d5 2553
2554 int bgp_gr_global_mode = GLOBAL_INVALID;
2555 unsigned int ret = BGP_GR_FAILURE;
2556
2557 if (old_peer_state == new_peer_state) {
2558 /* Nothing to do over here as the present and old state is the same */
794b37d5 2559 return BGP_GR_NO_OPERATION;
2560 }
2561 if ((old_peer_state == PEER_INVALID) ||
2562 (new_peer_state == PEER_INVALID)) {
2563 /* something bad happend , print error message */
2564 return BGP_ERR_GR_INVALID_CMD;
2565 }
2566
2567 bgp_gr_global_mode = bgp_global_gr_mode_get(peer->bgp);
2568
2569 if ((old_peer_state == PEER_GLOBAL_INHERIT) &&
2570 (new_peer_state != PEER_GLOBAL_INHERIT)) {
2571
2572 /* fetch the Mode running in the Global state machine
2573 *from the bgp structure into a variable called
2574 *bgp_gr_global_mode
2575 */
2576
2577 /* Here we are checking if the
2578 *1. peer_new_state == global_mode == helper_mode
2579 *2. peer_new_state == global_mode == GR_mode
2580 *3. peer_new_state == global_mode == disabled_mode
2581 */
2582
2583 BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer);
2584
2585 if (new_peer_state == bgp_gr_global_mode) {
2586 /*This is incremental updates i.e no tear down
2587 *of the existing session
2588 *as the peer is already working in the same mode.
2589 */
794b37d5 2590 ret = BGP_GR_SUCCESS;
2591 } else {
2592 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2593 zlog_debug(
2ba1fe69 2594 "[BGP_GR] Peer state changed from :%s ",
2595 print_peer_gr_mode(old_peer_state));
794b37d5 2596
2597 bgp_peer_move_to_gr_mode(peer, new_peer_state);
2598
2599 ret = BGP_GR_SUCCESS;
2600 }
2601 }
2602 /* In the case below peer is going into Global inherit mode i.e.
2603 * the peer would work as the mode configured at the global level
2604 */
2605 else if ((new_peer_state == PEER_GLOBAL_INHERIT) &&
2606 (old_peer_state != PEER_GLOBAL_INHERIT)) {
2607 /* Here in this case it would be destructive
2608 * in all the cases except one case when,
2609 * Global GR is configured Disabled
2610 * and present_peer_state is not disable
2611 */
2612
2613 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
2614
2615 if (old_peer_state == bgp_gr_global_mode) {
2616
2617 /* This is incremental updates
2618 *i.e no tear down of the existing session
2619 *as the peer is already working in the same mode.
2620 */
2621 ret = BGP_GR_SUCCESS;
2622 } else {
2623 /* Destructive always */
2624 /* Tear down the old session
2625 * and send the new capability
2626 * as per the bgp_gr_global_mode
2627 */
2628
2629 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2ba1fe69 2630 zlog_debug("[BGP_GR] Peer state changed from :%s",
2631 print_peer_gr_mode(old_peer_state));
794b37d5 2632
2633 bgp_peer_move_to_gr_mode(peer, bgp_gr_global_mode);
2634
2635 ret = BGP_GR_SUCCESS;
2636 }
2637 } else {
2638 /*
2639 *This else case, it include all the cases except -->
2640 *(new_peer_state != Peer_Global) &&
2641 *( old_peer_state != Peer_Global )
2642 */
2643 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2ba1fe69 2644 zlog_debug("[BGP_GR] Peer state changed from :%s",
2645 print_peer_gr_mode(old_peer_state));
794b37d5 2646
2647 bgp_peer_move_to_gr_mode(peer, new_peer_state);
2648
2649 ret = BGP_GR_SUCCESS;
2650 }
2651
2652 return ret;
2653}
2654
2655inline void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state)
2656
2657{
2658 int bgp_global_gr_mode = bgp_global_gr_mode_get(peer->bgp);
2659
2660 switch (new_state) {
794b37d5 2661 case PEER_HELPER:
2662 BGP_PEER_GR_HELPER_ENABLE(peer);
2663 break;
794b37d5 2664 case PEER_GR:
2665 BGP_PEER_GR_ENABLE(peer);
2666 break;
794b37d5 2667 case PEER_DISABLE:
2668 BGP_PEER_GR_DISABLE(peer);
2669 break;
794b37d5 2670 case PEER_GLOBAL_INHERIT:
2671 BGP_PEER_GR_GLOBAL_INHERIT_SET(peer);
2672
2673 if (bgp_global_gr_mode == GLOBAL_HELPER) {
2674 BGP_PEER_GR_HELPER_ENABLE(peer);
2675 } else if (bgp_global_gr_mode == GLOBAL_GR) {
2676 BGP_PEER_GR_ENABLE(peer);
2677 } else if (bgp_global_gr_mode == GLOBAL_DISABLE) {
2678 BGP_PEER_GR_DISABLE(peer);
2679 } else {
2ba1fe69 2680 zlog_err(
2681 "[BGP_GR] Default switch inherit mode ::: SOMETHING IS WRONG !!!");
794b37d5 2682 }
2683 break;
2684 default:
2ba1fe69 2685 zlog_err("[BGP_GR] Default switch mode ::: SOMETHING IS WRONG !!!");
794b37d5 2686 break;
2687 }
2688 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2ba1fe69 2689 zlog_debug("[BGP_GR] Peer state changed --to--> : %d : !",
794b37d5 2690 new_state);
2691}
2692
2693void bgp_peer_gr_flags_update(struct peer *peer)
2694{
2695 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2696 zlog_debug(
2ba1fe69 2697 "%s [BGP_GR] called !",
794b37d5 2698 __func__);
2699 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
2700 PEER_GRACEFUL_RESTART_NEW_STATE_HELPER))
2986cac2 2701 SET_FLAG(peer->flags,
794b37d5 2702 PEER_FLAG_GRACEFUL_RESTART_HELPER);
2703 else
2986cac2 2704 UNSET_FLAG(peer->flags,
794b37d5 2705 PEER_FLAG_GRACEFUL_RESTART_HELPER);
2706 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2707 zlog_debug(
2ba1fe69 2708 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !",
794b37d5 2709 peer->host,
2986cac2 2710 (CHECK_FLAG(peer->flags,
794b37d5 2711 PEER_FLAG_GRACEFUL_RESTART_HELPER) ?
2712 "Set" : "UnSet"));
2713 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
2714 PEER_GRACEFUL_RESTART_NEW_STATE_RESTART))
2986cac2 2715 SET_FLAG(peer->flags,
794b37d5 2716 PEER_FLAG_GRACEFUL_RESTART);
2717 else
2986cac2 2718 UNSET_FLAG(peer->flags,
794b37d5 2719 PEER_FLAG_GRACEFUL_RESTART);
2720 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2721 zlog_debug(
2ba1fe69 2722 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !",
794b37d5 2723 peer->host,
2986cac2 2724 (CHECK_FLAG(peer->flags,
794b37d5 2725 PEER_FLAG_GRACEFUL_RESTART) ?
2726 "Set" : "UnSet"));
2727 if (CHECK_FLAG(peer->peer_gr_new_status_flag,
2728 PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT))
2986cac2 2729 SET_FLAG(peer->flags,
794b37d5 2730 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
2731 else
2986cac2 2732 UNSET_FLAG(peer->flags,
794b37d5 2733 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT);
2734 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
2735 zlog_debug(
2ba1fe69 2736 "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !",
794b37d5 2737 peer->host,
2986cac2 2738 (CHECK_FLAG(peer->flags,
794b37d5 2739 PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT) ?
d7b3cda6 2740 "Set" : "UnSet"));
2741
2742 if (!CHECK_FLAG(peer->flags,
2743 PEER_FLAG_GRACEFUL_RESTART) &&
2744 !CHECK_FLAG(peer->flags,
2745 PEER_FLAG_GRACEFUL_RESTART_HELPER)){
2746 zlog_debug(
2ba1fe69 2747 "[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_MODE!",
d7b3cda6 2748 peer->host);
2749
2750 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
2751
2752 if (CHECK_FLAG(peer->sflags,
2753 PEER_STATUS_NSF_WAIT)) {
2754
2755 peer_nsf_stop(peer);
2756 zlog_debug(
2ba1fe69 2757 "[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_WAIT!",
d7b3cda6 2758 peer->host);
2759 }
2760 }
794b37d5 2761}