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