Coverage Report

Created: 2025-11-09 06:11

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